Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >听说你也在开发年终盘点?送你一篇详尽的踩坑实战~

听说你也在开发年终盘点?送你一篇详尽的踩坑实战~

作者头像
用户1097444
发布于 2022-06-29 06:44:36
发布于 2022-06-29 06:44:36
83101
代码可运行
举报
运行总次数:1
代码可运行

年终了,听说你也在开发年终盘点?也许你可以看看这篇腾讯 ABCmouse 圣诞年终盘点活动页的踩坑实战记录。

圣诞节的时候 ABCmouse 为用户精心准备了一份圣诞礼物,你也想看下吗?快来扫下这个神奇的二维码...

好吧,知道你可能不想扫码 '__' ,直接看下图吧(截取了其中一段)

当然了,这篇文章不是介绍整个开发过程(实际上本身开发周期很短,开发才三天,另外两天bugfix和视觉还原,时间非常赶)。这篇文章主要记录我在开发的过程的过程的一些经验总结和遇到的坑。

坑一:视频坑

这次的年终盘点在前面半部分是一个视频,点击播放视频完成(或者跳过)之后正式进入主页。

划重点: 在视觉设计初期我跟视觉反抗过,建议尽量不要在活动页做内联视频播放,有的浏览器会挟持video标签的播放,使用自己的方式实现,特别Android,会有很多兼容性问题,会比较影响用户体验。 事实证明也确实如此,且听我一一道来。 不过视频里的小老鼠真的好卡哇伊...

播放视频时内联播放,这里视频播放只限制在微信和QQ内才能内联播放。其他手机自带浏览器直接会跳过这个视频播放,后面我简单说明下原因。

为了实现视频的内联播放,我们可以借助video标签的playsinline属性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<video 
  webkit-playsinline="true"
  playsinline="true"
></video> 

另外为了能在视频播放的时候在视频上方显示跳过按钮,这里我们需要用到X5内核视频播放的一个属性 x5-video-player-type设置为h5-page之后,这样就可以控制视频在网页内部同层播放,同时也可以在视频上方显示html元素。(具体可以看这里: H5同层播放器接入规范[1])

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<video x5-video-player-type="h5-page"></video>

因为浏览器的自身自动播放策略,视频的自动播放需要用户在当前页面上有用户行为产生,或者设置视频静音属性 muted,才能自动播放。而我们的视频在前 7.23s的时候会有视频音乐的,因此播放时不能设置为静音,所以无法做成自动播放,于是做成了如上图所示, 用户点击时才能开始播放。(另外在Android上是无法自动获取视频的第一帧的,所以这里让视觉取第一帧图片给你吧)。

点击视频,终于要开始视觉设计的超级卡哇伊的视频了。但是这些都是什么鬼。。。

1、在Android设备下出现小窗播放

时间很紧张,这里没处理。(o(╥﹏╥)o)

2、在Android设备下小窗播放完成后出现广告页?

这个可不行。

解决方案:在视频播放完成后马上调用播放并暂停。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (lib.browser.os.android) {
  video.play();
  setTimeout(function(){
    video.pause();
  });
}

其实在X5内核中还可以考虑使用 mtt-playsinline属性来强制使用系统播放器,从而拒绝视频被拦截植入推荐视频。时间不够当时没考虑到上面去。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<video
  mtt-playsinline="true"
></video>
3、百花齐放、百舸争流的 Android 浏览器的视频播放问题

这里图片太多,就不一一放了。亲测出现过:

  • 自动横屏播放
  • 悬浮置顶播放
  • 自动全屏播放
  • ....

有些事,它想做,我也解决不了。。。跟视觉讨论,客户群体主要还是在微信和QQ,所以在手机自带浏览器里摸下小老鼠的屁股后直接跳过视频播放,直奔主题。

坑二:音频坑

视频问题不完美解决后,你以为完了?我之前说过: 视频播放到7.23s的时候需要自动播放背景音乐,此时的小老鼠往上抛,出现 叮叮当叮叮当...的背景音乐,是不是很有节奏感?但是...

