タイム コードをビデオに焼き付ける必要がありますが、これが ffmpeg で可能なことでしょうか?
7 に答える
FFMPEG の drawtext フィルターは私にとってはうまくいきます。開始タイムコードとその形式を次のように指定します。
-vf drawtext="fontsize=15:fontfile=/Library/Fonts/DroidSansMono.ttf:\
timecode='00\:00\:00\:00':rate=25:text='TCR\:':fontsize=72:fontcolor='white':\
boxcolor=0x000000AA:box=1:x=860-text_w/2:y=960"
hh:mm:ss[:;,]ff の形式でタイムコード形式を指定する必要があります。タイムコード形式文字列のコロンをエスケープする必要があり、タイムコード レート (ここでは 25fps) を指定する必要があることに注意してください。追加のテキストを指定することもできます - ここでは「TCR:」です。
フレームレートは、ffprobe と少しのシェル fu で取得できます。
frame_rate=$(ffprobe -i "movie.mov" -show_streams 2>&1|grep fps|sed "s/.*, \([0-9.]*\) fps,.*/\1/")
したがって、バッチ処理スクリプトですべてを簡単にプラグインできます。
for i in *.mov
frame_rate=$(ffprobe -i "$i" -show_streams 2>&1|grep fps|sed "s/.*, \([0-9.]*\) fps,.*/\1/")
clipname=${(basename "$i")/\.*/}
ffmpeg -i "$i" -vcodec whatever -acodec whatever \
-vf drawtext="fontsize=15:fontfile=/Library/Fonts/DroidSansMono.ttf:\
timecode='00\:00\:00\:00':rate=$frame_rate:text='$clipname' TCR:':\
fontsize=72:fontcolor='white':boxcolor=0x000000AA:\
box=1:x=860-text_w/2:y=960" "${i/.mov/_tc.mov}"
done
これにより、1920x1080 フレームの下部中央にある半透明のボックスに、クリップの名前とローリング タイムコードが追加されます。
編集 私はダークサイドに来て以来、Windows Powershell 環境でこれを行っています。これは私が使用しているものです。
ls -R -File -filter *.M*|%{
ffmpeg -n -i $_.fullname -vf drawtext="fontsize=72:x=12:y=12:`
timecode='00\:00\:00\:00':rate=25:fontcolor='white':`
boxcolor=0x000000AA:box=1" `
("c:\path\to\destination\{0}" -F ($_.name -replace 'M[OPT][V4S]', 'mp4'))}
これは、.MOV、.MP4、および .MTS ファイルを含むフォルダーを指定して mp4 を作成します (-filter
コマンドを使用して、名前に *.M* が含まれるファイルを検索します。.AVI ファイルを実行している場合は変更する必要があります)。もう少し最小限で、デフォルト設定の libx264 を出力コーデックとして使用するだけで、フォントなどを指定しません。この場合のタイムコードは、フレームの左上に焼き付けられます。
@stibの回答に記載されているdrawtextフィルターは、時間を挿入するための鍵です。ただし、このオプションを使用すると、時計の時刻と一致しません。(timecode_rate) パラメータを間違えると、再生時間と一致しなくなります。timecode
r
他にもオプションがあります。たとえば、このtext='%{prt}'
オプションを使用すると、経過時間をマイクロ秒の精度で表示できます。指示:
ffmpeg -i video.mp4 -vf "drawtext=text='%{prt}'" output.mp4
代わりに時計を取得するには、非推奨のstrftime
オプションを使用する必要がありました。これには、マイクロ秒単位basetime
で開始時間を設定するために使用できる文書化されていないオプションがあります。開始時刻を 2013 年 12 月 1 日の午後 12:00 に設定し (一部はシェルによって実行されるシェル拡張です)、時刻のみを表示する例 (可能な形式については strftime マニュアルを参照してください):$(...)
ffmpeg -i video.mp4 -vf "drawtext=expansion=strftime: \
basetime=$(date +%s -d'2013-12-01 12:00:00')000000: \
text='%H\\:%S\\:%S'" output.mp4
\\:
をエスケープするために使用され、:
それ以外の場合はオプション区切りの意味を取得します。
別の例: ブラック ボックス内に日付 + 時刻を挿入するコマンド、左上隅から数ピクセル離れた場所、および「一部のパディング」(実際には、2 つのスペースと端の改行):
newline=$'\r'
ffmpeg -i video.mp4 -vf "drawtext=x=8:y=8:box=1:fontcolor=white:boxcolor=black: \
expansion=strftime:basetime=$(date +%s -d'2013-12-01 12:00:00')000000: \
text='$newline %Y-%m-%d %H\\:%M\\:%S $newline'" output.mp4
クロックの下のマイクロ秒を取得する別の例:
newline=$'\r'
ffmpeg -i video.mp4 -vf "drawtext=expansion=strftime: \
basetime=$(date +%s -d'2013-12-01 12:00:00')000000: \
text='$newline %H\\:%M\\:%S $newline':fontcolor=white:box=1:boxcolor=black, \
drawtext=text='$newline %{pts} $newline': \
y=2*th/3:box=1:fontcolor=white:boxcolor=black:" output.mp4
これは、テキストが実際には 3 行の長さであり、両方のテキストの前後に改行 (キャリッジ リターン、^M
) が追加されているという事実を利用しています。(この改行がないと、スペースが削除されます)
その他のヒント:
-vf
と-filter:v
等しいです。- フィルターを複数回指定することはできません。たとえば
-vf drawtext=text=1 -vf drawtext=text=2
、2 番目のテキストのみを描画します。上で示したように、フィルターをコンマで組み合わせることができます。
短い答え、いいえ。
長い答えですが、別のライブラリを使用して、レンダリングされたタイム コードを含むフレームを作成し、フレームの残りの部分を透明にしてから、FFmpeg を使用して既存のビデオにフレームを重ねます。頭のてっぺんからこれを行う方法はわかりませんが、創造的な人ならそれを理解できると確信しています.
編集:私にとって興味深い質問/プロジェクトであるため、私はこの問題に取り組んできました。FFmpeg がメタデータを読み取れるように構成されている特定のビデオ ファイルに対して、タイム コードが埋め込まれたファイルを生成するPerl スクリプトを作成することで、ソリューションをもう少し進めました。.srt
ライブラリを使用しVideo::FFmpeg
てデュレーションを読み取り、字幕ファイルを として保存します${video}.srt
。これにより、次の行を に挿入すると、Mplayer で自動的にレンダリングされるようになります~/.mplayer/config
。
# select subtitle files automatically in the current directory, all files
# matching the basename of the current playing file
sub-fuzziness=1
レンダリングされた字幕をビデオに配置してオーバーレイし、同じ形式で再エンコードする方法については、まだ作業中です。詳細がわかり次第、この投稿を更新します。
最近のビルドでは、drawtextフィルター (例の「t」はフレームのタイムスタンプだと思います) を使用してテキストを挿入できます。また、「現在の」システム時間の srtftime でも機能します。
私が見つけた最も簡単な解決策は、ファイルがキャプチャされたときに時計を表示することであり、その期間ではなく、機能しています/この投稿に基づいて、ありがとう!/
D:\Temp\2>ffmpeg.exe -i test.avi -vf "drawtext=fontfile=C\\:/Windows/Fonts/arial.ttf:timecode='00\:20\:10\:00':rate=25:text='TCR\:':fontsize=46:fontcolor=white:x=500:y=50: box=1: boxcolor=0x00000000@1" -f mp4 textts.mp4
タイムコードはとてもシンプルです - 開始時間を入力すると、カウントはうまくいきます! 例はWindows用です
FFMPEG は多くの作業を行うことができますが、すべてがパッケージ化されるわけではありません。FFMPEG を使用すると、すべてのフレームを順番にデコードし、「プレゼンテーション タイム スタンプ」を取得できます (一部の形式では時間関連の追加のメタデータを利用できる場合がありますが、開始するには PTS を探す必要があります)。 .) 次に、デコードされたフレームに実際にテキストを自分で描画する必要があります。フレームデータを含む QImage で QPainter を使用して、同様の目的で Qt を使用していますが、より明白な画像を描画するための他の API があるかもしれません。次に、FFMPEG API を使用して、新しく描画したフレームを含む圧縮ビデオを作成します。オーディオも必要な場合は、もう少し複雑になります。私自身の仕事ではオーディオはあまり気にしていないので、API のオーディオの側面について学ぶことはありませんでした。基本的に、ファイルからパケットを取得する読み取りループを実行すると、それらの一部はオーディオになります。私のようにそれらを破棄する代わりに、それらを保持し、取得したとおりに出力ファイルに書き込む必要があります。
私は C# ではなく C API しか使用していないので、心配すべき特別な落とし穴があるかどうかはわかりません。