web-dev-qa-db-ja.com

iOS用にトランスコードされたMP4(HEVC / x265 / mov_text)とSRT字幕をマージする際の問題:「ptsには値がありません」および「mov / mp4形式の範囲外です」

HEVC(x265)ビデオエンコーディングを使用してMKVビデオをMP4にトランスコードし、すべてiOSと互換性のある方法でファイルを小さくする方法を学びました。しかし、プロセスは素晴らしく、ファイルサイズが小さいと圧縮も素晴らしくなりますが、字幕を1つの特定のビデオにマージしようとすると、結果のMP4ビデオに次のようなエラーが山積みになります。

[mp4 @ 0x7facb9002000] pts has no value
[mp4 @ 0x7facb9002000] Application provided duration: 3152805999 / timestamp: 3154741000 is out of range for mov/mp4 format

Homebrew経由でFFmpeg4.2.1がインストールされたmacOSMojave(10.15.2)を使用していますが、 ナイトリービルド (ffmpeg-4.2.1-macos64-static、20191215-)をダウンロードしても問題は解決しません9fe0790)、Homebrewでインストールされたバージョンの代わりにそのバイナリを使用します。

問題は、過去にx264ビデオとAACオーディオを使用してMP4に正常に変換したこのビデオがあり、SRT字幕も問題なく結果のファイルにマージできることです。しかし、今日、同じ正確なソースからHEVC(x265)ビデオを使用してMP4を作成すると、SRT字幕のマージが失敗し、「ptsには値がありません」および「mov/mp4形式の範囲外です」というエラーが発生します。

これは、MKVソースからHEVC(x265)MP4ビデオを作成するために使用するコマンドです。

ffmpeg -i input.mkv \
       -map_metadata -1 \
       -vf scale=-1:720 \
       -c:v libx265 -crf 20 -c:a aac -b:a 128k \
       -threads 4 \
       -tag:v hvc1 -sn \
       -map 0:0 -map 0:1 output_hevc.mp4 \
       ;

これは、過去にSRT字幕を再エンコードせずに既存のMP4にマージするために正常に使用されたコマンドです。

ffmpeg -i output_hevc.mp4 \
       -i input.srt \
       -c:v copy -c:a copy \
       -c:s mov_text -metadata:s:s:0 language=eng \
       output_final.mp4 \
       ;

問題は、ビデオの約50%に字幕がないことだと思います。ビデオの2番目の50%でのみ、字幕が必要です。

問題のビデオの長さは約2時間です。そして最初の50分ほどは英語の字幕は必要ありません。しかし、約50分で、字幕が始まります。

したがって、SRTの字幕は次のように始まります。

1
00:52:33,123 --> 00:52:50,123
It was a dark and stormy night…

しかし、上記のFFmpegコマンドを実行すると、出力は次のようになります。たとえば、目的が少し曖昧な場合:

Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
  Stream #1:0 -> #0:2 (subrip (srt) -> mov_text (native))
Press [q] to stop, [?] for help
frame=25560 fps=0.0 q=-1.0 size=  304640kB time=00:52:00.00 bitrate= 791.7kbits/frame=50730 fps=50726 q=-1.0 size=  681984kB time=time=00:52:00.00 bitrate=1772.4kbit[mp4 @ 0x7facb9002000] Application provided duration: 3152137000 / timestamp: 3152137000 is out of range for mov/mp4 format
[mp4 @ 0x7facb9002000] pts has no value
[mp4 @ 0x7facb9002000] Application provided duration: 3152805999 / timestamp: 3154741000 is out of range for mov/mp4 format
[mp4 @ 0x7facb9002000] pts has no value
[mp4 @ 0x7facb9002000] Application provided duration: 3153246998 / timestamp: 3156809000 is out of range for mov/mp4 format
[mp4 @ 0x7facb9002000] pts has no value
[mp4 @ 0x7facb9002000] Application provided duration: 3154051997 / timestamp: 3159013000 is out of range for mov/mp4 format
[mp4 @ 0x7facb9002000] pts has no value
[mp4 @ 0x7facb9002000] Application provided duration: 3155556996 / timestamp: 3163817000 is out of range for mov/mp4 format

そして、同様のメッセージがたくさんあります。マージは終了し、字幕は表示されません。

これは私を狂わせています!つまり、同じコマンドを使用するが、字幕が入ってくる時点から始まるシーク時間を指定すると、実際には、字幕が必要なビデオの50%に字幕が表示されます。

ffmpeg -I output_hevc.mp4 \
       -i input.srt \
       -c:v copy -c:a copy \
       -c:s mov_text -metadata:s:s:0 language=eng \
       -ss 3120 \
       output_final.mp4 \
       ;

もちろん、ビデオの50%以上が必要です。一体、私はこのコマンドを試しただけです。シークを1005秒以上の任意の値に設定すると、字幕をMP4とマージできます。

ffmpeg -i output_hevc.mp4 \
       -i input.srt \
       -c:v copy -c:a copy \
       -c:s mov_text -metadata:s:s:0 language=eng \
       -ss 1005 \
       output_final.mp4 \
       ;

しかし、これに関連して、16.75分(1005秒)ほど魔法のようなものは何ですか?

ビデオの2番目の50%に字幕が表示される時間を選択しただけで、ビデオ全体をマージするコマンドを実行した場合ではなく、字幕をマージできるのはなぜですか?

FWIW、同様のコマンドを実行してビデオのMKVを作成すると、すべて問題ありません。

ffmpeg -i output_hevc.mp4 \
       -i input.srt \
       -c:v copy -c:a copy -c:s copy \
       output.mkv \
       ;

どういうわけか、これをmov_textとマージすると、プロセスが失敗するように見えます。

そして、次のようにファイルの先頭に偽の字幕を追加すると、次のようになります。

0
00:00:00,000 --> 00:16:75,000
Foo!

1
00:52:33,123 --> 00:52:50,123
It was a dark and stormy night…

すべてが希望どおりに機能します! 「Foo!」という言葉があることを除いてビデオの50%に表示されます。明らかに理想的ではありません。

これを回避する方法はありますか?これはFFmpegのバグですか、それとも字幕がマージされているHEVC(x265)ビデオの問題ですか?

1
JakeGould

ビデオの冒頭から字幕が始まる場所までのSRTファイルの先頭に偽の字幕を追加するようです。この問題は修正されました。

このソリューションは明らかに「ハック」ですが、機能します。

SRTファイルの先頭に偽の字幕を追加するという私の考えから離れて、私はSRT字幕が SRT仕様 に従って-HTMLタグを許可することに気づきました。私が次の偽の字幕を追加したことを知っていて、それはすべてうまくいきます!

0
00:00:00,000 --> 00:16:75,000
<b></b>

1
00:52:33,123 --> 00:52:50,123
It was a dark and stormy night…

それでおしまい!空の太字タグを追加するだけで、すべてが機能し、字幕をマージできます…


しかし、冒頭で述べたように、これは明らかにハックであり、FFmpegについてもっと知っている他の人からもっと多くのことを聞くことができます。この問題はいずれも望ましい動作を反映していないと推測できます。このようなケースに対処するには、より洗練された方法が必要です。または、これはバグ(機能ではない)であり、報告する必要がありますか?

2
JakeGould