在设备上编码带有音频的视频时,AVAssetReaderOutput copyNextSampleBuffer会挂起

时间:2013-11-28 18:24:53

标签: ios avfoundation avasset avassetreader

在这个问题Video Encoding using AVAssetWriter - CRASHES中实现了编码视频(带音频)的解决方案之后,我发现代码在iPhone模拟器中正常工作。不幸的是,某些视频在实际的iPhone 5(以及其他设备)上运行时无法对其音频进行编码。

例如,从WWDC 2011示例代码RosyWriter(https://developer.apple.com/library/IOS/samplecode/RosyWriter/Introduction/Intro.html)生成的视频未完全编码,因为函数-[AVAssetReaderOutput copyNextSampleBuffer]永远不会返回。

视频缓冲区正确进入,但只要它尝试复制第一个音频CMSampleBufferRef,呼叫就会挂起。当我对来自其他来源的视频(例如原生iOS相机应用中记录的视频)进行尝试时,音频会正确导入。

这个帖子https://groups.google.com/forum/#!topic/coreaudio-api/F4cqCu99nUI记录了copyNextSampleBuffer函数在与AudioQueues一起使用时挂起,并建议将操作保留在单个线程上。我已经尝试将所有内容保存在主线程的单独线程中,但没有运气。

有没有其他人经历过此并有可能的解决方案?

编辑:看来RosyWriter生成的视频相对于来自原生相机应用的视频,即音频流为流0,视频流为流1,其视频相反。

Stream #0:0(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 60 kb/s
Metadata:
  creation_time   : 2013-10-28 16:13:05
  handler_name    : Core Media Data Handler
Stream #0:1(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1920x1080, 8716 kb/s, 28.99 fps, 29.97 tbr, 600 tbn, 1200 tbc
Metadata:
  rotate          : 90
  creation_time   : 2013-10-28 16:13:05
  handler_name    : Core Media Data Handler

不确定这是否会对AVAssetReader产生影响。

4 个答案:

答案 0 :(得分:3)

我在iOS 9.3.2上仍遇到此问题,解决问题的方法是确保AVAssetReaderAudioMixOutput*在调用nil时最初设置为选项而不是-[AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks]

示例:

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

// create an AVAssetReaderOutput for the audio tracks
NSArray* audioTracks = [asset tracksWithMediaType:AVMediaTypeAudio];
AVAssetReaderAudioMixOutput* _audioReaderOutput = [AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks:audioTracks audioSettings:outputSettings];

这阻止了以后对-[AVAssetReaderOutput copyNextSampleBuffer]的呼叫暂停,否则他们会这样做。

答案 1 :(得分:0)

使用以下内容检查音轨上的时间范围:

NSLog(@"audioTrack timeRange: %lld, %lld", audioTrack.timeRange.start.value, audioTrack.timeRange.duration.value);

空时间范围(0,0)可能导致copyNextSampleBuffer()挂起。

答案 2 :(得分:0)

这是iOS7中的AVFoundation错误。它现在已在iOS8中修复。

答案 3 :(得分:0)

这是一个特定于硬件的问题。我在模拟器,iPhone5和iPhone 6上进行了测试。某些视频文件出现问题100%,但仅限于iPhone 5.但我不能说iPhone 5S。 iOS8无法解决此问题。该修复程序可能必须限制您的iPhone 5用户使用某些功能。另一项工作是让用户从他们的相机胶卷中选择一个视频,从而迫使Apple对其进行特殊压缩 - 并将该视频转换为iPhone 5硬件可以使用的格式。