AVAssetReaderOutput在设备上编码视频带有音频时卡住了。

9
在实现了这个问题中有关编码视频(包括音频)的解决方案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提到了使用AudioQueues时copyNextSampleBuffer函数会出现挂起的情况,并建议在单个线程上进行操作。我已经尝试将所有内容保留在单独的线程或主线程上,但没有成功。
是否有其他人遇到过这种情况并有可能的解决方案? 编辑:看起来从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产生影响。


你有没有找到这个问题的解决方案?我也遇到了同样的问题。我一直在反向工程RosyWriter来录制自己的视频,但当我尝试稍后对它们进行编码/导出时,它们“有时”会失败。这非常不一致。 - Sti
似乎是AVFoundation编码音轨的方式出了问题。在iOS8中已经修复。我会添加一个答案。 - jlw
这个问题最近有什么新的进展吗? - pearl7721
4个回答

4

我在iOS 9.3.2上仍然遇到了这个问题,解决方法是确保在调用 -[AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks] 时,AVAssetReaderAudioMixOutput* 最初应该以选项形式设置,而不是使用nil

例如:

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]的调用出现挂起的情况。

0

使用类似以下代码检查音频轨道的时间范围:

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

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


谢谢您的建议,但我有一些非空时间范围的视频仍然无法正常工作。 - jlw
你检查了视频文件中的每个单独轨道吗? - John Lemberger
是的。视频文件中只有一个视频轨道和一个音频轨道,它们都具有非空时间范围。 - jlw

-1
这是一个与硬件有关的问题。我在模拟器、iPhone5和iPhone6上进行了测试。问题只会在某些视频文件中出现,但仅会在iPhone 5上出现。我无法确定iPhone 5S是否也会有此问题。iOS8无法解决此问题。解决方法可能是限制iPhone 5用户使用某些功能。另一个解决方法是让用户从相机胶卷中选择视频,从而强制Apple对其进行特殊压缩,并将该视频转换为iPhone 5硬件可处理的格式。

2
几年后,在各种设备上发生。 - xaphod

-1

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


这是个好消息,iOS8已经修复了这个问题,但对于那些想要支持早期iOS版本的人来说,它仍然是个问题 :( 我的文件中也是音频作为第一流,视频作为第二流。你发现这与错误有任何关联吗? - Sti
不确定是否与错误有关,但在iOS8中正确记录的视频现在具有视频流优先,音频流次之。 - jlw
有人找到解决这个问题的方法了吗?在设置AssetWriter时,也许有一种改变流顺序的方式吗?我真的很想能够重新处理之前录制的视频 - 在iOS 7中也是如此。 - Frank Rupprecht
我在我的iPhone 5上的iOS8上测试了这个,但它不起作用。模拟器上运行良好(但在iPhone 5上不行)。也许它在iPhone 6上能够工作? - etayluz
1
我也偶尔在iOS 9.3.3上看到copyNextBuffer卡住。对我来说,这是在AVAssetReaderAudioMixOutput中间歇性发生的,该输出具有5个音频轨道,所有轨道都具有非空时间范围。还有其他人仍然遇到这个问题吗? - Greg
3
在iOS 13新硬件上仍存在问题。 - xaphod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接