ラベル ffmpeg の投稿を表示しています。 すべての投稿を表示
ラベル ffmpeg の投稿を表示しています。 すべての投稿を表示

2025年7月18日金曜日

ffmpeg(ver 7.1.1) 動画をカットしたら音声だけ抜け落ちた

最近古い動画ファイルの不要な部分をカットしようとしたところ音声がない動画ファイルになってしまうという症状に悩んでいました。

やってることは再エンコなしで

ffmpeg -to 00:15:00 -i FileName -c copy CutedFileName

といった感じで不要な末尾をカットしているだけなのですが…

動画ファイルの日付を見ると2022/10/05とか結構昔のファイルです。

ffprobeで元ファイルとカット後のファイルを比べてみると映像と音声のストリームは存在するものの、音声ストリームのDURATIONが00:00:00.000000000となってしまっている。

確かにファイルサイズも音声分サイズが小さくなっている感じにw

色々と検索して調べてみるものの、似たような現象はあるものの、そちらでは音声のみ切り出せるようなのですが、こちらでは切り出しは行えず、再エンコーディングすれば音声を取り出せるのみ。

少し現象が違うものの、原因はffmpegの過去のバグに起因するっぽい感じ。 

aacで再エンコするとかなり高音域の音が歪まくるのでflacを使用するという手もあるのですが、ファイルサイズがそれなりに大きくなってしまうので、割り切って作業を進めることもできず途方に暮れていました。最悪、ffmpegのソースに手を入れて、バグ回避させてビルドすることも考えたのですが、手元にgcc環境が無いので少し時間をおいてみることに。

そして今日、過去のffmpegのバイナリーを使って試してみようかと。

現状メインで使っているのはffmpeg 7.1.1ですが、公式のリンクから存在したのはオートビルドのバイナリが格納されているBtbNさんのところで、現時点で最古のものはAuto-Build 2023-08-31 12:54のもの。

試しにmasterではなく、バージョン4.4.4-6を試してみました。

結果としては、あっさりと音声付きの動画を作ることができました。

同様に、5.1.3-16, 6.0-34でも問題なく動画が作成されました。

これらのバージョンで作成された後のファイルは7.1.1でも正しく処理が通るようになりました。 

今度は逆にどこまでのバージョンがこのバグ回避が行えるか気になったので調べてみると、Auto-Build 2025-07-17 14:10の6.1.2-192でも問題なし。しかし7.1.1-56では音声が無くなる状況に。

version 7ベースで最古のものが Auto-Build 2024-04-30 12:51に含まれていた7.0-21を試したところ、こちらは音声が含まれ問題がなさそうでした。

結論として7.1以上では、どうもバグのあるファイルでは-acodec copyが機能しなくなるのでしょう。

公式でwindows版のビルドを公開しているhttps://www.gyan.dev/ffmpeg/builds/ではprevious release version: 7.0.2が残っているので試したところ問題はない様子。

問題がなければ、現状ffmpegは7.0.2を使うのが幸せなのかな?
  

2022年5月11日水曜日

ffmpegの出力中にファイルを移動させると…

多分ファイルシステムが強固なwindowsなら、ファイル移動が失敗するのでしょうけど、linuxは簡単に移動できてしまう気がするのですが?

Windowsでも処理の実装方法によっては常にopenとcloseを繰り返している場合は処理中でも他からファイルを消したりすることはできるので、何とも言い難い部分だったり、そもそもそんな事するなと言うのが当たり前だったり。

まぁでもmotionだと内部からイベントの各タイミングで丁寧にフォークしてシェルコマンドが呼び出されてたりするので、かなり運用任せでいろいろできてしまうので表題のような処理になってしまいましたw

結論から言えば、運が良ければ動画ファイルとしては何とか通用するものとなりますが、ファイルフォーマット形式でいえば確実に破損状態となり、再生することもできなくなります。

motionで、ビルトインコーデックであれば外部イベント処理が呼び出される前に処理が完了している感じだったのですが、外部パイプでエンコーダ実行されている場合、エンコーダ自体もフォークされているっぽいので処理が終わってないことも。

試しに使ったlibx265とかだと、処理が重いためか確実に処理途中となってエラー処理になってしまっていました。ハードウェアが利用できると処理が軽くなるために今までは気になったことはないのですが、先ほど書いた記事にある通り、minimum_motion_framesを20とか頭の悪い設定していると、エンコード処理が間に合わずエラー処理へ。

で、そこからはエラー処理の話になるのですが、後からチェックできるようにエラーファイルはゴミも含めてフォルダに退避させているのですが…まだ出力中のファイルを移動することになって結局動画が死んでしまうというジレンマに。

そして結局取るべき措置としては、エンコードしている場合は処理を待ちましょうということ。

linuxではよくある話らしく、psとgrepを使ってプロセスを監視するのが当たり前の様で。

で、実装して処理を待つようにしました。ビルトインの場合はチェックができない…なのでまぁ外部パイプでエンコードしている場合のみですが回避できるように。

しかし、最初はそんなに大したことにはならないはずだったのに、結構色々詰め込んでしまった気がする。