在一切皆可视频化的今天,短视频内容作为移动端产品新的促活点,受到了越来越多的重视与投入。盒马在秒播、卡顿率、播放成功率等基础优化之外,在用户使用体验上引入了无痕续播能力,提升用户观看视频内容的延续性。本篇将分享盒马在 iOS 短视频方面的实践干货。

作者|神捕

审校|泰一

跨页面续播是除秒播外另一个可以从体感上增加用户体验的能力。由于一些业务场景需要在不同页面上播放同一个视频内容的场景,而这些场景页面切换往往是连续的,这就要求短视频的播放也是连续。这样才能使得体验上会有连贯性,让用户在进入沉浸式页面时,能流畅的过度,且无感知的继续播放,从而产生连续不间断的感受。下面我们开始介绍盒马短视频的跨页面续播能力和流畅的动画切换效果的流畅性。

https://v.youku.com/v_show/id_XNTgwNTk4NzQ4MA==.html

如上视频所示,视频在列表页预览观看后,用户很可能继续点击跳到下一个全屏页面,进入沉浸式体验。在这过程中,视频窗口平滑变大至全屏,视频进度是延续的,中间没有感觉到视频或音频的停顿感。在页面返回后,视频窗口也有相应的还原效果。

目标

接入简单,只需要关心并加一个参数,其它逻辑内聚。

适配性好,支持裁剪模式的切换。

视频、音频无缝衔接,不能有任何停顿感。

页面间播放状态隔离,互不干扰。

实现方案

在方案选择上,主要考虑了以下三种:

目前盒马采用的是第 3 种 ——playerView 的复用方式,具体来说,无痕续播的实现,至少需要以下几个步骤:

  1. 用户点击,从 A 页面跳转到 B 页面,如:domain/path?reusedPlayerView=0xyyyyyy, 在原有业务参数的基础上,添加一个 reusedPlayerView 参数,把 playerView 传给下个页面 。
  2. B 页面 HMTBPlayerView 的实例化:内部实例化一个或复用 A 页面的 reusedPlayerView。
  3. playerView 的大小位置换算,实现切换动画。
  4. 从 B 页面返回 A 时,实现退出动画并返还 playerView。

以上步骤不多,但具体实现起来是比较复杂的,下面我们将围绕 4 个主要问题的解决过程,来说明具体实现方式。

尺寸变化的动画

正常来说,只要计算好 playerView 的原始 Rect,以及最终 Rect,基于 UIView 做 frame 动画就可以简单实现窗口变大效果。但实现时发现,手淘播放器内部重写了 setFrame 方法,只要修改了 frame,playerView 将直接显示为终态,动画没有效果。

于是,这里采用了 CGAffineTransform 的 scale 实现:先把 playerView 的 frame 设置为终态,计算好变化前后的尺寸比例 ratio,设置 playerView.transform = CGAffineTransformMakeScale (ratio, ratio),将其尺寸等比缩小为初始位置大小,而后就可以执行 transform 的动画实现从起点到终点的变换。

需要注意的是,此处 ratio 的计算方式,是以 playerView 内真实渲染的视频尺寸计算,而不是 playerView 本身大小。

渲染 mode 的切换

视频渲染本身可以设置为 ScaleAspectFit 或 ScaleAspectFill,目前在盒马的场景中,存在一种 A 页面的播放器为 fill mode,且 playerView 固定正方形,但跳转到 B 页面时,变成 fit mode,这样就出现了一个在尺寸变化动画进行时的 mode 切换的问题。

上述通过 setFrame 并修改 transform 的方式,可以实现把 playerView 大小变换成与动画前的初始大小一致,但是,如果此时存在 mode 切换需求就有可能出现计算后的大小不一致,比如从一个 9:16 长方形的 playerview 变成一个 1 : 1 且 mode 为 fill 的正方形 playerView,此时宽度一致,但高度明显多出了,直接做动画会导致初始状态闪动。

这里的解决方式,我们使用了 maskView 进行 mode 切换过渡:首先,计算 maskView 分别在宽高上的 scale,然后设置 playerView.maskView.transform。计算方式如下:

CGAffineTransformMakeScale(originalRect.size.width/(destRect.size.width*ratio), originalRect.size.height/(destRect.size.height*ratio))

