2012-01-16 204 views
2

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

的方法[玩家游戏]的返回值是假的,所以没有播放声音,但为什么

感谢。

创建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]; 
+0

你不会一直在给视频帧的OpenGL你会吗?因为我试图做非常类似的事情,如果是的话,并想知道你是如何继续这样做的。 – 2017-04-05 12:24:38

回答

2

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

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

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

+0

谢谢。我将尝试使用AVComposition – ichoyb 2012-01-16 11:01:46

+0

此解决方案可以工作! thx – ichoyb 2012-01-17 05:32:51

+0

@ichoyb你能分享最终解决方案吗?我已经堆放在同样的事物中。谢谢 – fyasar 2012-07-25 12:39:44

0

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