Skip to content

video 标签 详解

更多请查看:https://www.w3school.com.cn/jsref/dom_obj_video.asp

html
  <video
    class="video-source"
    width="100%"
    height="200px"
    src=""
    preload="auto" /* 这个属性规定页面加载完成后载入视频*/
    controls /* 设置是否显示播放器控件(如播放/暂停等) */
    loop="loop" /* 设置或返回视频是否应在结束时再次播放 */
    webkit-playsinline="true"  /* 针对ios9不全屏播放 */
    playsinline="true"  /* 针对ios10、11不全屏播放 */
    x5-video-player-type="h5-page" /* 启用X5内核同层渲染 */
    x5-video-orientation="portraint" /* 播放器方向,landscape横屏,portraint竖屏,默认值为竖屏 */
    x5-video-player-fullscreen="true" /* 全屏设置,设置为 true 是防止横屏 */
    x5-playsinline="true"  /* 设置X5内核为行内播放模式,不能和`x5-video-player-type同时设置会覆盖 */
    x-webkit-airplay="true" /* 默认不全屏播放 */
    x5-video-ignore-metadata="true"
  />

preload="auto"

属性规定是否在页面加载后载入视频。

注:如设置了 autoplay 属性,则忽略该属性。

  • auto - 当页面加载后载入整个视频
  • meta - 当页面加载后只载入元数据
  • none - 当页面加载后不载入视频

autoplay

自动播放 自动播放不推荐的方案:

  • 设置autoplay属性,由于浏览器本身限制,设置该属性没有生效。浏览器(Google Chrome)上可以设置muted(静音)可自动播放,但效果并不理想,不推荐。
  • 直接调用play() 方法
  • 通过js主动触发click事件
  • 监听touchstart事件,调用play()方法,可以实现,但需要用户触发一次touchstart,可作为降级方案,并不建议采用。

iOS 微信内通过监听WeixinJSBridgeReady事件,调用play()事件,可实现自动播放功能

javascript
document.addEventListener('WeixinJSBridgeReady', () => {
  this.videoPlay();
}, false);


videoPlay() {
  if (this.$refs.liveVideo) {
    this.$refs.liveVideo.play();
  }
},

注: 如果视频地址是通过接口返回的,直接调用play方法会出现自动播放失败,因为WeixinJSBridgeReady只触发一次。 可以采用定时器连续调用的方式解决问题 处理代码如下:

javascript
  methods: {
    repeatVideoPlay() {
      // loadStatus 为接口返回后状态
      if (this.loadStatus) {
        this.videoPlay();
      } else {
        setTimeout(() => {
          this.repeatVideoPlay();
        }, 2000);
      }
    },
    videoPlay() {
      if (this.$refs.liveVideo) {
        this.$refs.liveVideo.play();
      }
    },
  },
  created() {
    document.addEventListener("WeixinJSBridgeReady", this.repeatVideoPlay, false);
  },
  destroyed() {
    document.removeEventListener("WeixinJSBridgeReady", this.repeatVideoPlay, false);
  },

playsinline与webkit-playsinline

如果你不希望用户来拖动进度条的话,可以直接使用 playsinline属性,webkit-playsinline属性 如果是想做全屏直播或者全屏H5体验的用户,iOS需要删除这个属性(设置false不生效),安卓则不需要,因为默认全屏

X5 内核两种播放状态

官方文档:TBS腾讯浏览器服务 - H5同层播放器

页面内播放

X5内核视频在用户点击后默认会进入全屏播放,前端可以设置 videox5-playsinline 属性来将视频限定于网页内部播放。

html
<video
  width="300"
  height="300"
  src="https://tbm-auth.alicdn.com/e7qHgLdugbzzKh2eW0J/kXTgBkjvNXcERYxh2PA%40%40hd_hq.mp4?auth_key=1631498860-0-0-7d175e8f2c2cab984708d2a5b3f17eac"
  x5-playsinline
  controls
