それぞれの AVAssetWriterInput を介してそれぞれのサンプルを AVAssetWriter に追加する 2 つのメソッド (オーディオ用とビデオ用) があります。単純な開始と停止のケースでは、すべてがうまく機能します。ここでの背景として、オーディオ ストリームはエコー抑制を適用した coreAudio から送られ、ビデオ フィードは setSampleBufferDelegate を介して AVCaptureVideoDataOutput から供給される AVCaptureVideoDataOutputSampleBufferDelegate を介して送られます。
問題は、録音を一時停止し、後で録音を再開したいときに、フィードのオーディオ部分とビデオ部分で異なることが起こることです。これまでのところ、一時停止からの再開後にオーディオとビデオの同期を保つことができませんでした。
appendSampleBuffera を介してオーディオ サンプル データを追加すると、CMSampleBufferRef に正確なタイム スタンプが含まれていても、サンプルのない期間が「スキップ」されないように見えます。つまり、オーディオ サンプルが追加されるとき、CMSampleBuffer のタイムスタンプが何であるかはあまり気にしません... (たとえば) 120 秒あったとしても、サンプルを連続して積み上げ続けるだけです。オーディオ データにギャップがあっても、そのための「空きスペース」は作成されません。
ビデオ サンプルの動作が同じである限り、率直に言って気にしません (ただし、そうではありません)。ビデオ サンプルの場合、結果として得られるビデオ エンコーディングはサンプルをスキップしますが、データがない期間は長時間の空のビデオ フレームが作成されます。
したがって、素朴な実装から、一時停止中、一時停止中は空白のビデオ セクションが取得されますが、オーディオ セクションでは、次の一時停止されていないセクションのサンプルが連続して取得されます。これは、一時停止および一時停止解除 (avasset ライターへのバッファー データの追加を抑制することによる) により、オーディオとビデオの間の完全な非同期化が発生することを意味します。
私が試した救済策:
CMSetAttachment() を使用して kCMSampleBufferAttachmentKey_FillDiscontinuitiesWithSilence を設定します -- オーディオ チャネルに対して、ビデオ ストリームと同じように動作することを期待します。これはまったく効果がありませんでした。私はそれを間違ったかもしれませんが、これに関する実際の文書がないので、これを暗闇の中で撮影します.
「一時停止」の影響を受ける期間に独自の空のサンプルを追加します(appendLapsedAudiotimeを介して)。問題は、バッファが正しく得られたとは思わないことです.0または1つのサンプルでオーディオバッファを追加し、それを非常に長期間にわたって拡張できるかどうかは不明です. 一時停止期間全体で 1 つのサンプルを実行するようにオーディオ バッファ フォーマットを変更すれば可能かもしれませんが、ダウンストリームの低レベル API が不安定なサンプル レート設定を評価する可能性は低いです)。
CMSampleBufferCreateCopyWithNewTiming() を使用して、オーディオの動作と一致するように、ビデオの表示タイミングを変更します。これは不安定であり、機能しませんでした。オーディオとビデオの両方のタイムスタンプを調整するなど、これを数回繰り返しました。おそらく私は間違いを犯したのでしょうが、ドキュメンテーションがほとんどないため、このアプローチについても盲目的に飛んでいます。
複数の startSessionAtSourceTime / endSessionAtSourceTime を使用して、一時停止状態でのスタンプルの書き込みを抑制しますが、それは機能しませんでした。実際、Apple のヘッダー ファイル内のメモは、これがサポートされていないことを警告しています (オンライン ドキュメントとは対照的に): : 複数のサンプル書き込みセッションは現在サポートされていません。endSessionAtSourceTime: を呼び出した後、2 回目に startSessionAtSourceTime: を呼び出すとエラーになります。
そこで私の次のアプローチは、複数の AVAsset を作成することです。「一時停止開始」が発生したら、録音を終了し、「一時停止」が発生したら、まったく新しい録音を開始します。すべてが完了したら、AVAssetComposition を使用してすべてを再びつなぎ合わせます。新しい AV キャプチャをセットアップするときに、急速な AV キャプチャがさまざまな場所で不可解な障害で停止および開始することを発見したため、このアプローチについて少し神経質になっています。新しい AV キャプチャを開始する前に、「一時停止解除」を強制的にしばらく待機させる必要がある場合があります。
問題は...もっと良い方法はありますか?