2012-01-16 122 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示例。