ios - glitches when playing audio in pieces with AVAudioPLayer -
i'm trying play audio ip camera streaming api http://...<ip-camera..>/audio.cgi
currently obtain play stream audio adapting mjpeg client, taking audio blocks , put them buffer (nsmutablearray
) of consecutive sounds packages. here code receives data:
-(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 - 1024 bytes nslog(@"data append lenght:%i",[recvdata length]); } else { [_encabezado appenddata:data]; //audio stream header - 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]; } }
each time when function called (function show up), header of data field getting (44 bytes) , bits of data bytes (1024 bytes) once per call. keep head receiving data in nsdata
, receiving data until defined packet size, keeping package in buffer respective header data. , iterated adding packages buffer.
and other hand, create "playerbuffer" (inspired examples on web) called above code , responsible controlling buffer , playing every packet of buffer. object based on 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 buffer } @end
that work , play looped audio, on each loop when avaudioplayer
play new packet (nsdata
) of buffer, hear annoying glitches between each packet.
i tried systemsound
and recording sound packs buffer data file see if data containing glitches, apparently fact glitches in end of data.
i found article in forum seems explain happens: here apparently not explain in case because x-wav audio , pcm codec, , think , understand uncompressed. although not know how uncompress audio nsdata
packets.
additional information of streaming audio ip camera:
datos del audio en el header:
"cache-control" = "no-cache"; "content-type" = "audio/x-wav"; date = "tue jan 5 01:17:04 2010"; pragma = "no-cache"; server = "goahead-webs";
datos adicionales del audio codec: pcm samplerate: 16 khz
i appreciate if give me light on how solve problem... try solve many many hours... driving me crazy!!
thanks in advance , sorry bad english.
the "glitch" you're hearing combination of time takes receive "did finish playing" event, process it, initialize avaudioplayer next data packet, , send data sound card.
it's analogus waiting 1 cd player finish playing before starting next — it's impossible react fast enough glitch-free playback.
you want use audio queue services, , you'll want way compensate audio clock skew between camera , phone.
Comments
Post a Comment