0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ffmpegによるメタ情報再構成.ps1

Posted at

1. スクリプト概要

スクリプト名: ffmpegによるメタ情報再構成.ps1
動画ファイルのメタ情報を再構成し、新しいファイルを生成します

2. 処理と目的

処理の流れ
 1. 再構成対象の動画ファイルもしくはフォルダのフルパスを指定します
 2. 出力用の一時フォルダを自動で取得します
 3. FFmpegの機能を利用して、メタ情報を再構成したファイルを生成します
 4. 手順3で作成したファイルの作成日時と更新日時を、元のファイルと同じ値に設定します
 5. 手順3〜4の処理を、指定されたファイルの数だけ繰り返します
 6. 手順2で取得した一時フォルダをエクスプローラーで開きます

目的
 動画ファイル再生時にシークが正常に動作しない場合の改善を目的としています

3. 動作環境と要件

PowerShellのバージョン
7.0以上

OS
Windows10

必要なモジュール
FFmpeg

必要な権限
特になし

その他の設定
特になし

4. 使用方法

基本的な実行方法
スクリプトコードを拡張子ps1で保存してPowershellで実行してください。
ファイルを保存する際は、文字コードをUTF8 BOM付にしてください。
FFmpegをインストールして環境パスを通してください

パラメータ
なし

使用例

  1. コマンドラインでpwsh ffmpegによるメタ情報再構成.ps1を実行します
  2. 検索対象のフォルダまたはファイルのフルパスを入力するプロンプトが表示されるので、パスを入力します

5. スクリプトコード

$host.UI.RawUI.WindowTitle = ([IO.Path]::GetFilenameWithoutExtension($PSCommandPath))
$ErrorActionPreference = 'Stop'

# 処理対象ファイルリストを初期化
$filelist = @()
do {
    # 有効な入力パスが指定されるまでループ
    do {
        # 入力フォルダ名の入力を促す
        $inputDir = Read-Host "入力フォルダ名"
        # 入力されたパスの前後の引用符をトリム
        $inputDir = $inputDir.trim('"')
    } while(!(Test-Path -literal $inputDir)) # パスが存在しない場合は再入力を求める

    # 入力パスがファイルの場合
    if ([IO.File]::Exists($inputDir)){
        # ファイルリストにそのファイルを追加
        $filelist += Get-Item -literalPath $inputDir
    } # 入力パスがディレクトリの場合
    elseif ([IO.Directory]::Exists($inputDir)){
        # ディレクトリ内のファイルを取得し、特定の拡張子を除外してファイルリストに追加 # .zip, .rm, .rmvb 拡張子のファイルは処理対象外
        $filelist += Get-ChildItem -literalPath $inputDir -File | Where-Object {$_.Extension -notin ('.zip','.rm','.rmvb')}
    }
} while($filelist.Count -eq 0) # ファイルリストが空の場合(有効なファイルが見つからない場合)は再入力を求める

echo "---------------------------------------------------------------------"
echo "--${filelist}"
echo "---------------------------------------------------------------------"
pause

# 一時出力ディレクトリの作成
do {
    $outputDir = (Join-Path ([IO.Path]::GetTempPath()) ([IO.Path]::GetRandomFilename()))
} while((Test-Path -literal $outputDir)) # 生成されたパスが既に存在する場合は再生成
$null = mkdir $outputDir


foreach( $filedata in $filelist ){
    echo $filedata.fullname

    # 入力ファイル名をフルパスで取得
    $inputfilename = $filedata.fullname
    # 出力ファイル名を一時出力ディレクトリ内に元のファイル名で設定
    $outputfilename = (Join-Path $outputDir ([IO.Path]::GetFilename($inputfilename)))

    # FFmpegコマンドを実行してメタ情報を再構成
    # -i $inputfilename : 入力ファイル
    # -c:v copy : 映像ストリームをコピー(再エンコードしない)
    # -c:a copy : 音声ストリームをコピー(再エンコードしない)
    # -map 0:v : 最初の入力ストリームの映像トラックを全て選択
    # -map 0:a? : 最初の入力ストリームの音声トラックを全て選択(存在しない場合は無視)
    # $outputfilename : 出力ファイル名
    & ffmpeg -i $inputfilename -c:v copy -c:a copy -map 0:v -map 0:a? $outputfilename
    
    if($LASTEXITCODE -ne 0){
        # FFmpegの終了コードが0以外の場合(エラーが発生した場合)
        Write-Warning "ffmpegでエラーが発生しました。LASTEXITCODE=${LASTEXITCODE}"

    } else {
        # エラーがない場合
        
        # 出力ファイルの作成日時を元ファイルの作成日時に設定
        (Get-Item -literalPath $outputfilename).CreationTime = (Get-Item -literalPath $inputfilename).CreationTime
        # 出力ファイルの更新日時を元ファイルの更新日時に設定
        (Get-Item -literalPath $outputfilename).LastWriteTime = (Get-Item -literalPath $inputfilename).LastWriteTime

    }
}

# 処理が完了したら一時出力ディレクトリをエクスプローラーで開く
& explorer $outputDir
pause

6. 注意事項と既知の問題

制約事項
大量のファイルやサイズの大きいファイルを処理する場合、完了までに時間がかかる可能性があります。

既知のバグ
もしバグを発見された場合は、コメントでご報告ください。

トラブルシューティング
・ps1ファイルのエンコーディングには注意してください。
・FFmpegをインストールして環境パスを通すことが必要です

7. 免責事項

本スクリプトにはいかなる保証もありません。使用は自己責任で行ってください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?