如何通过 AVAssetReader 播放声音

发布于 2024-12-27 03:33:55 字数 2028 浏览 1 评论 0原文

我正在使用 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];

I am using AVAssetReader to get the individual frames from a video file. I would like to know how I can play the audio from Mp4 file.

the return value of method [player play] is false, so there is no sound to play, but why

thanks.

create 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];

output code is as following:

  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];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

虐人心 2025-01-03 03:33:55

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

理想的方法是创建 AVComposition< /a> 来自 AVAsset 是从源 mp4 创建的文件。该 AVComposition (作为 AVAsset 的子类)可以在 AVPlayer 内使用,然后 AVPlayer 将为您播放音轨。

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

One option would be to avoid using the AVAudioPlayer, and instead use the PCM data you have decoded to fill an AudioQueue for output.

The ideal method would be to create an AVComposition from the audio track of an AVAsset that was created from your source mp4 file. That AVComposition (as a subclass of AVAsset) can be used inside an AVPlayer, which will then play just the audio track for you.

You're not able to simply write out blocks of PCM data into a file with the extension ".mp3" - that's an encoded format. The AVAudioPlayer will be looking for certain encoded data in the file, and the file you have written will be incompatible, which is why you are receiving a return value of false. If you have your heart set on writing the audio out to a file, use an AVAssetWriter with the appropriate settings. This could be written out as a Core Audio file for maximum performance. This step could also encode the audio as another format (say, mp3, or AAC), however this will have a heavy performance cost associated with it, and it's likely that it will not be suitable for real-time playback.

久随 2025-01-03 03:33:55

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

The assets is not playable immediately. Need to observe the value of status using key-value observing. Refer to the AVCam sample of Apple.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文