私の究極の目標は、fdkaacでコーディングしたときにzenity進行ダイアログを取得することです。
最初は、Lameを使用して「aa.wav」を「aa.mp3」にエンコードするときに正しく機能するいくつかのコードで始めました。これにより、進行状況バーは0から100%までシームレスに更新されます。
lame -m auto -V 4 aa.wav aa.mp3 | awk -vRS='\r' '(NR>3){gsub(/[()%|]/," ");print $2; fflush();}' | zenity --progress --title="Title" --text="encoding" --auto-close
次に、fdkaacを使用してこのコードを実行します。
fdkaac --profile 2 --bitrate-mode 5 aa.wav -o aa.aac
すると、エンコードが終了すると画面が出力されます。
[100%] 05:31.227/05:31.227 (43x), ETA 00:00.000
14607096/14607096 サンプルが 00:07.689 で処理済み
エンコード中に最初の行が印刷され、[100%]はエンコード中に0から100までシームレスに更新されます。エンコードの終わりに2行目を印刷します。
これに基づいてgsub検索を修正し、gsub(/[[%]/," ")に置き換えてデータを選択しました。
次に、次のコードを実行します。
fdkaac --profile 2 --bitrate-mode 5 aa.wav -o aa.aac 2>&1 | awk -vRS='\r' '(NR>3){gsub(/[\[%]/," ");print $1; fflush();}' | zenity --progress --title="Title" --text="Encoding" --auto-close
結果は私が期待していたものとは異なりました。進行状況ダイアログボックスに0%が表示されます...一定時間が経過すると50%にジャンプし、エンコードが完了すると消えます。
だから私は次のコードを使ってzenityに入ってくるデータを見ました。
fdkaac --profile 2 --bitrate-mode 5 aa.wav -o aa.aac 2>&1 | awk -vRS='\r' '(NR>3){gsub(/[\[%]/," ");print $1; fflush();}'
画面出力が予想したものとは異なります。 1から50までが同時にすべて印刷されますが、連続した行に印刷され、エンコードが完了すると、50から100までの連続した行に別々に印刷されます。
1
2
3
4
5
...
48
49
50
そして50まで続く。その後、出力は別の行に50から100まで続きます(再び同時に印刷されます)。
50
51
52
..
98
99100
したがって、問題は明らかです。出力データは2つのバッチで印刷されます(ダイアログボックスに表示されます)。そして、データは連続した行に表示されます。 (awkフィルタの後の誤った出力はすべて同じ行に印刷され、シームレスに更新されます。)
問題は追加のキャリッジリターンに関連していると思われますが、それを取り除く方法がわかりません。 -vRS='\r コマンドを削除しようとしましたが、まったく出力が提供されませんでした。
置換を理解できません: RS='\r'。変数RSはどこに現れますか?
データを出力してみると、正確に50%と100%であるのも驚きです。なぜ38%または67%ではないのですか? ..データが私に何かを教えてくれましたが、それが何なのかはよくわかりません。
ベストアンサー1
問題は、fdkaac
出力がパイプに移動しながら出力をバッファリングすることです。コマンドの前に以下を付けてみてください。
stdbuf -o 0 -e 0 fdkaac ... 2>&1 | ...
そのうち、-o は stdout を表し、-e は stderr を表します。
awkの代替を試すには、シェルスクリプトを使用できます。シェルがbashであることを確認してください
stdbuf -o 0 -e 0 fdkaac ... 2>&1 |
(IFS="$IFS%[]"
while read -d$'\r' junk1 percent junk2
do echo "$percent"
done) |
zenity --progress --title="Title" --text="encoding" --auto-close
追加の3文字 "%[]"を含むようにバスフィールド区切り記号(IFS)を設定すると、実際には入力のスペースのようになります。したがって、read
区切り文字キャリッジリターン(-d)を使用すると、行は次のようになります。 1つの単語がvarに入力されます。ゴミ 1、パーセンテージ 2 番目、残りのゴミ 2. 次に、数字だけを保持する必要がある変数をエコーできます。
注:数値フィールドを取得できることを確認するには、zenityビットなしでこれを試してください。パーセントが行の最初のフィールドである必要があるため、最初のvarjunk1を使用する理由がわかりません。ただし、目的の数値が得られない場合は、読み取りからjunk1変数を削除してみてください。