文档章节

那些年,追逐过的小视频

w
 wesk痕
发布于 2017/01/17 23:49
字数 1055
阅读 171
收藏 0

最近公司快不行了,又有空闲的时间了😳,对之前做的一些功能做一些总结,微信小视频,曾经热火朝天的功能,许多社交类app都想着模仿。下面就来解析下小视频功能特点。 1.小视频没有声音 2.小视频在cell中无限循环播放 3.性能要求,滑动需要顺畅(线程设计)。

最早接触iOS,我只知道播放视频通常有两种方式,一种是 AVPlayer,另一种是MPMoviePlayerController 。现在 ios9之后苹果已推荐播放视频使用 AVPlayer。

下面介绍下简单的说下 AVPlayer 视频播放器使用时的相关知识,具体的参见官方文档

//创建一个AVPlayer播放类
@property(nonatomic,strong) AVPlayer *player;

//AVPlayerItem(多媒体资源)
@property(nonatomic,strong) AVPlayerItem *playerItem;

//AVAsset(音视频当中单个资源,例如声道,影片)
@property (nonatomic, strong) AVAsset

AVPlayer功能很强大,音视频都可以播放,但像小视频功能我们只需要他的视频功能, 音频功能不需要,如果小视频功能用AVPlayer来实现,系统开销可能就有点浪费了,因为AVPlayer实现了Video+Audio ,而且AVPlayer的音频对AudioSession也有影响,如果app其他地方有使用到声音的,需要注意它的使用了。

后来追求性能,发现了AVAssetReader类 AVAssetReader用于从AVAsset资源中读取媒体样本,可以读取出视频和音频

//从媒体中得到声音轨道   AVMediaTypeVideo 视频
 AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeAudio] firstObject];

AVAssetReaderOutput输出资源并通过copyNextSampleBuffer方法将我们需要的数据给弄一份出来。注意读取的过程是分帧(音频是分块)读取,并不是一次性将将所有数据读取去完毕。结束时,AVAssetReader的status属性 会变成AVAssetReaderStatusCompleted,通过此属性来判断是否读取完毕。

