Android短视频SDK转场特效的音视频同步分析

在短视频的应用场景中,经常存在用户拍摄的两个或者多个视频生成一个视频的需求,为了达到两个视频平滑过渡,就需要在两个视频中间添加转场效果。由于导入视频的帧率、码率等参数都不一致,如何保证在添加完转场效果后音视频同步?
本文主要介绍转场效果的实现及如何保证最终合成视频的音视频同步,同时简单介绍一下转场滤镜。

视频转场涉及基本的视频转码相关,关于转码相关不是此篇文章的重点,可参考Android短视频SDK转码实践

一. 转场功能介绍

市面上的转场基本分为三类:

  1. 片头片尾转场:即只作用在一个视频上。
    此种和普通的时间滤镜添加区别不大,并不复杂,本文不再赘述

  2. 非重叠转场:转场接替作用在第一个视频的最后和第二个视频的开始,两个视频是顺次拼接。
    比如持续1s的blur转场blur滤镜 在第一个视频的最后0.5s开始,直到结束,作用是由清晰变模糊;在第二个视频的开始作用,持续0.5s,作用是由模糊变清晰。效果如下:

    transition_blur

  3. 重叠转场:转场叠加作用在第一个视频的最后和第二个视频的开始,两个视频有一个转场时间的重叠区。
    比如持续1s的 淡入淡出转场淡入淡出滤镜接收两个视频输入源,并且从第一个视频的最后1s开始作用,即在第一个视频的最后1s需要同时启动第二个视频的解码,并将解码后的数据输入到滤镜中,在转场的持续时间内是同时叠加了两个视频数据。效果如下:

    transition_fadesinout

二. 转场方案介绍

转场是在时间上对多个视频做转码和拼接。
我们采取的方案如如下图所示,依次对待拼接文件做解码,输出音频采样和视频像素数据到编码器,经过muxer最终将不同帧率、码率的视频生成统一格式的文件。

transition_flow

上图中AVMediaCapture为demuxer和decoder的封装。
如第一章节的介绍转场同一时间最多作用在两个视频上,因此只需要创建两个AVMediaCapture的实例,第一个视频解码结束后,第三个视频可以使用第一个视频创建的AVMediaCapture,依次类推,避免反复创建造成资源浪费。如下图所示:


AVMediaCapture

而对于AVMediaCapture中的解码器(硬解为例),也不需要反复创建,我们来看官网上关于MediaCodec的生命周期:


MediaCodec_states

如上图所示,当一个文件解码完成以后,通过reset接口使解码器处于Uninitialized状态,当对第二个文件进行解码时,只需要重新configure,start即可。

三. 转场中的音视频pts 计算

3.1 非重叠转场

在两个视频之间添加持续时间 trans_t 的转场滤镜,滤镜在第一个视频 [dur_0 - trans_t / 2.0f] 开始作用,直到第一个视频结束,然后继续在第二个视频的开始作用,持续 [trans_t / 2.0f]
pts 依次是之前视频时长的累加,公式如下:
vTrack_1aTrack_1 开始点的 pts : [0 + dur_0];
vTrack_2aTrack_2 开始点的 pts : [dur_0 + dur_1]
vTrack_naTrack_n 开始点的 pts : [dur_0 + dur_1 + ... + dur_n]

pts_1

3.2 重叠转场

在两个视频之间添加持续时间 trans_t 的转场滤镜,滤镜是同时作用在两个视频上的,因此滤镜在第一个视频的 [dur_0 - 1.0f] 时开始作用,直到第一个视频结束,同时开始第二个视频的解码,并作为滤镜的第二视频输入源。
pts 的计算需要将转场的作用时间裁剪掉,公式如下:
vTrack_1aTrack_1 开始点的 pts: [0 + dur_0 - trans_t];
vTrack_2aTrack_2 开始点的 pts: [dur_0 + dur_1 - 2 * trans_t]
vTrack_naTrack_n 开始点的 pts: [dur_0 + dur_1 + ... + dur_n - n * trans_t]

pts_2

四. 转场中的音视频同步

因为采用的是pull的方式从解码向编码输入数据,因此在添加重叠场景的转场时,在转场的时间段内,同时存在2个音频轨道和2个视频轨道,就需要考虑四个轨道的同步问题

  • 单个视频的音视频解码同步
    重叠场景的转场,若音视频 demuxer 相差很大,比如第一个视频的音频已经 demuxer 结束,但是第一个视频的视频还在继续处理,因为同时开启了第二个视频的 demuxer ,所以会有累加的音视频不同步的情况。
    transition_avsync

如上图所示,在 decoder 之后添加AVSync模块以解决此种情况的不同步问题,AVSync模块采用视频驱动音频的同步模式,即,对音频做缓存,以视频帧驱动音频帧向下传递,threshold 不超过100ms。

  • 两个视频之间的视频解码同步
    重叠场景下,转场滤镜需要同时输入两个视频源,若第一个视频解码速度快,但是第二个视频的解码速度慢,会造成某一帧数据中只有第一个视频,并没有第二个视频,或者滤镜已经持续了0.8s了,第二个视频才有了输入,造成整体的转场效果较差。


    transition_vsync

为了解决此种问题,加入 VTracks_Sync 同步模块, Vtracks_Sync 保证两个视频的 pts 的diff在100ms之内,若 vtrack_0_pts – vtrack_1_pts > 100ms
则对 vtrack_0demuxer 做暂停,反之对 vtrack_1demuxer 做暂停,以达两个视频源的同步

五. 转场滤镜

重叠转场的渐变滤镜,基本方案为
vtrack_0 为滤镜的主视频输入源 sTexture ,以 vtrack_1 为滤镜第二个视频输入源 vTexture1 ,在 shader 中通过修改渐变因子,以达到不同输入源的比重不同。
以最简单的淡入淡出滤镜为例,offset 为渐变因子,例如持续时间为1s的转场,则offset在1s内从0渐变到1,作用到视频帧的单位值计算公式:
[offset_maxvalue / offset_maxcount]
offset_maxvalue为渐变因子的最大值,即1
offset_maxcount为作用帧数,以帧率是20为例,1s的转场,offset_maxcount即为20。

void main()       
{
        vec4 video = texture2D(sTexture, vTextureCoord);
        vec4 screen = texture2D(vTexture1, vTextureCoord);  
        gl_FragColor = mix(video, screen, offset);
}";

mix是对video和screen做线性混淆,即gl_FragColor = video(1- offset) + (screen * offset)

转载请注明:
作者金山视频云,首发简书 Jianshu.com


Android短视频SDK:https://github.com/ksvc/KSYMediaEditorKit_Android
有关音视频的更多精彩内容,请参考https://github.com/ksvc

金山云SDK相关的QQ交流群:

  • 视频云技术交流群:574179720
  • 视频云Android技术交流:620036233
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容