5

コンテキストとして、ffmpeg のリアルタイム コンソール出力を簡素化し、エンコードされている現在のフレームのみを表示するシェル スクリプトを作成しようとしています。私の最終的な目標は、この情報をバッチ処理の進行状況インジケーターとして使用することです。

ffmpeg の出力に慣れていない人のために説明すると、エンコードされたビデオ情報が stdout に出力され、コンソール情報が stderr に出力されます。また、実際にエンコード情報を表示するときは、改行を使用してコンソール画面がいっぱいにならないようにします。これにより、単純に grep と awk を使用して適切な行とフレームの情報を取得することができなくなります。

私が最初に試したのは、trを使用してキャリッジリターンを置き換えることです:

$ ffmpeg -i "ScreeningSchedule-1.mov" -y "test.mp4" 2>&1 | tr '\r' '\n'

これは、リアルタイムの出力をコンソールに表示するという点で機能します。ただし、その情報を grep や awk などにパイプすると、tr の出力はバッファリングされ、リアルタイムではなくなります。例:$ ffmpeg -i "ScreeningSchedule-1.mov" -y "test.mp4" 2>&1 | tr '\r' '\n'>log.txtファイルにすぐに何らかの情報が書き込まれ、5 ~ 10 秒後に、さらに多くの行がログ ファイルにドロップされます。

最初は sed がこれに最適だと思っていました: $ # ffmpeg -i "ScreeningSchedule-1.mov" -y "test.mp4" 2>&1 | sed 's/\\r/\\n/'、しかし、すべての改行を含む行に到達し、処理が完了するまで待ってから何かをしようとします。これは、sed が行ごとに動作し、他の処理を行う前に行全体が完了する必要があり、とにかく改行を置き換えないためだと思います。改行と改行についてさまざまな正規表現を試しましたが、改行に代わる解決策をまだ見つけていません。私はOSX 10.6.8を実行しているので、BSD sedを使用しています。これが原因かもしれません。

また、情報をログ ファイルに書き込んでtail -f読み戻そうとしましたが、リアルタイムでキャリッジ リターンを置き換えるという問題が発生します。

Python と Perl でこれに対する解決策があることを確認しましたが、すぐにその方法に進むのは気が進まないのです。まず、私は python も perl も知りません。第二に、完全に機能するバッチ処理シェル アプリケーションがあり、それを移植するか、python/perl と統合する方法を理解する必要があります。おそらく難しいことではありませんが、絶対に必要でない限り、私がやりたいことではありません。だから私はシェルソリューション、できればbashを探していますが、どのOSXシェルでも問題ありません。

そして、私が望んでいることが単に実行できない場合は、そこに着いたらその橋を渡ろうと思います.

4

3 に答える 3

5

パイプの後の受信アプリケーションによる出力バッファリングのみの問題である場合。次に、gawk(およびいくつかのBSD awk)を使用するか、mawkバッファをフラッシュできるかを試すことができます。たとえば、次を試してください。

... | gawk '1;{fflush()}' RS='\r\n' > log.txt

または、awk がこれをサポートしていない場合は、出力ファイルを繰り返し閉じて次の行を追加することで、これを強制することができます...

... | awk '{sub(/\r$/,x); print>>f; close(f)}' f=log.out

または、次のようにシェルを使用することもできますbash

... | while IFS= read -r line; do printf "%s\n" "${line%$'\r'}"; done > log.out
于 2013-05-01T14:31:30.897 に答える