はじまり
リサちゃん
GIFにしたいよなあ。
135ml
軽くしたいよなあ。
mp4をgifに変換したい。
動画として何かしらを残しておきたい時、音声フォーマットは要らないんだよなあ。という時があります。
つまり、MP4じゃなくていい、GIFでいい。
というわけで今回は、PowerShellからmp4ファイルをgifファイルに変換していきたいと思います。
ffmpegで変換していく。
今回、mp4からgifにファイルを変換するために、「ffmpeg」のライブラリを使っていきます。情報は沢山出てきました。定番みたいですね。
FFmpeg
ffmpegは様々なパッケージ管理ライブラリからインストールできます。今回は、Scoopからインストールしていきます。
scoop update
scoop install ffmpeg
そして、ffmpegでファイルを変換していきます。実行するバッチファイルはこんな感じです。
@echo off
setlocal enabledelayedexpansion
echo "%1"
:: Check if space is contained.
set "filePath=%~1"
echo "Check if the source file name contains SPACE characters. That causes a bug."
set /p tmp="The process is starting. Input any key."
Start /WAIT Powershell -Windowstyle Normal -NoProfile -ExecutionPolicy Unrestricted -File ".\Z5-5_convert_mp4_to_gif.ps1" %1 10 1080
:FINISH
set /p tmp="The process is terminated. Input any key."
endlocal
PowerShellファイルの中身はこんな感じです。
ffmpegの-vf
オプションを「"split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse"
」と指定すると、高画質に出力されます。しかし、サイズがかなり大きくなります。逆に、「"scale=1920:-1"
」という感じで指定すると、アスペクト比を維持しながら出力して、画質は悪くなりますがサイズがかなり減らせます。
function Convert-Mp4ToGif([string]$srcMovieAbsName, [Int32]$loop, [Int32]$fps, [Int32]$imgWidth) {
<#
.Synopsis
Converts an input video into an animated GIF
.Description
Converts an input video into a high-quality animated GIF.
Supported extensions are mp4, mkv.
.INPUTS
System.String # Path to the source MP4 file.
System.Int32 # 0: output GIF with loops forever. -1: output GIF with no loops.
System.Int32 # FPS of the output GIF.
System.Int32 # Width of the output GIF. 0: Outputs with higher quality with default width.
.Example
Convert-Mp4ToGif -srcMovieAbsName "C:\path\to\video.mp4" -fps 30
Get-ChildItem -Path "C:\path\to\videos" -Filter "*.mp4" | ForEach-Object { Convert-Mp4ToGif -srcMovieAbsName $_.FullName -loop 0 -fps 15 -imgWidth 0 }
Get-ChildItem -Path "C:\path\to\videos" -Filter "*.mkv" | ForEach-Object { Convert-Mp4ToGif -srcMovieAbsName $_.FullName -loop 0 -fps 15 -imgWidth 0 }
.Link
Nothing.
.Notes
Enjoy.
#>
Write-Host ("{0}: converting mp4 to gif.`n" -f $MyInvocation.MyCommand.Name);
Write-Output "Input: $srcMovieAbsName";
$srcFile = Get-Item -Path $srcMovieAbsName;
Write-Output "{0}" -f $srcFile.BaseName;
$dstExt = ".gif";
$srcFileDirectory = Split-Path $srcFile.FullName
$dstMovieAbsName = "{0}\{1}{2}" -f $srcFile.Directory, $srcFile.BaseName, $dstExt;
Write-Host ("{0}: destination decided.`n" -f $MyInvocation.MyCommand.Name);
Write-Output "directory: $srcFileDirectory"
Write-Output "destination to output: $dstMovieAbsName"
$vfStr = "split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse";
if ($imgWidth -ne 0){
$vfStr = "scale={0}:-1" -f $imgWidth;
}
ffmpeg -i "$srcMovieAbsName" -vf $vfStr -r $fps -loop $loop $dstMovieAbsName;
Write-Host ("{0}: finished converting mp4 to gif.`n" -f $MyInvocation.MyCommand.Name);
return $dstMovieAbsName;
}
$targetFolder = (Get-Location).Path;
$srcMovieAbsName = $Args[0];
$dstFps = $Args[1];
$dstImgWidth = $Args[2];
Write-Host ("{0}: destination decided.`n" -f $MyInvocation.MyCommand.Name);
Write-Output "srcMovieAbsName: $srcMovieAbsName"
if ($srcMovieAbsName.Contains(" ")) {
$tmp = Read-Host "Source file name contains space characters. Input 'y' to cancel this process.";
return;
}
if (-not $srcMovieAbsName.Contains(".")) {
$tmp = Read-Host "Source file name does not contain a dot as extension. Input 'y' to cancel this process.";
return;
}
Convert-Mp4ToGif $srcMovieAbsName 0 $dstFps $dstImgWidth;
$tmp = Read-Host "Input 'y' to move source files and terminate this process......";
If ($tmp -eq "y") {
$folderName = ".\5_original_files";
If (!(Test-path $targetFolder\$folderName)) {
New-Item -Name $folderName -ItemType Directory;
}
# Move-Item -Path .\*.mp4 -Destination $folderName -Exclude *$suffix*;
}
変換されたGIFはこんな風に動きました。FPS10です。
まとめ
今回の記事では、ffmpegライブラリを使って、mp4をgifに変換する流れを紹介しました。
これで動画を手頃なサイズで共有できるようになりましたね。
PowerShell関連記事
その他のPowerShell関連の記事を貼っておきます。
おしまい
リサちゃん
軽くなったなあ。
135ml
GIFになったなあ。
以上になります!
コメント