手机端微信 H5 页面视频居然加载失败?!😣

689 阅读6分钟

背景

最近我负责实现一个 视频背景的 Banner 模块,这个功能本身并不复杂,主要是通过一些 CSS 技巧确保视频作为背景时能够自适应宽度,且保持视频不变形、始终播放。

不过,在实现之后,我发现视频在微信浏览器里无法加载,不仅是安卓设备,连苹果手机的微信中也无法显示!

现状

这个官网用到的技术栈是 Hugo

简单的说一下,Hugo 是由 Go 语言实现的静态网站生成器。简单、易用、高效、易扩展、快速部署。感兴趣的可以去下列相关链接去了解。

  1. Hugo 官网
  2. Hugo github
  3. Hugo 中文文档

有问题版本

<div class="banner">
  <video
    autoplay
    muted
    loop
    class="background-video"
  >
    <source src="/video/intro.mp4" type="video/mp4"></source>
  </video>
  
  <div class="introduction resize-padding">
    <div class="title">xxxxxxxxxxxx</div>
    <div class="desc">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</div>
    <div class="desc">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</div>
    {{ $lang := .Lang }}
    {{ $careerHref := "/career" }}
    {{ if ne $lang "zh" }}
    {{ $careerHref = add "/" (add $lang $careerHref) }}
    {{ end }}
    <a href="{{$careerHref}}" class="join">加入我们 > </a>
  </div>
</div>

video 的一些属性:

  • autoplay 视频在就绪后马上播放。
  • controls 向用户显示控件,比如播放按钮。
  • height 设置视频播放器的高度。
  • loop 当媒介文件完成播放后再次开始播放。
  • muted 规定视频的音频输出应该被静音。
  • poster 规定视频下载时显示的图像,或者在用户点击播放按钮前显示的图像。
  • preload 视频在页面加载时进行加载,并预备播放。如果使用 "autoplay",则忽略该属性。
  • src 要播放的视频的 URL。
  • width 设置视频播放器的宽度。
.banner {
    width: 100%;
    height: 860px;
    overflow: hidden;
    position: relative;
    & > .background-video {
      position: absolute;
      top: 50%;
      left: 50%;
      width: 100%;          /* 视频宽度自适应 */
      height: 100%;         /* 高度覆盖父容器 */
      object-fit: cover;    /* 保持视频比例,多余部分裁剪 */
      transform: translate(-50%, -50%); /* 视频居中 */
      z-index: -1;          /* 确保视频在内容的下方 */
    }
}

效果在微信里边访问就是直接该模块白屏了?!

手机其他浏览器可以正常访问,微信的 PC 浏览器也可以正常访问。第一感想,微信还来这么一手...

复现问题,找到根源,寻找解决办法,经过一番寻找,尝试,终于修复了该问题。

修复后版本

<video
    autoplay
    muted
    loop
    id="video"
    x5-video-player-type="h5"
    x5-video-player-fullscreen
    x5-video-orientation="portraint"
    x-webkit-airplay
    webkit-playsinline
    playsinline
    x5-playsinline
    class="background-video"
    >
    <source src="/video/infinilabs-intro.mp4" type="video/mp4"></source>
</video>

由于 X5 浏览器是微信和 QQ 内嵌的浏览器引擎。所以新增设置了以下几个 腾讯 X5 浏览器 的自定义属性以及一些其他属性。

这些属性的组合是为了确保视频在移动设备,尤其是微信和 QQ 内嵌的 X5 浏览器,以及 iOS 系统的 Safari 浏览器中,能够顺利内嵌播放,避免视频强制全屏或无法播放的问题。

  • x5-video-player-type="h5" 用于强制视频使用 H5 播放器进行播放,而不是调用系统自带的播放器。
  • x5-video-player-fullscreen 启用这个属性可以使视频在点击播放时进入全屏模式。
  • x5-video-orientation="portrait" 用于锁定视频播放时的屏幕方向。portrait 表示竖屏锁定播放。可以设置为 "landscape" 来锁定横屏播放。
  • x-webkit-airplay 这是 WebKit 引擎(用于 Safari 和一些其他基于 WebKit 的浏览器)的属性,允许视频通过 AirPlay 投射到其他支持 AirPlay 的设备上,如 Apple TV。
  • webkit-playsinline 这是 iOS 上 WebKit 内核浏览器的属性。它允许视频在页面内嵌播放(非全屏),特别是在 iOS 的 Safari 浏览器中。默认情况下,iOS 上的视频会自动全屏播放,添加这个属性可以避免全屏。
  • playsinline 这是 HTML5 的标准属性,作用与 webkit-playsinline 相同,允许视频在页面内嵌播放而不是自动全屏。
  • x5-playsinline 允许视频在微信和 QQ 浏览器中内嵌播放,而不是全屏播放。功能与 webkit-playsinline 类似,但专门针对 X5 浏览器。
