首先,要先把 Icaros 安裝好,不裝也可以,只是不一定可以拿到的縮圖。
接著,需要神秘的 WindowsAPICodePack,這裡有連結,只要 Core 和 Shell 兩樣,兩件事情提醒:
- Code 和 Shell 要相同版本
- NuGet 下載下來的檔案,其實就是 zip 檔,只需要 lib 目錄底下的 .dll 檔案
thumbnail 馬上拿到
將 WindowsAPICodePack裡面的兩個 .dll 檔案,放在你喜歡的地方:
try
{
Add-Type -path "Microsoft.WindowsAPICodePack.dll";
Add-Type -path "Microsoft.WindowsAPICodePack.Shell.dll";
}
catch [System.Reflection.ReflectionTypeLoadException]
{
Write-Host "Message: $($_.Exception.Message)"
Write-Host "StackTrace: $($_.Exception.StackTrace)"
Write-Host "LoaderExceptions: $($_.Exception.LoaderExceptions)"
}
$shellFile = [Microsoft.WindowsAPICodePack.Shell.ShellFile]::FromFilePath("some things here.mp4");
$bitmap = $shellFile.Thumbnail.ExtraLargeBitmap;
$bitmap.Save("D:\temp\bm.bmp");
#Start "D:\temp\bm.bmp";
D:\temp\bm.bmp 就是縮圖了!有 small、medium、large、extra large 四種 size 的縮圖,就那麼簡單,所以我說「用 ffmpeg 一張一張產生」還是叫做不知道。
如果只拿到檔案類型的 icon,代表縮圖還沒有產生,用檔案總管去看看有沒有縮圖,如果你想知道縮圖是哪個程式在負責,以下是方法:
New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT ;
$guid = (((Get-ChildItem HKCR:\.mp4\shellex) | Where -Property Name -eq -Value "HKEY_CLASSES_ROOT\.mp4\shellex\{e357fccd-a995-4576-b01f-234630154e96}")).GetValue("");
Get-ChildItem HKCR:\CLSID\$guid;
如果你安裝了 Icaros,就會看到 C:\Program Files\Icaros\64-bit\IcarosThumbnailProvider.dll 負責提供縮圖。
修改檔案詳細資料
再來,在 Windows 裡面的檔案,如果你在檔案總管裡面,找一個檔案按右鍵,再選詳細資料,就可以看到詳細資料。例如影像、圖形檔,就會看到長、寬,音樂影像就有時間長度,大部分資料是唯讀的,可以修改的,例如評等;這些詳細資料,可以用 Shell.Application 拿到,這不是新鮮事,只是用 Shell Application 拿到的所有資料,都是唯讀,不能修改。
現在當然也有好消息了:
$shellFile.Properties.DefaultPropertyCollection | Select CanonicalName
可以看到一大堆「詳細內容」的名稱,$shellFile.Properties.GetProperty('System.Rating')就是我一直想改的「評比」了。
$rating = $shellFile.Properties.GetProperty('System.Rating');
$rating.Value = 50;
1、25、50、75、99 分別代表 1、2、3、4、5 顆星,所以設定成 50 (到 74 之間),那個檔案就是三顆星了。
這兒還有 System.Video.FrameHeight、System.Video.FrameDuration 之類的值,不過速度不算快,除非只是少少一、兩個檔案,否則建議用 SYSTEMINDEX 來取得這些詳細資料;寫資料的速度也不快,如果真的要用,得注意注意。
什麼?你連 frame width 這些,也是去問 ffmpeg 的?太震驚了!如果有些資料是用 Windows 問不到的,例如 video 的 codec ID,除非只是少少一、兩個檔案,可以去執行 ffmpeg 來問,否則建議可以用 MediaInfo.dll,它載入後就在記憶體裡面了,當然快多了!
MediaInfo.dll 下回再說。