From a7e49779e5785d9af5ea47505660de1e49a799d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Minisini?= Date: Fri, 23 Dec 2022 15:42:56 +0100 Subject: [PATCH] FileView: Add preview of video files if 'ffmpeg' is installed. [GB.FORM] * NEW: FileView: Add preview of video files if 'ffmpeg' is installed. * OPT: FileView: Don't hash the contents of the file for preview. Just hash the path and the last modification time. --- comp/src/gb.form/.src/File/CTaskPreview.class | 91 ++++++++++++++----- comp/src/gb.form/.src/File/FileView.class | 66 +------------- comp/src/gb.form/.src/Main.module | 68 ++++++++++++++ 3 files changed, 137 insertions(+), 88 deletions(-) diff --git a/comp/src/gb.form/.src/File/CTaskPreview.class b/comp/src/gb.form/.src/File/CTaskPreview.class index d786b364e..03e19a9f7 100644 --- a/comp/src/gb.form/.src/File/CTaskPreview.class +++ b/comp/src/gb.form/.src/File/CTaskPreview.class @@ -11,6 +11,7 @@ Private $sDir As String Private $iSize As Integer Private $iMaxFileSize As Integer Private $sCache As String +Private $sFFmpeg As String Public Sub _new(sDir As String, iSize As Integer, iMaxFileSize As Integer, aPreview As String[], sTempDir As String) @@ -56,11 +57,13 @@ Private Sub IsTextFile(sPath As String) As Boolean End -Private Sub PrintIcon(hImage As Image, sThumb As String) +Private Sub PrintIcon(hImage As Image, sThumb As String, Optional bVideo As Boolean) Dim hIcon As Image Dim X As Integer Dim Y As Integer + Dim W As Integer + Dim I As Integer If hImage.W > hImage.H Then hImage = hImage.Stretch($iSize, ($iSize * hImage.H) \ hImage.W) @@ -78,6 +81,18 @@ Private Sub PrintIcon(hImage As Image, sThumb As String) 'hRect = Paint.StretchImage(hImage, 0, 0, $iSize, $iSize) + If bVideo Then + W = $iSize \ 16 + Paint.FillRect(X, Y, W, hImage.H, Color.SetAlpha(Color.Black, 128)) + Paint.FillRect(X + hImage.W - W, Y, W, hImage.H, Color.SetAlpha(Color.Black, 128)) + Paint.Background = Color.White + For I = 0 To hImage.H Step W + Paint.Ellipse(X + W \ 4, Y + I + W \ 4, W \ 2, W \ 2) + Paint.Ellipse(X + hImage.W - W + W \ 4, Y + I + W \ 4, W \ 2, W \ 2) + Paint.Fill() + Next + Endif + Paint.Rectangle(X + 0.5, Y + 0.5, hImage.W - 1, hImage.H - 1) Paint.Background = Color.LightForeground Paint.Stroke @@ -113,6 +128,7 @@ Private Sub PrintTextFile(sPath As String, sThumb As String) If fSize >= 4 Then + Paint.Font = Font["monospace"] Paint.Font.Size = fSize While Not Eof(hFile) @@ -166,9 +182,26 @@ Private Sub PrintPdfFile(sPath As String, sThumb As String) End +Private Sub PrintVideoFile(sPath As String, sThumb As String) + + Dim sFile As String + Dim hImage As Image + + If Not $sFFmpeg Then Return + sFile = File.SetExt(Temp$("ffmpeg"), "png") + Exec [$sFFmpeg, "-nostdin", "-hide_banner", "-loglevel", "error", "-i", sPath, "-frames:v", "1", "-y", "-t", "00:00:03", "-vf", "scale=" & CStr($iSize) & ":-1", sFile] Wait + 'Exec [$sFFmpeg, "-nostdin", "-hide_banner", "-i", sPath, "-frames:v", "1", "-y", "-t", "00:00:03", sFile] Wait + Try hImage = Image.Load(sFile) + Try Kill sFile + If Error Then Return + PrintIcon(hImage, sThumb, True) + +End + Private Sub GetThumbnailPath(sPath As String) As String - Try Return $sCache &/ Hash.Sha256(File.Load(sPath)) & "." & CStr($iSize) & ".png" + sPath &= "." & CStr(Stat(sPath).LastModified) + Try Return $sCache &/ Hash.Sha256(sPath) & "." & CStr($iSize) & ".png" End @@ -182,6 +215,8 @@ Public Sub Main() Dim sThumb As String Application.Priority += 10 + + $sFFmpeg = System.Find("ffmpeg") For Each sFile In Preview @@ -199,35 +234,43 @@ Public Sub Main() Continue Endif - If sExt = "jpg" Or If sExt = "jpeg" Or If sExt = "png" Or If sExt = "gif" Or If sExt = "bmp" Or If sExt = "xpm" Or If sExt = "webp" Then + If Main.Ext[sExt] = "image" Then - Try hImage = Image.Load(sPath) - If Not Error Then PrintIcon(hImage, sThumb) - - Else If sExt = "svg" Or If sExt = "svgz" Then - - Try hSvgImage = SvgImage.Load(sPath) - If Not Error Then - - If hSvgImage.Width > hSvgImage.Height Then - hSvgImage.Resize($iSize, $iSize * hSvgImage.Height / hSvgImage.Width) - Else - hSvgImage.Resize($iSize * hSvgImage.Width / hSvgImage.Height, $iSize) - Endif - - hImage = New Image(hSvgImage.Width, hSvgImage.Height) - Paint.Begin(hImage) - hSvgImage.Paint() - Paint.End + If sExt = "svg" Or If sExt = "svgz" Then - PrintIcon(hImage, sThumb) + Try hSvgImage = SvgImage.Load(sPath) + If Not Error Then + + If hSvgImage.Width > hSvgImage.Height Then + hSvgImage.Resize($iSize, $iSize * hSvgImage.Height / hSvgImage.Width) + Else + hSvgImage.Resize($iSize * hSvgImage.Width / hSvgImage.Height, $iSize) + Endif + + hImage = New Image(hSvgImage.Width, hSvgImage.Height) + Paint.Begin(hImage) + hSvgImage.Paint() + Paint.End + + PrintIcon(hImage, sThumb) + + Endif + Else + + Try hImage = Image.Load(sPath) + If Not Error Then PrintIcon(hImage, sThumb) + Endif - + Else If sExt = "pdf" Then Try PrintPdfFile(sPath, sThumb) - + + Else If Main.Ext[sExt] = "video" Then + + Try PrintVideoFile(sPath, sThumb) + Else If IsTextFile(sPath) Then Try PrintTextFile(sPath, sThumb) diff --git a/comp/src/gb.form/.src/File/FileView.class b/comp/src/gb.form/.src/File/FileView.class index fe7ba9d35..db8a16556 100644 --- a/comp/src/gb.form/.src/File/FileView.class +++ b/comp/src/gb.form/.src/File/FileView.class @@ -70,8 +70,6 @@ Property MaxPreviewSize As Integer Use $iMaxPreviewSize Property Orientation As Integer -Static Private $cExt As New Collection(gb.IgnoreCase) - Private Const PREFIX_DIR As String = "0" Private Const PREFIX_FILE As String = "1" @@ -130,68 +128,8 @@ Private $sLastPreview As String Static Public Sub _init() - $cExt["html"] = "html" - $cExt["htm"] = "html" - $cExt["css"] = "css" - $cExt["js"] = "js" - $cExt["xml"] = "xml" + Main.InitExt - $cExt["tar"] = "archive" - $cExt["gz"] = "archive" - $cExt["tgz"] = "archive" - $cExt["bz2"] = "archive" - $cExt["z"] = "archive" - $cExt["zip"] = "archive" - $cExt["xz"] = "archive" - - $cExt["txt"] = "text" - $cExt["log"] = "text" - $cExt["json"] = "text" - - $cExt["mp3"] = "audio" - $cExt["aac"] = "audio" - $cExt["ogg"] = "audio" - $cExt["oga"] = "audio" - $cExt["flac"] = "audio" - $cExt["wav"] = "audio" - - $cExt["mpg"] = "video" - $cExt["mpeg"] = "video" - $cExt["avi"] = "video" - $cExt["wmv"] = "video" - $cExt["mov"] = "video" - $cExt["mp4"] = "video" - - $cExt["gambas"] = "gambas" - $cExt["gbs"] = "gambas" - - $cExt["c"] = "c" - $cExt["cpp"] = "cpp" - $cExt["h"] = "h" - - $cExt["deb"] = "package" - $cExt["rpm"] = "package" - - $cExt["iso"] = "cdrom" - - $cExt["jpg"] = "image" - $cExt["jpeg"] = "image" - $cExt["png"] = "image" - $cExt["gif"] = "image" - $cExt["xpm"] = "image" - $cExt["bmp"] = "image" - $cExt["ico"] = "image" - $cExt["xcf"] = "image" - $cExt["svg"] = "image" - $cExt["svgz"] = "image" - $cExt["webp"] = "image" - - $cExt["pdf"] = "pdf" - - $cExt["ttf"] = "font" - $cExt["otf"] = "font" - $cExt["bdf"] = "font" - End Static Public Sub _exit() @@ -339,7 +277,7 @@ Private Sub GetIcon(sPath As String, iSize As Integer) As Picture Endif - Try sIcon = $cExt[File.Ext(sPath)] + Try sIcon = Main.Ext[File.Ext(sPath)] If sIcon Then hPict = Picture["icon:/" & CStr(iSize) &/ sIcon] Goto LOCK_ICON diff --git a/comp/src/gb.form/.src/Main.module b/comp/src/gb.form/.src/Main.module index 94f2416ee..f01420c0e 100644 --- a/comp/src/gb.form/.src/Main.module +++ b/comp/src/gb.form/.src/Main.module @@ -2,6 +2,8 @@ 'Class DesktopMime +Public Ext As New Collection(gb.IgnoreCase) + Private $cArrow As New Collection Private $bInitGTK As Boolean Private $bUseGTK As Boolean @@ -422,3 +424,69 @@ Public Sub AddEmblem(hPict As Picture, sIcon As String) As Picture End +Public Sub InitExt() + + Ext["html"] = "html" + Ext["htm"] = "html" + Ext["css"] = "css" + Ext["js"] = "js" + Ext["xml"] = "xml" + + Ext["tar"] = "archive" + Ext["gz"] = "archive" + Ext["tgz"] = "archive" + Ext["bz2"] = "archive" + Ext["z"] = "archive" + Ext["zip"] = "archive" + Ext["xz"] = "archive" + + Ext["txt"] = "text" + Ext["log"] = "text" + Ext["json"] = "text" + + Ext["mp3"] = "audio" + Ext["aac"] = "audio" + Ext["ogg"] = "audio" + Ext["oga"] = "audio" + Ext["flac"] = "audio" + Ext["wav"] = "audio" + + Ext["mpg"] = "video" + Ext["mpeg"] = "video" + Ext["avi"] = "video" + Ext["wmv"] = "video" + Ext["mov"] = "video" + Ext["mp4"] = "video" + Ext["mkv"] = "video" + + Ext["gambas"] = "gambas" + Ext["gbs"] = "gambas" + + Ext["c"] = "c" + Ext["cpp"] = "cpp" + Ext["h"] = "h" + + Ext["deb"] = "package" + Ext["rpm"] = "package" + + Ext["iso"] = "cdrom" + + Ext["jpg"] = "image" + Ext["jpeg"] = "image" + Ext["png"] = "image" + Ext["gif"] = "image" + Ext["xpm"] = "image" + Ext["bmp"] = "image" + Ext["ico"] = "image" + Ext["xcf"] = "image" + Ext["svg"] = "image" + Ext["svgz"] = "image" + Ext["webp"] = "image" + + Ext["pdf"] = "pdf" + + Ext["ttf"] = "font" + Ext["otf"] = "font" + Ext["bdf"] = "font" + +End