2

iPhone のストリーミング オーディオにシーク (タイムライン機能) を実装するにはどうすればよいですか?

AudioFileStreamSeek メソッドは、シークを開始したいバイト オフセットを受け取ります。再生中の mp3 の現在の位置を取得し、後でユーザーが同じ位置に戻る (シークする) ことができるようにしたいと考えています。

しかし、すでに再生されたバイト数を知る方法が見つかりませんでした。ストリーミングされたバイト数を確認できます。しかし、再生されたバイト数を見つけることができません。Matt Gallagher のオーディオ ストリーミングの例をベースとして使用しています。

どんな助けでも大歓迎です。

ありがとう。

解決策を見つけることができるかもしれません。AudioFileStreamSeekのドキュメントによると

この関数を呼び出した後、パーサーは AudioFileStreamParseBytes 関数に渡される次のデータが、outAbsoluteByteOffset パラメーターで返されたバイト オフセットから始まると想定します。

どうやってそれを行うのですか?Http Range パラメータを使用する必要がありますか? バイト オフセットを Range に送信すると、期待どおりに動作しますか? また、2 つのストリームが一緒に再生されないようにするには、バッファ内の既存のバイトをどのようにクリアすればよいでしょうか?

どんな助けでも大歓迎です。ありがとう。

4

3 に答える 3

2

AudioFileStreamSeek は、バイト数ではなくパケットで機能します。したがって、本当に追跡する必要があるのはパケット数です。

Matt のコードの MyEnqueueBuffer メソッドは、バッファが再生のために AudioQueue に送信される場所です。packetfilled を取得し、packetsfilled が 0 にリセットされる前に index 変数をインクリメントします。

myData.absolutePackets = myData.absolutePackets + myData->packetsFilled;

私の問題は、この値でも AudioFileStreamSeek を正しく実装できないことです。したがって、Matt のコードを使用したシークのサンプル コードがある場合は、共有してください。

ありがとう!

于 2009-03-20T15:17:50.507 に答える
1

私はこれのためにAudioFileStreamAPIを実際に試していません(私たちは内部で独自にロールしました)が、ここであなたが世話をしなければならないいくつかのことがあります。

ランダムにバイトストリームを探すのに問題がないと仮定すると、Paulが言うように、MP3フレーム番号と絶対バイトストリームの場所との関係を追跡し続ける必要があります。途中でAudioFileStreamSeekを呼び出すことにより、AudioFileStream_PacketsProcでそれを実行できると思います。

これが難しい部分です。ランダムシークを行う場合は、AudioFileStreamの内部状態をリセットする必要があります。次の着信バイトが現在のフレームを完了することを期待している中間状態にある可能性があるためです。ゼロをフィードして現在のフレームをスキップして最初からやり直すことができるかどうかはわかりません(APIにAudioFileStreamResetのようなものが表示されないため、試してみる必要があります。ただし、オーディオキュー自体は実行します。すでにキューに入れられているフレームをクリーンアップできるリセット機能があります)。いずれにせよ、すでに追跡しているバイトストリームの一部を解析するため、AudioFileStream_PacketsProcにも注意を払う必要があります。

2番目とビットレートに依存してMP3フレームの開始を見つけることはできないことに注意してください。非可変レートのMP3ストリームでも、数フレームおきにパディングが発生する可能性があります。したがって、最も正確な情報は依然としてパーサーから取得されます。

ランダムシークを行う別の方法は、非常に長くて大きなストリームを再生していない場合に、解析されたパケットを単に「キャッシュ」(保存)することです。フレームインデックスは、フレームヘッダー情報から計算できます。非VBRMP3の場合、1秒あたりのフレーム数は一定です(たとえば、44.1kHzステレオ非VBRMP3の場合は44100/1152= 38.28125フレーム/秒です。その理由についてはMP3仕様を確認してください)。

于 2009-03-21T06:52:03.800 に答える
0

探したい場所の mSampletime で AudioQueueStart を使用できますか?

再生を停止して、別のサンプル時間で開始しますか? [現在のサンプル時間を取得し、必要に応じて操作しますか?]

inDeviceStartTime オーディオ キューを開始する時刻。

関連するオーディオ デバイスのタイムラインに相対的な開始時間を指定するには、AudioTimeStamp 構造体の mSampleTime フィールドを使用します。Audio Queue をできるだけ早く開始する必要があることを示すには、NULL を使用します。

戻り値 結果コード。「Audio Queue Result Codes」を参照してください。</p>

関連するオーディオ デバイスがまだ実行されていない場合、この関数はそれを開始します。

于 2009-04-14T20:38:29.013 に答える