AppleのHTTPライブストリーミングプロトコルを使用して、iOSおよびSafariクライアントにオーディオをストリーミングしようとしています。HTTPライブストリーミングの多くの一般的な実装とは異なり、私の目標は、長さがさまざまで、ほとんどが10〜30秒の範囲の短いオーディオクリップを使用することです。これらのセグメントからのオーディオのストリーミングに加えて、各セグメントのメタデータにアクセスして、表示を更新したり、特定のオーディオセグメントに関する詳細情報を取得するための追加オプションをユーザーに提供したりしたいと思います。
現在、ソースオーディオ(MP3)をさまざまな形式に変換し、iOSデバイスでテストするストリーミングM3Uファイルを作成するいくつかのテストケースを設定しましたが、どのアプローチも正しく機能しませんでした(正しくストリーミングしてクライアントにメタデータを渡す) 。AVPlayer作成したM3Uファイルをロードして再生するために使用しています。
_playerItem = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:@"http://localhost/sample.m3u8"]]
_player = [[AVPlayer alloc] initWithPlayerItem:_playerItem];
[_playerItem addObserver:self forKeyPath:@"timedMetadata" options:NSKeyValueObservingOptionNew context:NULL];
// ... wait for user input
[_player play];
アプローチ1:生のMP3ファイル
id3v2(v2.3.0)メタデータを含む元のソースMP3ファイルを取得し、それらをM3Uプレイリストに追加しました。
#EXTM3U
#EXT-X-TARGETDURATION:23
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:14
http://localhost/trk_01.mp3
#EXTINF:22
http://localhost/trk_02.mp3
#EXTINF:16
http://localhost/trk_03.mp3
#EXT-X-ENDLIST
結果:timedMetadata最初のトラックの正しいID3情報で再生が開始されるとすぐに、プロパティが更新されます。最初のトラックは再生されますが、終わり近くで途切れます。2番目のトラックのID3データは表示されますが、2番目のトラックは再生を開始しません。しばらくすると、コンソールにエラーが表示されます。
2011-04-26 07:04:52.668 TestClient[49756:601b] Prime: Exiting because mConverterError is '!buf' (0x800 req, 0x0 primed)
2011-04-26 07:04:52.668 TestClient[49756:601b] Prime failed ('!buf'); will stop (2048/0 frames)
アプローチ2:Appleのmediafilesegmenterを使用して個々のMP3ファイルを作成する
このアプローチではmediafilesegmenter、セグメントごとに新しいMP3ファイルを作成するために使用します。Appleのセグメンテーションツールは通常、セグメンテーションに使用されますが、私のオーディオクリップはすべて短く、さまざまな長さであるため、これは私のアプリケーションにはあまり適していません。999秒のターゲット期間をユーティリティに渡して、指定した入力ファイルごとに1つの出力ファイルを作成します。個々のトラックを作成するために使用するコマンドは次のとおりです。
mediafilesegmenter -t 999 -f "$OUTPUT_DIR" "$INPUT_FILE" && cp $OUTPUT_DIR/fileSequence0.mp3 $OUTPUT_FILE
vbindiffがファイルヘッダーの変更を示し、文字列「com.apple.streaming.transportStreamTimestamp」が新しいファイルの最初の数バイトに表示されるため、結果のMP3ファイルにはタイムスタンプデータが含まれているようです。その文字列を調査すると、 HTTPライブストリーミングドラフト仕様に一節が表示されます。
エレメンタリーオーディオストリームファイルは、ID3 PRIVタグ[ID3]に「com.apple.streaming.transportStreamTimestamp」の所有者識別子を付加することにより、ファイル内の最初のサンプルのタイムスタンプを通知する必要があります。バイナリデータは、上位31ビットがゼロに設定されたビッグエンディアンの8オクテット数として表される33ビットのMPEG-2プログラムエレメンタリーストリームタイムスタンプである必要があります。
次に、アプローチ1と同じようにM3Uファイルを作成します(mediafilesegmenterを使用すると、事前に作成されたID3タグファイルとID3タイムオフセットを記述したメタファイルを使用してID3情報を渡すこともできます。これらのファイルを正しく再生することもできます。)
結果:最初のトラックはアプローチ1と同じようにストリーミングされます。トラックは終わり近くで再び切断され、2番目のトラックは再生されません。メタデータは存在しませんが、mediafilesegmenterの-Mオプションを使用して簡単に追加できます。
アプローチ3:ffmpegを使用してMPEGトランスポートストリームファイルを作成する
この最後のアプローチを使用して、ソースMP3ファイルをffmpegに渡し、MPEGトランスポートストリームデータを作成します。
ffmpeg -i "$INPUT_FILE" -f mpegts -acodec copy "$OUTPUT_FILE"
次に、最初の2つのアプローチと同じようにM3Uを作成します。
結果:このアプローチは実際に機能します。すべてのファイルがクライアント上でスムーズにストリーミングされます。ただし、メタデータをクライアントに渡すことができません。-metadata title="My Title"運が悪かったので、ffmpegのような引数を渡してみました。