使用AVAudioPLayer播放音频片段时出现故障



我正在尝试从IP摄像机流播放音频,它是API 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字节),然后每次调用一次数据字节位(1024字节)。我所做的是在NSData中保持头部接收数据,然后接收数据,直到定义的数据包大小,将包与各自的头部数据保持在缓冲区中。所以我迭代添加包到缓冲区。

另一方面,我创建了一个"playerBuffer"(灵感来自网络上的例子),由上面的代码调用,也负责控制缓冲区和播放缓冲区的每个数据包。该对象基于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 header:

"Cache-Control" = "no-cache";"Content-Type" = "audio/x-wav";日期="星期二1月5日01:17:04 2010";Pragma = "no-cache";服务器="GoAhead-Webs";

Datos adicionales del audio Codec: PCM SampleRate: 16 kHz

如果有人能给我指点一下如何解决这个问题,我将不胜感激。我试着解了很多很多个小时……快把我逼疯了!

你听到的"glitch"是你接收"did finish playing"事件,处理它,为下一个数据包初始化AVAudioPlayer,并将数据发送到声卡所花费的时间的组合。

这类似于等待一个CD播放机播放完后才开始下一个—要想做到无故障播放,反应速度是不可能的。

你可能想要使用音频队列服务,你也会想要一些方法来补偿相机和手机之间的音频时钟偏差。

我用AVQueuePlayer解决了我的问题。

希望对大家有所帮助。

相关内容

  • 没有找到相关文章

最新更新