></video>

同层页面内播放

同层播放,就是在视频全屏的时候,div可以呈现在视频层上,WeChat(x5内核)特有的属性。 同层页面内播放是标准的视频播放形态,在 video 标签中添加且只需要添加一个(不要与 **x5-playsinline** 同时存在): x5-video-player-type='h5-page' 属性来控制网页内部同层播放,可以在视频上方显示 html 元素。

html
<video
  id="video"
  width="300"
  height="300"
  src="https://tbm-auth.alicdn.com/e7qHgLdugbzzKh2eW0J/kXTgBkjvNXcERYxh2PA%40%40hd_hq.mp4?auth_key=1631498860-0-0-7d175e8f2c2cab984708d2a5b3f17eac"
  controls
  preload
  loop="loop"
  x5-video-player-type="h5-page"
></video>

腾讯浏览服务,常见的音视频问题

Android 遇到的问题

如果视频没有播放的情况,双击进度条快进会吧整个video播放不了的情况出现,导致出现该问题的原因暂时不知什么原因引起

解决方法:添加一个蒙层,点击蒙层就播放视频,短暂的处理方案 完整代码如下:

vue
<template>
  <div class="video_box">
    <div class="cover" @click.stop.prevent="play" v-if="!played"></div>
    <video
      :src="src"
      :poster="poster"
      :id="`videoElement${index}`"
      controls
      playsinline
      webkit-playsinline
      webkit-inline
      x5-video-player-type="h5-page"
      x5-video-player-fullscreen="true"
      x-webkit-airplay="allow"
      x5-video-orientation="portraint"
    />
  </div>
</template>

<script>
export default {
  props: {
    src: {
      type: String,
      default: '',
    },
    poster: {
      type: String,
      default: '',
    },
    index: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      played: false,
    }
  },
  methods: {
    play() {
      document.getElementById(`videoElement${this.index}`).play()
      this.played = true
    },
  },
}
</script>

<style lang="scss" scoped>
.video_box {
  position: relative;
  width: 100%;
  height: 194px;
  .cover {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 1000;
  }
  video {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
  }
}
</style>

video 属性返回 Infinity

解决参考:https://stackoverflow.com/questions/38443084/how-can-i-add-predefined-length-to-audio-recorded-from-mediarecorder-in-chrome

javascript
;<video
  controlslist='nodownload'
  playsinline=''
  webkit-playsinline=''
  x5-video-player-type='h5-page'
  x-webkit-airplay='true'
  autoplay='autoplay'
  controls='controls'
  preload='auto'
  style='width: 100%;height: auto;'
  src=''
></video>

var player = document.querySelector('video')
window.onload = function () {
  // 获取总时长
  player.addEventListener('durationchange', (event) => {
    console.log(player.duration)
    // Infinity
  })
  // 监听缓存进度
  player.addEventListener('progress', (event) => {
    let bufvalue = player.buffered.end(player.buffered.length - 1)
    console.log(parseInt(bufvalue))
    // Infinity
  })
}

前端 video 直播场景时,对延迟比较高要求(电商秒杀等场景)的可以通过监控 progress 来达到效果

javascript
// TODO:设置currentTime为最新的播放时长要控制好频率与快进时长,要不然会导致一直loading加载新的TS片段
var player = document.querySelector("video");
var videoCanskip = 0;
player.addEventListener("progress", function (event) {
  // 返回表示音频/视频已缓冲部分的 TimeRanges 对象。
  var startBuffered = player.buffered.start(0);
  var endBuffered = player.buffered.end(0);
  videoCanskip = parseInt(endBuffered - startBuffered);
  console.log("video_可快进时长" + Math.ceil(videoCanskip));
}

// 设置currentTime 值 来播放最新内容
player.currentTime = videoCanskip;

解决ios video audio无法自动播放、循环播放的问题

writing....