как воспроизводить звук с помощью AVAssetReader - PullRequest
2 голосов
/ 16 января 2012

Я использую AVAssetReader для получения отдельных кадров из видеофайла. Я хотел бы знать, как я могу воспроизвести аудио из файла Mp4.

возвращаемое значение метода [player play] равно 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 ]

2 голосов
/ 16 января 2012

Один из вариантов - избегать использования AVAudioPlayer и вместо этого использовать декодированные данные PCM, чтобы заполнить AudioQueue для вывода.

Идеальный способ - создать AVComposition из звуковой дорожки AVAsset , созданной из исходного файла mp4. Эта AVComposition (как подкласс AVAsset) может использоваться внутри AVPlayer, который затем будет воспроизводить только звуковую дорожку для вас.

Вы не можете просто записать блоки данных PCM в файл с расширением ".mp3" - это закодированный формат. AVAudioPlayer будет искать определенные закодированные данные в файле, и файл, который вы написали, будет несовместим, поэтому вы получаете возвращаемое значение false. Если вы настроены на запись аудио в файл, используйте AVAssetWriter с соответствующими настройками. Это может быть записано как файл Core Audio для максимальной производительности. Этот шаг также может кодировать аудио в другой формат (скажем, mp3 или AAC), однако это будет сопряжено с большими затратами на производительность, и, скорее всего, оно не подойдет для воспроизведения в реальном времени.

0 голосов
/ 17 октября 2012

Активы не могут быть воспроизведены сразу. Необходимо наблюдать значение статуса, используя наблюдение значения ключа. Обратитесь к образцу AVCam Apple.

...