APIでストリーミングしているIPカメラからオーディオを再生しようとしていますhttp://...<ip-camera..>/audio.cgi
現在、MJPEGクライアントを適応させてストリームオーディオを再生し、オーディオブロックを取得して、NSMutableArray
連続するサウンドパッケージのバッファ()に配置しています。ここにデータを受け取るいくつかのコードがあります:
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"Data recv.");
NSLog(@"Data lenght:%i",[data length]);
if ([data length]>AUDIO_STREAM_HEADER_SIZE){
[recvData appendData:data]; //audio stream data - always 1024 bytes
NSLog(@"Data Append lenght:%i",[recvData length]);
}
else {
[_encabezado appendData:data]; //audio stream header - always 44 bytes
NSLog(@"Crea encabezado:%@",_encabezado);
NSLog(@"Largo encabezado:%i",[_encabezado length]);
}
if ([recvData length] >= PACKET_SIZE_BUFFER_SONIDO) //PACKET_SIZE_BUFFER_SONIDO = 81920
{
NSMutableData *soundData = [[NSMutableData alloc] initWithCapacity:([recvData length])];
NSMutableData *soundCut = [[NSMutableData alloc] initWithData:recvData];
[soundData appendData:_encabezado]; //audio stream header
[soundData appendData:soundCut]; //audio stream data
[_arrSonidos addObject:soundData];
if ([_arrSonidos count]>(BUFFER_SIZE_FOR_PLAY-1)) {
if (playerBuffer.isPlaying) {
[playerBuffer AgregaDataSound:soundData]; //addDataSound in Buffer
} else {
playerBuffer = [[SoundDataPLayer alloc]initWithFileNameQueue:_arrSonidos];
}
}
[recvData setLength:0];
[soundData release];
}
}
関数が呼び出される(関数が表示される)たびに、データフィールドのヘッダーは(44バイト)を取得し、その後、呼び出しごとに1回データバイト(1024バイト)のビットを取得します。私がしていることは、ヘッドがデータをNSData
受信し、定義されたパケットサイズまでデータを受信し、パッケージをそれぞれのヘッダーデータとともにバッファーに保持することです。そのため、バッファにパッケージを追加することを繰り返しました。
一方、私は上記のコードによって呼び出される「playerBuffer」(Web上の例に触発された)を作成し、バッファーの制御とバッファーのすべてのパケットの再生も担当します。このオブジェクトは:に基づいていAVAudioPlayer
ます
SoundDataPLayer.h
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
@interface SoundDataPLayer : NSObject <AVAudioPlayerDelegate> {
AVAudioPlayer* myplayer;
NSMutableArray* dataSound;
int index;
}
@property (nonatomic, retain) AVAudioPlayer* myplayer;
@property (nonatomic, retain) NSMutableArray* dataSound;
- (id)initWithFileNameQueue:(NSArray*)datas;
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;
- (void)playX:(int)i;
- (void)stop;
- (BOOL)isPlaying;
- (void)AgregaDataSound:(NSData *)data;
@end
SoundDataPLayer.m
#import "SoundDataPLayer.h"
#import "ExtAudioFileConvertUtil.h"
@implementation SoundDataPLayer
@synthesize myplayer;
@synthesize dataSound;
- (id)initWithFileNameQueue:(NSArray*)datas {
if ((self = [super init])) {
self.dataSound = [[NSMutableArray alloc]initWithArray:datas];
index = 0;
[self playX:index];
}
return self;
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
if (index < dataSound.count) {
[self playX:index];
} else {
//reached end of queue
}
}
- (void)playX:(int)i {
self.myplayer = [[AVAudioPlayer alloc] initWithData:[dataSound objectAtIndex:i] error:nil];
myplayer.delegate = self;
[myplayer prepareToPlay];
[myplayer play];
index++;
}
- (void)stop {
if (self.myplayer.playing) [myplayer stop];
}
- (BOOL)isPlaying{
return self.myplayer.playing;
}
- (void)AgregaDataSound:(NSData *)data {
[dataSound addObject:data]; //Add Sound Data to the buffer
}
@end
これは、オーディオをループ再生する作業ですが、ループごとに、バッファAVAudioPlayer
の新しいパケット()を再生するために戻るとNSData
、各パケット間に迷惑なグリッチが聞こえます。
グリッチを含むデータがあるかどうかを確認するために、サウンドパックバッファをデータファイルに記録してみましSystemSound
たが、明らかにグリッチがデータの最後にあるという事実があります。
フォーラムで何が起こっているのかを説明しているように見える記事を見つけました。ここでは、x-wavオーディオとPCMコーデックであるため、私の場合は完全には説明されていないようです。NSData
パケットからオーディオを解凍する方法はわかりませんが。
IPカメラからのストリーミングオーディオの追加情報:
datos del audio en elヘッダー:
"Cache-Control"="キャッシュなし"; "Content-Type" = "audio / x-wav"; 日付="2010年1月5日火曜日01:17:04"; プラグマ="キャッシュなし"; サーバー="GoAhead-Webs";
Datos adicionales del audioコーデック:PCMサンプルレート:16 kHz
誰かがこの問題を解決する方法を教えてくれたら幸いです...私は何時間もそれを解決しようとしています...私を夢中にさせています!!
事前に感謝し、私の悪い英語をお詫びします。