如何通过AVAssetReader播放声音

时间:2012-01-16 10:15:05

标签: ios audio avaudioplayer avassetreader

我正在使用AVAssetReader从视频文件中获取各个帧。我想知道如何播放Mp4文件中的音频。

方法[播放器播放]的返回值为false,因此没有声音播放,但为什么

感谢。

创建AVAssetReader

  NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"zhang" ofType:@"mp4"]];
    AVURLAsset *avasset = [[AVURLAsset alloc] initWithURL:url options:nil];
    AVAssetTrack *track1 = [[avasset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];

NSMutableDictionary *dic2 = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,  [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,
                             [NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey,
                             [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,
                             [NSNumber numberWithBool:NO],AVLinearPCMIsNonInterleaved, nil]; 

output1 = [[AVAssetReaderTrackOutput alloc] initWithTrack:track1 outputSettings:dic2];

AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:avasset error:nil];

[reader addOutput:output1];
[reader startReading];

输出代码如下:

  CMSampleBufferRef sample = [output1 copyNextSampleBuffer];
    CMBlockBufferRef blockBufferRef = CMSampleBufferGetDataBuffer(sample);

    size_t length = CMBlockBufferGetDataLength(blockBufferRef);
    UInt8 buffer[length];
    CMBlockBufferCopyDataBytes(blockBufferRef, 0, length, buffer);

    NSData * data = [[NSData alloc] initWithBytes:buffer length:length];
    NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *filePath = [NSString stringWithFormat:@"%@/test.mp3", docDirPath];
    [data writeToFile:filePath atomically:YES];
    [data release];

    NSError *error;
    NSURL *fileURL = [NSURL fileURLWithPath:filePath];
    AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error];
    player.numberOfLoops = 0;
    [player play];

2 个答案:

答案 0 :(得分:2)

一种选择是避免使用AVAudioPlayer,而是使用已解码的PCM数据填充AudioQueue输出。

理想的方法是从源mp4文件创建的AVComposition的音轨创建AVAsset。 AVComposition(作为AVAsset的子类)可以在AVPlayer中使用,然后AVPlayer将为您播放音频轨道。

您无法简单地将PCM数据块写入扩展名为“.mp3”的文件中 - 这是一种编码格式。 AVAudioPlayer将在文件中查找某些编码数据,并且您编写的文件将不兼容,这就是您收到返回值false的原因。如果您已将心音设置为将音频写入文件,请使用具有适当设置的AVAssetWriter。这可以写成Core Audio文件以获得最佳性能。此步骤还可以将音频编码为另一种格式(例如,mp3或AAC),但是这会产生很大的性能成本,并且很可能不适合实时播放。

答案 1 :(得分:0)

资产不能立即播放。需要使用键值观察来观察状态值。请参阅Apple的AVCam示例。