这样就实现利用 maskView,把 9:16 的长方形显示成 1:1 的可见区域,实现动画的起始位置重合。最后,结合上述 playerView.transform 动画,再添加一个 maskView.transform 动画,二者配合,模拟出带 mode 切换场景下的动画过渡效果。

主动回收与主动归还策略

在实现了进场动画之后,最重要的是需要考虑 playerView 复用逻辑,其中比较重要的一点就是 playerView 什么时候归还给 A 页面。

目前我们采用的是租借思路:

  1. 有可借 playerView 时,进行借用;
  2. 复用的 playerview 不再使用时,及时主动归还;
  3. 当出租方自己要使用时,发现租方还未返还,此时进行主动回收。

具体场景来说:进场时,判断有 reusePlayerView,则进行复用;当沉浸式视频(B 页面,类似抖音)翻到下一个视频时,上一个视频进行主动归还操作,如果用户又划回到第 1 个视频,此时是 new 的 playerView 了;另外,当用户点击页面关闭时,主动归还(如果还未还的话);特别要注意的是,这里还增加了一个主动回收机制,场景比如用户通过一些我们未知的方式,回到了页面 A,此时 reusePlayerView 是没有主动归还的,但页面 A 自己又需要 play,此时就触发了主动回收机制,保证当前页面可用。

有一点需要提一下的是,在页面返回时也有动画,实现方面与上述类似,唯一区别是,返回时页面可能 dealloc 了,动画会有问题,所以我们做法是先把 playerView 从 B 页面,添加到 window, 做好缩放动画,结束后,再主动归还给页面 A。

状态隔离

在使用播放器复用时,需要考虑一个重要的问题,就是复用后,播放器状态、设置的隔离。比如,在页面 A 进入页面 B 后,播放器无痕续播,但播放器的状态对 A 来说是暂停,对于 B 来说必须是播放状态,虽然二者使用的是同一个 playerView。

这种隔离是很有必要的,比如业务想要引导用户进入页面 A 的业务,在这里观看视频可以得积分,那么在他进入页面 B 时,就不应该继续结算积分(业务依赖了播放状态通知)。还有,A 与 B 页面的播放设置可能不同,A 可能是静音,B 是有声音,设置不同,也需要隔离。我们是这样做的,如下图(视图层级):

图中,最外层的 view 是盒马自己封装的播放器 HMTBPlayerView,内部有一个手淘的 TBMPBPlayerView,大小一样。我们拿来做复用的其实是 TBMPBPlayerView 这一层,而把业务层的所有设置放在 HMTBPlayerView,这样的话,在 TBMPBPlayerView 被移走时,重新根据新的 HMTBPlayerView 设置它,做好关联,而旧的 HMTBPlayerView 设置不受影响,包括播放器回调。

总结

综上,我们实现了一种播放器复用方式,在播放器内部实现了窗口切换、状态隔离等逻辑,对 App 使用方来说是几乎无感的。该方案不仅可用在无痕续播场景上,今后也可以用在 App 内全局播放器实例复用优化方向。

「视频云技术」你最值得关注的音视频技术公众号,每周推送来自阿里云一线的实践技术文章,在这里与音视频领域一流工程师交流切磋。公众号后台回复【技术】可加入阿里云视频云产品技术交流群,和业内大咖一起探讨音视频技术,获取更多行业最新信息。

