2016年6月6日月曜日

ikaLogとFFMPEG Launcherを連携させるスクリプト+録画用コマンドライン

この記事の番外編。

FFMPEG Launcher(FFML)を配信用ではなくローカル録画用に使っている人は少ないだろうし
そもそもAutoItスクリプトの中で直接ffmpeg.exeを叩けばいいのだけど、
やり方を調べるのが面倒なので FFMLに設定を保存出来て便利なので、一応。

※以下のスクリプトはFFMPEG Launcher ver 0.0.1.15.8で動作を確認。

=============================↓↓ここから↓↓==============================
#include <FileConstants.au3>
#include <StringConstants.au3>

Const $STARTsleepSec = 0 ;録画開始の待機時間(秒で指定)
Const $STOPsleepSec = 10 ;録画終了の待機時間(秒で指定)
Const $RENAMEsleepSec = 2 ;録画終了後リネーム処理までの待機時間(秒で指定)

Func RenameFile($source)
Local $dest = EnvGet('IKALOG_MP4_DESTNAME')
$dest = StringReplace($dest, "/", "\")
If $dest = '' Then
Return False
EndIf

FileMove($source, $dest, $FC_OVERWRITE)
EndFunc

Func FindRecentRecording()
Local $directory = EnvGet('IKALOG_MP4_DESTDIR')

; Replace all slashes to backslashes.
; $directory also needs a backslash at its end.
$directory = StringReplace($directory, "/", "\")
If StringRight($directory, 1) <> "\" Then
 $directory = $directory & "\"
EndIf

Local $hSearch = FileFindFirstFile($directory & "*.mp4*")

If $hSearch = -1 Then
 MsgBox(0, "Error", "Could not find any candinates in " & $directory & " (path 1)", 10)
 Return False
EndIf

Local $latest_file = ''
Local $latest_timestamp = ''

While True
Local $file = FileFindNextFile($hSearch)
If @error Then ExitLoop

Local $timestamp = FileGetTime($directory & $file, $FT_MODIFIED, $FT_STRING)
If StringCompare($timestamp, $latest_timestamp) > 0 Then
$latest_file = $directory & $file
$latest_timestamp = $timestamp
 EndIf
WEnd

FileClose($hSearch)

If $latest_file = '' Then
MsgBox(0, "Error", "Could not find any candinates in " & $directory & " (path 2)", 10)
Return False
EndIf

Return $latest_file
EndFunc

Func ControlFFMPEGLauncher()
;ウィンドウを取得
Local $hWnd = WinWait("FFMPEG Launcher","", 1)

If $hWnd == 0 Then
Return False
EndIf

; 配信ボタンの文字列を取得
Local $l = ControlGetText ($hWnd, '', '[CLASS:WindowsForms10.BUTTON.app.0.141b42a_r28_ad1; INSTANCE:3]')
;「配信中」なら録画状態、それ以外なら待機状態
Local $recStatus = (StringCompare($l, '配信中') == 0)

If $recStatus Then
; 録画終了待機
Sleep(1000 * $STOPsleepSec)
Else
; 録画開始待機
Sleep(1000 * $STARTsleepSec)
EndIf

WinActivate($hWnd)
WinWaitActive($hWnd, "", 1)

; 配信ボタンを押す
ControlClick($hWnd, '', '[CLASS:WindowsForms10.BUTTON.app.0.141b42a_r28_ad1; INSTANCE:3]')

; 録画中だったらmp4ファイルのリネーム処理実行
If $recStatus Then
If EnvGet('IKALOG_MP4_DESTDIR') <> "" Then
Sleep(1000 * $RENAMEsleepSec)
Local $file  = FindRecentRecording()
RenameFile($file)
EndIf
EndIf

EndFunc

ControlFFMPEGLauncher()

=============================↑↑ここまで↑↑==============================

配信ボタンのクラス名は、以下のサイトを参考にして取得しました。

(スクリプトとは関係ない話)
自分の環境だとFFMPEGでのローカル録画時にCPU使用率が100%近くまで張りついてしまい、
どちらかというとスクリプトの作成よりその負荷解消に四苦八苦することに orz

結局一番効いたのは、プリセットをmediumからveryfastに変更すること。
よっぽど画質にこだわらない限り十分。crfやmaxrateは独立して調節できるし。

うーん、どのオプションがCPUに負荷をかけていたのやら。


おまけ ローカル録画用のコマンドライン
FFMPEG Launcherの高度な設定→拡張タブに入力して使う。
画質の高さより負荷の軽さを取っていくスタイル

コピペ用
----------------------------------------------
ffmpeg.exe -rtbufsize 200MB -f dshow  -i video="XSplitBroadcaster":audio="XSplitBroadcaster" -threads 0 -r 30  -profile main -preset veryfast -partitions parti4x4+partp8x8+partp4x4 -pix_fmt yuv420p  -crf 20.0 -maxrate 2000k -bufsize 4000k -vcodec libx264  -acodec libfdk_aac -profile:a aac_he  -afterburner 1 -ar 44100 -ab 192k -ac 2 -vsync 1 -async 1 -vol 256 -y "L:\ika\movie\ffmpegoutput.mp4"
----------------------------------------------

補足
ffmpeg.exe【※1】 -rtbufsize 200MB -f dshow  -i video="XSplitBroadcaster":audio="XSplitBroadcaster"【※2】 -threads 0 -r 30  -profile main -preset veryfast -partitions parti4x4+partp8x8+partp4x4 -pix_fmt yuv420p  -crf 20.0 -maxrate 2000k -bufsize 4000k -vcodec libx264  -acodec libfdk_aac【※3】 -profile:a aac_he  -afterburner 1 -ar 44100 -ab 192k -ac 2 -vsync 1 -async 1 -vol 256 -y "L:\ika\movie\ffmpegoutput.mp4"【※4】

※1
ffmpegにパスを通していない場合はフルパスで記述する

※2
オーディオ名には"XSplitBroadcaster"もしくはデバイス名を指定する。
デバイス名はFFMPEG Launcherの基本設定タブの「音声」欄で確認する。
(video/audioともに"XSplitBroadcaster"で揃えないと音ズレが発生する?要確認)

※3
このffmpegはオレ流FFmpegビルドツールでビルドしたものなのでlibfdk_aacを指定している。
公式版ffmepgの場合は-acodec aac(で合ってるっけ?)
そもそもaac v1で192kbpsとか色々ツッコミどころありそうだけどキニシナイ

※4
保存ファイル名は決め打ちでよい。
(ikaLog側で「録画ファイルを自動的にリネームする」にチェックを入れればOK)
もちろんフルパスは環境に合わせて変更する