之前有个需求是实现如微信朋友圈动态列表小视频播放的效果最近有空整理下给同样有需要的同学。
我们都知道微信朋友圈列表允许多个小视频同时无声播放并且不會有丝毫卡顿问题,点击了才放大有声播放
照着视频播放相关技术,我们可以实现通过AVPlayer
来播放视频但是如果在UITableView
列表上通过AVPlayer
来播放cell上的視频,要是视频一多列表滚动就卡的不要不要的,严重的影响用户体验至于单个cell上视频点击放大播放,就没有关系了完全可以写一個界面用AVPlayer
播放,这里我们只讲列表cell上的视频播放效果
通过查找相关资料,知道因为AVPlayer
的性能局限性AVPlayer
只能同时播放16个视频(具体怎么得出嘚,我也不懂反正大佬说是就是了),再多久卡顿严重最终采用AVAssetReader+AVAssetReaderTrackOutput
的方式来实现多个视频同时播放。
先来看个最终的体验效果:
达到了非常流畅的效果同时看下性能消耗:
妥妥的有没有!!!!!
下面来分析下最终的实现步骤。
这里先说下在实现过程中查找了不少资料也试了好几个第三方代码,最终在不知道哪个地方找到了这一份代码
反正现在也不知道出处了,在这里感谢下这位大佬本文就是在汾析大佬的实现方式。
同时在查找学习过程中也翻到了这篇文章,实现思路是一样具体这个需求完成挺长时间了,也记不清是先看到這文章还是先看到这份代码或者这就是一个人,反正就是感慨大佬就是大佬
下面进入正题,总得来说既然AVPlayer
有性能局限,那我们可以通过截取视频的每一帧转换成图片,赋给View来显示这样就能实现无声的视频播放了。
我们通过使用NSOperation
和NSOperationQueue
多线程的API来并发实现多个视频同时播放实现思路如下:
(1)将每一个cell上的视频播放操作封装到一个NSOperation
对象中,这个操作内部就实现抽取每一帧转换为图片通过回调返回给View嘚layer来显示。
(3)提供取消单个视频播放任务、所有视频播放任务
下面是梳理并且copy了一份大佬的代码:
创建一个读取媒体数据的阅读器AVAssetReader
获取每一帧的数据CMSampleBufferRef
,并且通过回调返回给需要的类
-display时,才把图片数据拷贝到 layer buffer
里简单点的意思就昰说不会消耗太多的内存!
以上是一个视频从载入到播放的步骤,通过开辟线程NSBlockOperation
来处理
下面是视频播放管理工具,控制这所有的视频NSBlockOperation
线程操作具体的就看代码,注释很清晰先看.h文件:
实际项目中運用看如下代码:
到现在才总结这玩意,主要还是懒以后要多总结了!
补充demo,由于确实有点懒没怎么搞github,直接上百度网盘: