【Aviutl】Aviutl Controlプラグインを使って一括エンコードしようとしたら何度も同じファイルをエンコードしてしまう事象の解決方法

PC
この記事は約7分で読めます。
スポンサーリンク

事象

Aviutl Controlプラグインの導入方法を元にスクリプトを動かすところまでは問題なくできたが、

スクリプトを実行し、1つ目の画像を移動させる処理のところでどうやらおかしい動作をしている様子。

スクリプトがエラーになるわけでもないのに、ひたすら同じファイルをエンコードし続けてしまう。

ちょっと分かりにくいが、Aviutlで今エンコードが終わったばかりのファイルをまた開こうとしている(ファイルが移動していない)

類似事象

しばらく調べてみたが、解決方法は見つからず。

どうやら同じ(あるいは似ている)事象で困っている人が他にもたくさんいることがわかった。

解決方法

結局自分で色々試して解決に至ったので共有。

Aviutl Controlプラグインのサンプルコードに記載されているファイル移動の処理のタイミングで、PSDToolkit.exeがファイルを掴んでいるのが直接的なエラーの原因のようだった。

そのため、PSDToolkit.exeをタスクキルする処理を追加したところ、事象が改善し、本来の想定通りにエンコード後にファイル移動を行い、ループせずに次のファイルのエンコードに移ってくれるようになった。

エンコードが終わったらそのファイルが移動されて次のファイルの処理に入ってくれるようになった

修正したコードは以下に記載。
使う時はもちろんパスを自身の環境に合わせて変更してね。

'''
''' AviUtlエンコード&ファイル移動 サンプルスクリプト
'''
' あるフォルダの中のファイル全部について、
' プロファイル&出力プラグイン指定でエンコードし、
' エンコードが終わったら指定のフォルダに移動するスクリプト

On Error Resume Next

' キャプチャしたファイルがあるフォルダ(最後の文字は"\")
Const SOURCE_FOLDER  = "エンコード対象のパス"

' エンコードが終わったファイルを移すフォルダ(最後の文字は"\")
Const MOVE_FOLDER    = "エンコードが終わった後に元ファイルを移動する先のパス"

' エンコードしたデータを出力するフォルダ(最後の文字は"\")
Const OUTPUT_FOLDER  = "エンコード出力先のパス"

' プロファイル番号(メニューの一番上が0)
Const OUTPUT_PROFILE = 0

' 出力プラグイン番号(メニューの一番上が0)
Const OUTPUT_PLUGIN  = 0

' 出力ファイルの拡張子
Const OUTPUT_EXT     = ".mp4"

' AviUtlのフルパス
Const AVIUTL_PATH    = "aviutlのアプリケーションのフルパス"

' AviUtl Controlを置いてあるフォルダ(最後の文字は"\")
Const AUC_FOLDER     = ".\" ' = スクリプトと同じフォルダ

Dim WHSHell, Fs
Set WSHShell = WScript.CreateObject("WScript.Shell")
Set Fs = CreateObject("Scripting.FileSystemObject")

Function Auc(command, arg)
  Auc = WSHShell.Run("""" & AUC_FOLDER & "auc_" & command & ".exe"" " & arg, 2, True)
End Function

Dim srcFiles, srcFile, date, input, output, i, hwnd, open

' AviUtlのウィンドウ番号を取得

hwnd = Auc("findwnd", "")
open = 0
If hwnd = 0 Then
  hwnd = Auc("exec", """" & AVIUTL_PATH & """")
  If hwnd = 0 Then
    Call WScript.Quit(-1)
  End if
  open = 1
End if

' キャプチャしたファイルがあるフォルダが空になるまで繰り返す
While Fs.GetFolder(SOURCE_FOLDER).Files.Count > 0

  ' SOURCE_FOLDER で一番古いファイルを探す
  Set srcFiles = Fs.GetFolder(SOURCE_FOLDER).Files
  i = 0
  For Each srcFile In srcFiles
    If i = 0 Then
      date   = srcFile.DateLastModified
      input  = srcFile.Path
      output = OUTPUT_FOLDER & Fs.GetBaseName(input) & OUTPUT_EXT
      i = 1
    Elseif date < oFile.DateLastModified then
      date   = srcFile.DateLastModified
      input  = srcFile.Path
      output = OUTPUT_FOLDER & Fs.GetBaseName(input) & OUTPUT_EXT
    End if
  Next
  
  ' キャプチャしたファイルを開く
  Call Auc("open",    CStr(hwnd) & " """ & input & """")
  Call WScript.Sleep(3000)
  
  ' プロファイルを設定する
  Call Auc("setprof", CStr(hwnd) & " " & CStr(OUTPUT_PROFILE))
  Call WScript.Sleep(1000)
  
  ' 出力プラグインから出力する
  Call Auc("plugout", CStr(hwnd) & " " & CStr(OUTPUT_PLUGIN) & " """ & output & """")
  
  ' 出力が終わるまで待つ
  Call Auc("wait",    CStr(hwnd))
  
  ' ファイルを閉じる
  Call Auc("close",   CStr(hwnd))
  Call WScript.Sleep(3000)
  
  ' PSDToolkitのプロセスを強制終了
  KillProcess("PSDToolkit.exe")
  
  ' エンコードが終わったファイルを移動する
  Call Fs.MoveFile(input, MOVE_FOLDER)

Wend

' スクリプトで起動したAviUtlを終了する
If open = 1 Then
  Call Auc("exit", CStr(hwnd))
End if

' PSDToolkitのプロセスを強制終了する関数
Function KillProcess(processName)
    On Error Resume Next
    Dim WSHShell
    Set WSHShell = WScript.CreateObject("WScript.Shell")
    
    ' タスクマネージャーで指定したプロセスを強制終了
    WSHShell.Run "taskkill /F /IM " & processName, 0, True
    On Error GoTo 0
End Function

まとめ

同じ事象が発生していて、PSDToolkitをすでに導入している人は、もしかしたら同じ事象かもしれません。

本記事に記載している方法をぜひ試してみてください。

コメントの通知/購読設定
受け取る通知
guest
0 Comments
古い順
新しい順 評価順
Inline Feedbacks
すべてのコメントを見る
タイトルとURLをコピーしました