2016-04-06 47 views
4

FFMPEGライブラリを使用してAACオーディオストリームをmp4ファイルに書き込もうとしています。私はioContext->seekable = 0を設定する必要があるので、ソケットに直接書き込むカスタムIOコンテキストを使用しています。この作業を行うために、ヘッダを書き込むときに "movflags" empty_moovfrag_keyframeを追加しなければなりませんでした。シーク可能なAACオーディオストリームをFFMPEGでMP4ファイルに書き込む

出力をソケットの反対側のファイルに書き込んだ後、VLCまたはWindows Media Playerでファイルを再生できます。ただし、ファイル内の特定の位置を探すことは、両方のプレーヤーで正しく機能していません。また、WMPは合計時間を表示せず、VLCは音声の最後に近づくとすぐに点滅します。

マルチプレクサでメタデータを追加する方法はありますか?プレーヤはファイルをストリームとして書き込まないように扱うことができますか?ソケット経由での転送は突然中断されないので、ファイルの最後にメタデータを書き込むことができます。私はまた、事前に合計期間を知っているので、可能ならばファイルのヘッダーに追加することができます。 faststartフラグを使用することはできません。これは、ソケットに書き込む前にシーク可能なファイルに出力する必要があるためです。

アップデート:私はAVFormatContextに期間を設定することができると私はAVStreamnb_framesavg_frame_rateを設定することができることを学びました。しかし、それは私の問題を解決しません。 codecContextフラグAV_CODEC_FLAG_QSCALEを設定すると、VLCは合計時間を見積もることができます。しかし、依頼はまだ動作しません。

+0

この** [リンク](http://www.bogotobogo.com/VideoStreaming/ffmpeg_AdaptiveLiveStreaming_SmoothStreaming.php)**あなたがMOVフラグ(ワード検索であなたの問題を理解するのに役立つかもしれません: '-movflagsはempty_moov'と読みますセクションの残りの部分)。あなたは問題を説明しましたが、アプリケーションのコンテキストは何ですか?あなたはオーディオを受信して​​いるし、Xの金額がファイルに保存されるまでMP4を構築したいですか?まず、必要なAACをすべてバッファリングしてから最終的なMP4にエンコードするのはなぜですか? #すべてのオーディオフレームはキーフレームです。#MPEGデコーダはメタデータがない場合は検索できません。#M4aの出力を試してからMP4として名前を変更しますか? –

+0

PS:私はFFmpegをプロセスとして(直接インポートされたライブラリではなく)慣れていますが、実行中のプロセスとして 'ffmpeg -i - -c:libfdk_aac -b:128k output.mp4'を使用します。 '-i -'を使って入力ファイルがないことを知らせ、プロセスを終了して再生可能なAACの終わりまで各AACフレームのバイトを' process.writeBytes(myAACframe); 'に繰り返し書きます要するに、利用可能なAACフレームを追加することによって、動的に構築されたMP4ファイル。その論理の何かがあなたを助けることができるでしょうか? –

+0

回答がないと、100ポイントを燃え尽きさせる代わりに、ただ応答しないでください。他の人があなたを助けてくれたコメントを追加することができます。シーク可能なMP4ファイルが必要な場合は、メタデータを持っていることを確認してください**それは** MPEGデコーダを求めるための必需品です。 (これは、問題に追加するので、 '-movflags empty_moov&frag_keyframe'を失うことを意味します)。私はあなたの完全なコードが適切かどうか心配することなく、簡単なテストである(例: 'nb_frames'など)、" process "メソッドを提案しました。あなたの言語に応じて、C++、Java、またはC#で行うことができます。 –

答えて

1

あなたはシーク可能なMP4ファイルは、それが(MP4メタデータは、各AACフレームのバイト開始位置を示しています求めて処理するためのMPEGデコーダのためのneccessityだとして、それは間違いなく、メタデータを持っていることを確認したい場合。
これは彼ら以来-movflags empty_moov & frag_keyframeことを失うことを意味問題に追加

考えてみましょう:。

  • を全てのオーディオフレームがキーフレームとして分類されているので、あなたがfrag_keyframeを必要としない
  • empty_moovのを強制しないでください。 MP4デコーダは、メタデータがないかどうかを調べることはできません。 (FFmpegはフラグメンテーションモードでメタデータを扱います)。

ストリーミングのthis excellent guideからの引用:

断片化したファイルを書き込むには、通常のMOV/MP4は復号できない いる間に書き込みが(中断され 場合でも、ファイルは復号化可能であるという利点を有しています非常に長いファイルを書き込むときには メモリが少なくて済みます( のファイルが閉じられるまで、通常のMOV/MP4を書き込むと ファイルはすべての単一パケットに関する情報をファイルに保存するため)。欠点は、less compatible with other applicationsです。あなたが試みることができる

オプションは次のとおりです。

  • frag_duration [num]numミリ秒の長された断片を作成します。
  • frag_size [num]ペイロードのサイズが最大でnumバイトであるフラグメントを作成します。
+0

これは実際に動作しましたか?同様の問題に直面しています。なぜなら、httpでストリーミングされたときのAACファイルは、5.0.1と5.1の後でAndroid MediaPlayerでシークできないからです。オーディオは再生されますが、seekTo()を使用しようとするとオーディオは0から始まります。これはAndroid 5.0.1,4.4.2などの古いバージョンでは問題です。私はすでにmoov要素をファイルであり、ストリーミングしています。それはちょうどseekableではありません。メタデータが存在するかどうかを私のストリームで調べる必要がありますか? – chubbsondubs

関連する問題