// https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#1
<script src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

<script>
document.addEventListener('DOMContentLoaded', function() {
  const video = document.getElementById('video');

  if (video) {
      video.play().catch(err => {
          console.log("Autoplay failed:", err);
      });
  }

  document.addEventListener('WeixinJSBridgeReady', function() {
      if (video) {
          video.play().catch(err => {
              console.log("WeixinJSBridgeReady play failed:", err);
          });
      }
  }, false);
});
</script>

小结

至此,我们就算解决了 手机端微信 H5 页面视频居然加载失败 的问题。

大家如果也遇到同样的问题,不妨试试上述提到方法,如果大家有更好的方法或者其他有效的方法,也希望在评论区讨论留言,互相学习。

拓展部分:Hugo 的一些特性

下边介绍一下 Hugo 的一些特性,感兴趣的可以继续了解一下。

其实如果会 go + 前端基础,用这个 Hugo 实现一些静态网站,还是挺不错的。不知道你会不会选择 Hugo ?

1. 基于 Go 模板引擎

  • Hugo 使用 Go 语言的模板引擎 (Go Template),其模板语法简洁且功能强大。开发者可以使用条件语句、循环、过滤器等构建高度定制的页面布局。
{{ if .Title }}
  <h1>{{ .Title }}</h1>
{{ else }}
  <h1>Default Title</h1>
{{ end }}

{{ range .Pages }}
  <a href="{{ .Permalink }}">{{ .Title }}</a>
{{ end }}

2. 支持 Markdown 格式

  • Hugo 支持 Markdown 文件作为内容源,并自动将其渲染为 HTML。这使得内容编写简单直观,特别适合写博客、文档和其他文字内容。

  • Markdown 文件与 YAML、TOML 或 JSON 前置数据(Front Matter)结合使用,可以方便地定义页面元数据(如标题、日期、标签等)。

---
title: "Hello World"
date: 2023-09-09
tags: ["Hugo", "Go", "Static Site"]
---

## 这是一个 H2 标题
欢迎使用 Hugo!这是使用 Markdown 编写的内容。

3. 短代码(Shortcodes)

  • Hugo 支持短代码功能,允许开发者在 Markdown 内容中插入动态和自定义的元素。短代码是一种特殊的 Hugo 模板,可以大大提升内容的可重用性和灵活性。
{{< youtube video_id >}}
{{- /* layouts/shortcodes/youtube.html */ -}}
<iframe
    width="560"
    height="300"
    src="https://www.youtube.com/embed/{{ .Get 0 }}"
    frameborder="0"
    allowfullscreen>
</iframe>

4. 静态与动态内容的分离

  • Hugo 强调将布局(模板)与内容分离。页面的内容由 Markdown 文件负责,布局和样式则通过 Go 模板和 CSS 文件控制。这样的分离模式便于维护和扩展网站。

5. 自定义变量与数据文件支持

  • Hugo 允许在模板中使用自定义变量(通过前置数据)或从外部文件(如 JSON、YAML、TOML)加载数据。
  • 这使得 Hugo 具有动态特性,尽管它生成的是静态页面,但可以根据数据源生成个性化的内容。
{{ range .Site.Data.authors }}
  <p>{{ .name }} - {{ .bio }}</p>
{{ end }}

6. 支持模板继承与区块

  • Hugo 支持模板继承机制,可以让多个页面共享同一布局。你可以定义全局布局,然后在具体页面上复写某些区块(block)。
{{ define "main" }}
  <div class="content">
    {{ block "content" . }}{{ end }}
  </div>
{{ end }}

7. 支持多语言与国际化(i18n)

  • Hugo 的代码支持多语言站点的构建,通过在模板中使用翻译函数,结合语言配置文件,可以轻松实现多语言支持。
{{ T "hello" }}

i18n/en.yaml 中:

hello: "Hello"

8. 强大的 URL 管理和自定义路由

  • Hugo 提供对 URL 的灵活控制,支持自定义 URL 路径、路由格式以及目录结构,开发者可以通过配置文件或前置数据自由定义页面的路径。

9. 内置的 SEO 和元数据支持

  • Hugo 允许通过模板轻松添加 SEO 元数据,Open Graph 标签,Twitter 卡片等,提升网站在搜索引擎中的表现。
<meta name="description" content="{{ .Description }}">
<meta property="og:title" content="{{ .Title }}">

10. 热重载与开发友好工具

  • 使用 hugo server 命令启动的本地服务器支持热重载,开发者修改内容或模板后,页面会自动刷新,提高开发效率。