我正在开发一个有集合视图的应用程序,集合视图的单元格可以包含视频.现在我正在用AVPlayer
和显示视频AVPlayerLayer
.不幸的是,滚动性能很糟糕.看起来AVPlayer
,AVPlayerItem
和AVPlayerLayer
做了很多工作的主线上.他们不断拿出锁,等待信号量等,这阻碍了主线程并导致严重的帧丢失.
有没有办法告诉AVPlayer
停止在主线程上做这么多事情?到目前为止,我所尝试的一切都没有解决问题.
我也试过使用构建一个简单的视频播放器AVSampleBufferDisplayLayer
.使用它我可以确保一切都发生在主线程之外,我可以在滚动和播放视频时达到~60fps.不幸的是,这种方法的级别要低得多,而且它不提供开箱即用的音频播放和时间擦除等功能.有没有办法获得类似的表现AVPlayer
?我更愿意使用它.
编辑:
在进一步研究之后,看起来在使用时可能无法实现良好的滚动性能AVPlayer
.创建一个AVPlayer
并与一个AVPlayerItem
实例关联开始了一大堆蹦床到主线程的工作,然后它在信号量上等待并尝试获取一堆锁.随着滚动视图中视频数量的增加,停止主线程的时间量会急剧增加.
AVPlayer
dealloc似乎也是一个巨大的问题.Dealloc'ing an AVPlayer
也尝试同步一堆东西.再次,当你创造更多的球员时,这会非常糟糕.
这非常令人沮丧,它AVPlayer
几乎无法用于我正在尝试的事情.阻止像这样的主线程这样做是一件非常业余的事情,很难相信苹果工程师会犯这种错误.无论如何,希望他们能尽快解决这个问题.
我有一个可以显示视频的应用程序,我想要以下行为。
当视频首次出现在屏幕上并开始播放时,它的音频应该与来自其他可能已经在播放的应用程序的音频混合。例如,如果用户正在收听 Spotify,他们应该同时听到来自 Spotify 和正在播放的视频的音频。
如果用户点击特定按钮,则其他应用程序的音频应静音,以便仅播放视频中的音频。
如果用户再次点击按钮,来自其他应用程序的音频应该恢复,并且视频的音频与来自其他应用程序的音频应该再次混合。
本质上,我希望能够在“混合”和“非混合”之间切换我的应用程序的音频模式。
这是一些代码,显示了我如何修改AVAudioSession
以尝试获得此功能。
打开混音模式
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryAmbient
withOptions:AVAudioSessionCategoryOptionMixWithOthers
error:nil];
[session setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
Run Code Online (Sandbox Code Playgroud)
关闭混音模式
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback
withOptions:0
error:nil];
[session setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,在之前关闭混音后打开混音,不会通知其他应用程序可以再次继续播放音频。我真的,真的想要那种行为。这是不可能的事情。
似乎通知其他应用程序可以恢复的唯一方法是将我的应用程序的音频会话设置为“非活动”。不幸的是,在播放视频时执行此操作会导致控制台中打印出警告,提示我应该在停用音频会话之前停止播放音频。这也有基本上破坏 AVPlayer 的效果,因为它不能再播放任何音频。
有谁知道如何解决这些问题?欢迎任何解决方案,即使是非常复杂或使用私有 API 的解决方案。
我想为iOS构建一个流媒体视频播放器,它能够播放.mp4
托管在远程服务器上的文件.我还想使用像AudioToolbox和VideoToolbox中的低级API那样做.我不希望使用AVPlayer
此.我想这样做主要是作为一个学习练习,但也因为我注意到它AVPlayer
和它的相关类阻止了主线程,这使得在滚动视图中嵌入视频非常困难.
据我所知,这将需要4个主要挑战,我必须解决;
从互联网下载MP4文件并提取音频/视频样本
这可能是我对它如何工作最不了解的领域.假设我为MP4文件启动网络下载,并得到结果数据流.
从流中解压缩和播放音频样本
从围绕Apple的文档开始,看起来我可以使用AudioQueue
API.它似乎拥有播放音频数据流所需的一切.将所有内容设置正确以播放压缩音频数据可能并不容易,但似乎可行.
解压缩并显示流中的视频样本
对于解压缩和显示视频样本,到目前为止我已经研究过了AVSampleBufferDisplayLayer
.我已经玩了一下它似乎非常有希望我想做什么.请问AVSampleBufferDisplayLayer
是在这里使用推荐的东西,或者是有别的,更适合呢?
同步音频和视频播放
这是我不太了解的另一个领域.从阅读文档和头文件看起来我需要创建一个CMAudioClock
然后创建一个CMTimeBase
使用该时钟,然后可以用来驱动AVSampleBufferDisplayLayer
.关于此设置有一些我不明白的事情
CMAudioClock
前进的速度有多快?它是否只是以固定费率不断前进?或者每次播放声音时它会前进一点吗?CMAudioClock
带有关联的CMTimeBase
,我需要将它与我的音频管道相关联吗?这两件事如何保持同步?