IOS 5: получение выборочных буферов из файла в цикле - PullRequest
0 голосов
/ 21 января 2012

После многих часов чтения документации, предоставленной Apple, я все еще растерялся. Скажем, я могу найти способ периодического доступа к буферам семплов через семейство AVCaptureDevice. Но не ясно, как я могу сделать то же самое с семейством AVAssetReader. Скажем, я хочу получать периодически буферы аудиосэмплов, в то время как их источником является файл MP3. Как это могло быть сделано?

1 Ответ

1 голос
/ 21 января 2012

Чтобы декодировать любой аудиофайл, поддерживаемый Apple:

NSString *songName = @"song.mp3";
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];

NSURL *path = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@", resourcePath, songName]];

AVURLAsset *song = [AVURLAsset URLAssetWithURL:path options:nil];

AVAssetReader *reader = [AVAssetReader assetReaderWithAsset:song error:nil];

NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
    [NSNumber numberWithFloat:48000.0], AVSampleRateKey,
    [NSNumber numberWithInt:16], AVLinearPCMBitDepthKey,
    [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
    [NSNumber numberWithBool:NO], AVLinearPCMIsFloatKey,
    [NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey,
    nil];

AVAssetReaderTrackOutput *output = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:[[song tracks] objectAtIndex:0] outputSettings:outputSettings];

[reader addOutput:output];

bool reading = [reader startReading];

CMSampleBufferRef sampleBuffer = [output copyNextSampleBuffer];

while (sampleBuffer != nil) {
    NSLog(@"Received PCM buffer with [TIMESTAMP:%.1fms]", CMTimeGetSeconds(CMSampleBufferGetOutputPresentationTimeStamp(sampleBuffer)) * 1000);
    NSLog(@"Buffer contains [SAMPLES:%ld]", CMSampleBufferGetNumSamples(sampleBuffer));
    NSLog(@"Buffer contains [DURATION:%.1fms] worth of audio", CMTimeGetSeconds(CMSampleBufferGetDuration(sampleBuffer)) * 1000);
    sampleBuffer = [output copyNextSampleBuffer];
}
...