如何实现 iOS 短视频跨页面的无痕续播?的更多相关文章

  1. 如何实现 Android 短视频跨页面的流畅续播?

    在一切皆可视频化的今天,短视频内容作为移动端产品新的促活点,受到了越来越多的重视与投入,同时短视频也是增加用户粘性.增加用户停留时长的一把利器.那么如何快速实现移动端短视频功能呢?前两篇我们介绍了盒马 ...

  2. 从350ms到80ms,揭秘阿里工程师 iOS 短视频优化方案

    内容作为 App 产品新的促活点,受到了越来越多的重视与投入,短视频则是增加用户粘性.增加用户停留时长的一把利器.短视频的内容与体验直接关系到用户是否愿意长时停留,盒马也提出全链路内容视频化的规划,以 ...

  3. iOS 短视频开发总结二 AVCaptureSession

    开始录制短视频 录制完成 根据项目需求,对视频URL进行处理 基本原理和方法已经完成,具体细节根据项目实际需求再处理

  4. 揭秘盒马鲜生 Android 短视频秒播优化方案

    短视频作为内容重要的承载方式,是吸引用户的重点,短视频的内容与体验直接关系到用户是否愿意长时停留.因此,体验的优化就显得尤为重要.上一篇我们分享了 iOS 短视频秒播优化,这篇我们来聊聊 Androi ...

  5. 如何快速打造一款高清又极速的短视频APP?

    整个短视频的市场规模一直在增长,网络数据显示2018年已经突破100亿大关,在2019年预测将超过200亿.纵观行业,在生活资讯.美食.搞笑.游戏.美妆等领域,短视频流量巨大但竞争激烈,但是在教育.财 ...

  6. EasyVideoRecorder短视频拍摄、短视频录制SDK支持IOS版本

    在前面的博客<EasyDarwin开发出类似于美拍.秒拍的短视频拍摄SDK:EasyVideoRecorder>和<美拍.秒拍中安卓.IOS短视频拍摄的一些关键技术>中我们简单 ...

  7. 干货|浅谈iOS端短视频SDK技术实现

    短视频SDK主要包含"视频录制"和"视频编辑"这两个核心功能. 视频录制包括:视频采集.美颜.滤镜.摄像头切换.视音频采集参数设置等功能: 视频编辑包括:视频导 ...

  8. 快手、抖音、微视类短视频SDK接入教程,7步就能搞定

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由视频咖 发表于云+社区专栏 终端部分 按照如下三步操作,可以用 XCode 或者 Android Studio 编译和调试小视频 Ap ...

  9. 浅谈短视频APP的发展趋势

    2014年6月20日,在AppAnnie最新发布5月应用指数中,美拍荣登“非游戏类iOS榜单”全球下载量第一位置,成为全球iOS应用商店最热门APP.能在<AppAnnie应用指数>这份A ...

随机推荐

  1. (11)MySQL进阶篇SQL优化(InnoDB锁问题排查与解决)

    1.概述 前面章节之所以介绍那么多锁的知识点和示例,其实最终目的就是为了排查与解决死锁的问题,下面我们把之前学过锁知识重温与补充一遍,然后再通过例子演示下如果排查与解决死锁. 2.前期准备 ●数据库事 ...

  2. 在阿里云上单机部署k8s

    系统:CentOS Linux release 8.1.1911 配置主机名 [root@iZwz9e3t4tj14jzewdtvj8Z ~]# hostnamectl set-hostname la ...

  3. CentOS 永久修改系统时间

    1.查看当前系统时间 date       2.修改当前系统时间 date -s "2018-2-22 19:10:30       3.查看硬件时间 hwclock --show      ...

  4. [源码解析] 机器学习参数服务器 Paracel (1)-----总体架构

    [源码解析] 机器学习参数服务器 Paracel (1)-----总体架构 目录 [源码解析] 机器学习参数服务器 Paracel (1)-----总体架构 0x00 摘要 0x01使用 1.1 配置 ...

  5. springboot自定义ObjectMapper序列化、配置序列化对LocalDateTime的支持

    背景 问题1:项目中使用默认自带的jackson进行前后端交互,实现数据对象的序列化和反序列化,默认的ObjectMapper采用小驼峰的格式,但是调用其他业务的http接口时,ObjectMappe ...

  6. 超详细Java基础-多态

    茫茫人海千千万万,感谢这一秒你看到这里.希望我的能对你的有所帮助!共勉! 愿你在未来的日子,保持热爱,奔赴山海! Java基础知识(多态) 多态 多态就是指程序中定义的引用变量所指向的具体类型和通过该 ...

  7. 《手把手教你》系列技巧篇(十六)-java+ selenium自动化测试-元素定位大法之By xpath下卷(详细教程)

    1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍定位倒数二个方法:By xpath.xpath 的定位方法, 非常强大.  使用这种方法几乎可以定位到页面上的任意元素. ...

  8. Vue-axios 封装了一手好axios:)

    请求方式 很多种请求方式,重点还是第一种吧 下载 npm install axios --save 下载完成 直接导入 import axios from 'axios' 简单配置 axios({ u ...

  9. git submodule 操作

    git submodule foreach git status 举一反三,对所有子库的操作,都可以使用 git submodule foreach 做前缀 foreach,可以记忆为for each ...

  10. 【Mongodb】数据库备份与还原

    Mongodb 备份与还原 Mongodb 备份与还原 文件快照 快照备份 快照直接还原 从压缩文件还原 复制文件 备份文件 从文件还原 mongodump mongodump备份 mongodump ...