//从媒体中得到视频轨道   AVMediaTypeAudio 音频
    AVAssetTrack *track = [[self.asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
 
 //读取配置
NSDictionary *setting = @{
                              (id)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_32BGRA),
                              (id)kCVPixelBufferWidthKey:@(self.size.width),
                              (id)kCVPixelBufferHeightKey:@(self.size.height),
                              };

//读取输出,在相应的轨道和输出对应格式的数据
    self.assetReaderOutput = [[AVAssetReaderTrackOutput alloc] initWithTrack:track outputSettings:setting];
//赋给读取并开启读取
    if ([self.assetReader canAddOutput:self.assetReaderOutput]) {
        [self.assetReader addOutput:self.assetReaderOutput];
    }
    [self.assetReader startReading];//开始读取

小视频功能可以通过AVPlayer和AVAssetReader 两种途径实现, 我写了个简单的demo,但里面还是有很多学问的。下面简述下demo中的3中实现方式:

实现方式1:用过AVPlayer的 可能都遇到过这么一个现象:黑屏。黑屏的原因是app最多支持16个AVPlayerLayer同时存在,等到17个的时候就会出现黑屏,解决这个问题需要及时释放AVPlayer相关资源。 如果一屏需要展示的播放个数大于16,那么AVPlayer就不适合用来实现小视频,当然实际过程中1屏幕就最多6,7个人视频同时播放了。

实现方式2:利用AVAssetReader 中的获取到的CGImageRef 将每一帧都放到layer.contents中展示

    self.videoImageView.layer.contents = (__bridge id)(imageRef);

实现方式3:实际开发中 gif图 你可以是服务器下载下来的,也可以是通过AVAssetReader 获取到所需要的UIImages,制作成gif,然后保存展示。

以上3中方式,1的性能较差。2,3各有优点。

这3种方式都有一个最大的特点,cell滑动过程中不做视频的加载,这样做为了滑动更流畅,结束的时候再加载当前屏幕中的cell视频。对于gif和customPlayerLayer如果想要修改成滑动时播放,需要修改timer的runloop的model。

//cell 不在可视区域内 可以暂停播放 释放资源
- (BOOL)currentCellIsNotShowedInScreen
{
    UITableView *table;
    for (UIView* next = [self superview]; next; next = next.superview) {
        UIResponder* nextResponder = [next nextResponder];
        if ([nextResponder isKindOfClass:[UITableView class]]) {
            table = (UITableView *)nextResponder;
            break;
        }
    }
    if (table) {
        CGRect cellR = [table rectForRowAtIndexPath:self.currentIndexPath];
        if ((table.contentOffset.y + table.frame.size.height) < CGRectGetMinY(cellR) || table.contentOffset.y > CGRectGetMaxY(cellR)) {
            return true;
        }
    }
    return false;
}

demo 总结:demo中cell元素比较简单,但也能比较不同方式的性能差异,视频播放其实并不难实现,主要是注意性能,利用线程的特性,处理好视频播放。视频播放肯定还有其他实现方式。

© 著作权归作者所有

上一篇: iOS 中的反射
w
粉丝 2
博文 17
码字总数 14343
作品 0
杭州
程序员
私信 提问
一文带你学会使用YOLO及Opencv完成图像及视频流目标检测(下)|附源码

在上一节内容中,介绍了如何将YOLO应用于图像目标检测中,那么在学会检测单张图像后,我们也可以利用YOLO算法实现视频流中的目标检测。 将YOLO应用于视频流对象检测 首先打开文件并插入以下代...

【方向】
2018/11/21
0
0
一直在追逐

我一直在追逐,追逐梦想,追逐爱情,追逐家庭,追逐房子,追逐车子,追逐金钱,现在我感觉我在追逐时间,但到目前为止依然是一无所有!首先我相信这些我都会有,然而我却不清楚如果我真的拥有...

v289
2016/07/31
0
0
我是如何甘于平庸的

我常常会想,我是不是骨子里就是一个懒惰、平庸的人,就这样日复一日年复一年的终老,生活里是买不完的地摊货和逛不完的菜市场。 生活的尽头,一眼即达,毫无悬念。 可我曾经也是那样一个追逐...

乔兰伊雪
2017/08/21
0
0
嘻哈-小青龙 vs 辉子《Time》好好听

Time 视频地址 副歌好好听----- 当我没日没夜工作从长水起飞 时间反复催促让我忘了疲惫 那心酸的滋味我只能独自体会 想要回到过去但是时光不能倒退 校门口美味的路边摊还在不在 包里塞的小吃...

水球喵
2017/08/05
0
0
AI的下一步是理解视频

对于 AI 的发展来说,理解视频中的动态行为是接下来的关键发展方向,这对于 AI 用其软件理解世界至关重要,也有助于 AI 在医疗、娱乐和教育等领域的广泛应用。解释视频的 AI 系统,包括自动驾...

solidot
2017/12/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS7.6中安装使用fcitx框架

内容目录 一、为什么要使用fcitx?二、安装fcitx框架三、安装搜狗输入法 一、为什么要使用fcitx? Gnome3桌面自带的输入法框架为ibus,而在使用ibus时会时不时出现卡顿无法输入的现象。 搜狗和...

技术训练营
昨天
5
0
《Designing.Data-Intensive.Applications》笔记 四

第九章 一致性与共识 分布式系统最重要的的抽象之一是共识(consensus):让所有的节点对某件事达成一致。 最终一致性(eventual consistency)只提供较弱的保证,需要探索更高的一致性保证(stro...

丰田破产标志
昨天
8
0
docker 使用mysql

1, 进入容器 比如 myslq1 里面进行操作 docker exec -it mysql1 /bin/bash 2. 退出 容器 交互: exit 3. mysql 启动在容器里面,并且 可以本地连接mysql docker run --name mysql1 --env MY...

之渊
昨天
10
0
python数据结构

1、字符串及其方法(案例来自Python-100-Days) def main(): str1 = 'hello, world!' # 通过len函数计算字符串的长度 print(len(str1)) # 13 # 获得字符串首字母大写的...

huijue
昨天
6
0
PHP+Ajax微信手机端九宫格抽奖实例

PHP+Ajax结合lottery.js制作的一款微信手机端九宫格抽奖实例,抽奖完成后有收货地址添加表单出现。支持可以设置中奖概率等。 奖品列表 <div class="lottery_list clearfix" id="lottery"> ......

ymkjs1990
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部