1、Android切换背景音乐的时候视频暂停播放

没错就是卡在这里...

需要注意: 在Android设备上视频播放后同时使用audio标签播放音频时会导致视频卡住。

幸亏组里缺什么也不会缺大佬,大佬说:这个问题我遇到过,你用 WebAudio 播放音频就 OK 了。关于 WebAudio 你可以点这里[2],崇拜ing...(IMWeb 前端团队火热招聘中~快来投递简历吧!

解决方案:在Android设备中使用WebAudio播放音频,而在其它设备中使用audio标签进行播放。(疑问解答:为什么不统一用WebAudio?,因为在另外一个需要中出现过播放视频时播放音频在IOS设备中出现过破音,没错就是 破音

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (lib.browser.os.android) {
  this.player = new WebAudioPlayer(this.src);
} else {
  this.player = new AudioPlayer(this.src);
}

ps: 其中 WebAudioPlayerAudioPlayer 是自己封装的一个简单库

2、iOS下音频自动播放失效?

音频的自动播放策略和视频的一样,设置静音或者有用户行为。但是点击播放视频的时候不是已经有了用户行为,为什么还是播放不了? iOS出于安全机制,不允许audio和video自动播放,所以当切换播放音频播放时还是无法自动播放。

解决方案:在点击触发视频播放的时候同时触发音频播放,只是马上暂停。(在这里你可以做下音频预加载)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
this.bgmusic.play();
setTimeout(function() {
  self.bgmusic.pause();
});

写到这里,其实我很困了...

3、切换后台后背景音乐未停止播放

这个其实应该大家都遇到过,这里简单记录下解决方案:监听下 visibilitychange事件,网页被挂起时暂停背景音乐即可。呼起时继续播放。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
document.addEventListener("visibilitychange", function(event) {
    if (document.hidden) { // 网页被挂起
        beforePlayPaused = !self.bgmusic.isPlaying();
        self.bgmusic.pause();
    } else { // 网页被呼起
        if (beforePlayPaused) {
            return;
        }
        self.bgmusic.play();
    }
});

除了坑,那还有一部分就是细节了。

细节一:下雪的效果

毕竟圣诞,毕竟小孩,有一个下雪的效果是不是小孩子更喜欢?

这里的效果很简单,我们可以使用 Canvas 绘制就可以,因为是全屏雪,所以这里可以把 Canvas 的层级放后一点,防止覆盖上面层级的用户操作。

实现思路

可以将雪花和下雪的效果拆分为两个实体类 SnowflakeSnow。其中雪花可以给它一些 透明度大小水平和垂直方向速度 等属性,当然还有它的水平和垂直坐标,然后每帧更新下雪花的位置即可。甚至你可以给它来点风,让它看起来更真实。

下雪的时候以屏幕宽度为维度,设置雪花的数量用来控制雪的密度。如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
_initSnowflakes: function() {
    var level = this.options.level,
        baseNum = LevelEnum.hasOwnProperty(level) ? LevelEnum[level] : LevelEnum.middle,
        snowflakesNum = parseInt(this.windowWidth / baseNum);
    for (var i = 0; i < snowflakesNum; i++) {
        this.snowflakes.push(new Snowflake(this.options));
    }
}

然后绘制到canvas上,最后使用帧动画来改变雪花的位置来实现下雪的效果。

我已经将这部分代码进行了抽离并发布到github上,有兴趣的可以了解下: Canvas下雪效果[3]

性能优化点
  • 使用 requestAnimationFrame 实现帧动画
  • 雪花数量的控制
  • 监听 visibilitychange 事件,在切换后台的时候暂停 Canvas 动画,因为在 Android 设备上切换后台后定时器还是在运行的。

细节二:骚气的进度条

你可能没注意到,在页面的左上角挂了一串彩灯,每进入一个场景,灯就会亮一盏。

好吧,这里我还是用canvas绘制的,但是时间不够,我本来可以做的足够好,而不是目前这么粗糙的效果...

需要注意的是彩灯亮了之后是一个渐变,这里使用了 createRadialGradient 径向渐变来绘制灯光效果。但是 iOS12.3(忘记版本了反正是最新的)这个方法可以执行但是是无效的。还没有时间找找原因,这里简单做了个判断如果是IOS直接使用纯色填充。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (lib.browser.os.android) {
  fillStyle = context.createRadialGradient(locationX, locationY, radius, locationX + radius, locationY + radius, radius);
  fillStyle.addColorStop(0, '#FFF');
  fillStyle.addColorStop(1, '#FFF800');
} else {
  fillStyle = '#FFF800';
}

细节三:滑雪橇的小老鼠和视差的背景 (远景、树木和雪地)

小老鼠使用了简单的 CSS 骨骼动画( 但是我觉得没啥区别,因为没做很精细 ),完整的骨骼动画至少需要将手拆成很细(如上肢、下肢、滑雪棍)、同时利用 CSS 做骨骼动画有个很坑的点,就是层级,自己可以去实现下。最好使用 Canvas 实现。至于视差其实给三个元素不同的速度即可,很简单。篇幅很长了,这里不展开讲。

细节四:渐变的轮播的文字

为了让文字轮播不至于很生硬,如果不加渐变,滚动的时候会出现文字裁剪的效果。 加上渐变后会让整个过程很流畅,但是实际上要实现这个效果并不简单。

你可以试着想一下,雪因为要不遮挡建筑和文字等,所以层级会放的比较低,所以这里的雪对应的canvas层级会比文字的层级要低,如果直接对文字容器两端新增遮罩并设置渐变或者高斯模糊(blur)的话虽然能起到遮罩效果。但是透明度不仅针对文字,对它下面层级的元素也同样有效果(因为这里文字容器需要设置为透明背景)。这样雪经过渐变的时候会出现穿透的效果,影响用户体验。

简单看个效果图(这里我把颜色放的比较深,更容易看见效果):

可以看到雪花被遮罩挡住了,也变得有渐变了。

解决方案:使用 -webkit-mask-image,有兴趣的可以自己去了解下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-webkit-mask-image: linear-gradient(to bottom,
     rgba(255,255,255,0) 0,
     rgba(255,255,255,.6) 6%,
     rgba(255,255,255,1) 25%,
     rgba(255,255,255,1) 75%,
     rgba(255,255,255,.6) 85%,
     rgba(255,255,255,0) 100%);

细节五:steps 逐帧动画

在这次的年终盘点中充斥着很多逐帧动画,使用 animationsteps 函数完成毕竟还是比较有限,我简单写了一个工具方法来完成我这次的效果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var FrameAnimation = function() {
  return this.initialize.apply(this, arguments);
};
FrameAnimation.prototype = {
  initialize: function(frames) {
    this.frames = Array.isArray(frames) ? frames : [];
    this.timer = null;
    this.delayTimer = null;
  },
  /**
   * 执行完成之后的回调
   * @param {Function} finish
   */
  start: function(finish) {
    var self = this,
        frames = this.frames;
    finish = typeof finish === 'function' ? finish : function() {};
    if (!frames.length) {
      finish();
      return;
    }
    var runAnimation = function(frame) {
      var animationFinish = function() {
            if (frames.length === 0) {
                finish();
                return;
            }
            // 可能存在delay
            self.delayTimer = setTimeout(function() {
                self.delayTimer = null;
                runAnimation(frames.shift());
            }, parseInt(frame.delay, 10) || 0);
          };
      // 可能无法控制持续时间
      if (!frame.hasOwnProperty('duration')) {
        frame.animation(function() {
            animationFinish();
        });
      } else {
        var duration = parseInt(frame.duration, 10) || 0
        frame.animation();
        self.timer = setTimeout(function() {
            self.timer = null;
            animationFinish();
        }, duration);
      }
    };
    runAnimation(frames.shift());
  },
  /**
   * 停止动画
   */
  clear: function() {
    this.frames = [];
    if (this.delayTimer) {
        clearTimeout(this.delayTimer);
        this.delayTimer = null;
    }
    if (this.timer) {
        clearTimeout(this.timer);
        this.timer = null;
    }
  }
};
return FrameAnimation;

使用如下: 虽然简单,但是能满足我所有的需求了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
this.enterFrame = new FrameAnimation([
    // 诞我有你
    {
      duration: 500,
      animation: function() {
        self.titleUpElem.addClass("show");
      }
    },
    // 作伴前行
    {
      duration: 600,
      delay: 100,
      animation: function() {
        self.titleDownElem.addClass("show");
      }
    },
    // 老鼠飞入
    {
      duration: 200,
      animation: function() {
        self.mouseElem.addClass("show");
      }
    }
]);

其实其中还有很多细节,特别是对于 CSS 的使用,这里不一一列举,毕竟篇幅很长了,也很晚了。

开发效率

这种场景切换用 Layers 面板最适合了,嘿嘿...

涉及到动画比较多的场景,也可以通过一些现有的动画可视化工具进行参数调优,如:http://jeremyckahn.github.io/stylie/ 等。

当然,如果你只想调整贝塞尔曲线的参数: cubic-bezier.com 也许是一个不错的选择。

性能

因为动画性能的文章太多,这里规整下,不进行深入探讨。

  • 雪碧图(尤其是动画效果特别多的活动页时特别重要)
  • 图片的压缩(你可以通过 https://tinypng.com/ 在线压缩)
  • 视频和音频资源文件的压缩(视频初始为:15M -> 1.5M,音频7.8M -> 851 KB)清晰度压完觉得还是大那就抽帧吧,再不行就缩短时间。
  • 性能优化时间不够?开启实时帧率吧,关注掉帧
  • 使用transform和opacity,减少重排(reflow)和重绘(repaint)
  • 硬件加速尽量不要直接用在初始时,在开始动画的时候再使用,使用完成后及时关掉,类似这样,开始动画的时候追加class,动画完成后移除
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@keyframes abcmouseMove {
  0% {
    transform: translate3d(0vw, 0vw, 0vw) skew(0deg);
  }
  25% {
    /* skew一下,让老鼠有用力的感觉 */
    transform: translate3d(25vw, 0vw, 0vw) skew(-5deg);
  }
  50% {
    transform: translate3d(50vw, 0vw, 0vw) skew(0deg);
  }
  100% {
    transform: translate3d(100vw, 0vw, 0vw) skew(0deg);
  }
}
  • 不要轻易使用will-change,除非实在没办法,使用完成后马上移除掉。
  • 使用js动画requestAnimationFrame也不要忘记了哦~
  • 不行,不想写了,要吐了...

更多CSS性能优化深入了解,可以看下我们结一(结衣)老师的这篇文章 搞定这些疑难杂症,向 CSS 3 动画说 Yes [4]

参考链接
  1. H5同层播放器接入规范 https://user-gold-cdn.xitu.io/2020/1/5/16f75f8933b03580
  2. Web Audio API https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Audio_API
  3. Canvas下雪效果 https://github.com/abcmouse-frontend/snow
  4. 搞定这些疑难杂症,向 CSS 3 动画说 Yes https://imweb.io/topic/5643850eed18cc424277050e

IMWeb 团队隶属腾讯公司,是国内最专业的前端团队之一。

我们专注前端领域多年,负责过 QQ 资料、QQ 注册、QQ 群等亿级业务。目前聚焦于在线教育领域,精心打磨 腾讯课堂、企鹅辅导 及 ABCMouse 三大产品。

扫码关注 腾讯IMWeb前端团队

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯IMWeb前端团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
H5视频自动播放踩坑杂记
最近的一次业务需求中,偶然接到了这么一个需求:“用户首屏可以自动播放一段视频,希望点击再全屏”。
不换
2024/04/30
1.8K0
H5视频自动播放踩坑杂记
网页背景H5视频自动播放---PC端、移动端兼容问题完美解决方案(IOS、安卓、微信端)
PC端相应简单些,浏览器对<video>标签的兼容还是很好的,但是想要在浏览器中当做Banner视频自动播放就必须设置这些属性来更好地实现;
Tz一号
2020/09/10
4.1K0
为了防止狗上沙发,写了一个浏览器实时识别目标功能
网友的家里有一条狗🐶,很喜欢乘人不备睡沙发🛋️,恰好最近刚搬家 + 狗迎来了掉毛期 不想让沙发上很多毛。所以希望能识别到狗,然后播放“gun 下去”的音频📣。
@派大星
2024/03/20
2250
为了防止狗上沙发,写了一个浏览器实时识别目标功能
Vue3开发:视频播放器video.js使用详解
Video.js是一个通用的在网页上嵌入视频播放器的JS库,比原生video标签有更强大的功能、更好的兼容性、更美观等优点。是一个比较流行的视频播放器,它的官网是https://videojs.com/
BennuCTech
2023/08/28
13K0
Vue3开发:视频播放器video.js使用详解
视频H5 video最佳实践
随着 4G 的普遍以及 WiFi 的广泛使用,手机上的网速已经足够稳定和高速,以视频为主的 HTML5 也越来越普遍了,相比帧动画,视频的表现更加丰富,这里介绍一些实践经验。
gnip
2020/10/28
5.1K0
videojs插件使用「建议收藏」
使用整理:使用主要针对于移动端视频播放,考虑的点:视频显示适配手机宽度;适配定义样式;在微信端,安卓、ios视频空间控件不同,定制等会自动被微信视频控件覆盖;播放过程中定制暂停/播放按钮事件等;播放结束后定制重播、下一个视频事件,读秒播放下一个视频
全栈程序员站长
2022/11/01
11.1K0
SkeyeExPlayer(Windows)开发之接口说明
SKEYE_PARAM_MEDIA_DURATION 和 SKEYE_PARAM_MEDIA_POSITION
Openskeye
2023/04/17
3580
腾讯云 Web 超级播放器开发实战
腾讯云 Web 超级播放器 TCPlayer 可实现在手机浏览器和 PC 浏览器上播放音视频流的问题,功能强劲,兼容性好,可以不依赖用户安装 App,就能进行播放。
初九之潜龙勿用
2024/06/20
7590
复杂帧动画之移动端video采坑实现
本文由 IMWeb 首发于 IMWeb 社区网站 imweb.io。点击阅读原文查看 IMWeb 社区更多精彩文章。 在企鹅辅导品牌页中,我们需要实现一个动画如下: 页面滚动到动画区域,播放动画, 对应动画部分如下: 帧动画当前的实现有以下几种方式: GIF 动画 大家比较熟悉的图片格式 lottie(http://airbnb.io/lottie/) Airbnb 开源项目,通过解析 AE 动画为 json 数据,支持跨平台的动画效果解决方案;lottie 在辅导中已经有实际应用,使用过的同学都表示
用户1097444
2022/06/29
2.5K0
复杂帧动画之移动端video采坑实现
videojs播放器插件使用详解
HLS是苹果公司实现的基于 HTTP 的流媒体传输协议,全称 HTTP Live Streaming,可支持流媒体的直播和点播,主要应用在 iOS 系统,为 iOS 设备(如 iPhone、iPad)提供音视频直播和点播方案。
菲宇
2020/04/16
54.4K2
Cordova插件cordova-plugin-media-capture实现短视频的录制上传和播放
1、网上的教程大部分都是虎头蛇尾的不全的。互相抄来抄去真的感觉就没有一个是真正自己去写一写的,不然这里面这么多的坑就没有一个人出来说说的?下面就写写我实现功能过程中的一些问题吧,代码绝对完整并且按照步骤来一定可以成功!
用户6493868
2022/03/05
2.2K0
【Android FFMPEG 开发】OpenSLES 播放音频 ( 创建引擎 | 输出混音设置 | 配置输入输出 | 创建播放器 | 获取播放/队列接口 | 回调函数 | 开始播放 | 激活回调 )
① FFMPEG 初始化 : 参考博客 【Android FFMPEG 开发】FFMPEG 初始化 ( 网络初始化 | 打开音视频 | 查找音视频流 )
韩曙亮
2023/03/27
1.5K0
视频H5Video标签在微信里的坑和技巧(转)
随着 4G 的普遍以及 WiFi 的广泛使用,手机上的网速已经足够稳定和高速,以视频为主的 HTML5 也越来越普遍了,相比帧动画,视频的表现更加丰富,前段时间开发了一个以视频为主的移动端 HTML5,在这里介绍一些实践经验。
山河木马
2019/03/05
2.9K0
视频H5Video标签在微信里的坑和技巧(转)
腾讯云点播 SDK 集成接入之踩坑&填坑记
音视频播放对于现在的互联网应用来说,已经是不可或缺的功能之一。作为一个 App 开发者,开发一个音视频播放功能,说难不难,说简单也不简单,我们常常会面临几个抉择:
开发的猫
2021/12/01
4.1K0
腾讯云点播 SDK 集成接入之踩坑&填坑记
HTML5 Audio & Video - 兼容性总结(一)
监听 ended 事件不准确,可以监听 timeupdate 事件,判断 当前播放进度 currentTime 大于等于 总时长 duration 时,就是播放完成;
用户9253515
2021/12/27
1.7K0
Electron 低延迟视频流播放方案探索
去年最后一篇文章介绍了我们的 Electron 桌面客户端的一些优化措施,这篇文章也跟我们正在开发的 Electron 客户端有一定关系。最近我们正在预研在 Electron 页面中实时播放会议视频流的方案。
_sx_
2020/04/10
7.1K0
Electron 低延迟视频流播放方案探索
Cocos Creator 出新版本啦, 2.1.2 圆形Shader终于可以完美解决了!
自 Cocos Creator 2.1.0 发布以来,经过半年时间更新迭代,版本现已趋于稳定,目前 2.1 的新增用户已经占据主流。因此我们计划减少 2.0 版本的后续维护力度,将分散的精力集中投入到引擎后续的发展中,力争将 Cocos Creator 打造成更加专注、开放、健康的开源平台。
张晓衡
2019/09/25
3.3K0
Cocos Creator 出新版本啦, 2.1.2 圆形Shader终于可以完美解决了!
关于直播卖货系统平台在微信浏览器中音视频播放的问题
Android 上,因为各个软件使用的浏览器渲染引擎不一样,所以直播卖货系统页面播放的效果差异也很大,这里主要以微信为主。微信使用的是腾讯浏览器自带的X5内核。
云豹kj的晨曦
2020/09/17
1.5K0
关于直播卖货系统平台在微信浏览器中音视频播放的问题
从零开始仿写一个抖音App——视频编辑SDK开发(一)
本文首发于微信公众号——世界上有意思的事,搬运转载请注明出处,否则将追究版权责任。交流qq群:859640274
何时夕
2019/11/21
2.1K0
从零开始仿写一个抖音App——视频编辑SDK开发(一)
Vue3.0+Vant3移动端短视频+聊天+直播实战
随着人们生活品质的提高,5G及手机硬件的快速发展,短视频/直播快速的成为了很多人的娱乐方式。
andy2018
2021/02/03
4.9K1
Vue3.0+Vant3移动端短视频+聊天+直播实战
推荐阅读
相关推荐
H5视频自动播放踩坑杂记
更多 >
领券
一站式MCP教程库,解锁AI应用新玩法
涵盖代码开发、场景应用、自动测试全流程,助你从零构建专属AI助手
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验