Как реализовать полноэкранное воспроизведение небольших видеороликов, совместимых с ПК и WeChat H5

внешний интерфейс WeChat HTML

Для этой проблемы на самом деле есть хорошие практики в Интернете, но иногда я не понимаю, почему это настроено таким образом, если вы хотите узнать слабого, жалкого и беспомощного<video>Как стать пухлым и крепким видеоплеером, тогда читайте дальше!

нужно

Приходите, чтобы задать вопрос на странице сведений о терминале врача H5 (ПК и WeChat):

  • Поддержка нажатия кнопки воспроизведения, чтобы вызвать проигрыватель для воспроизведения видео
  • Во время воспроизведения поддерживается приостановка видео, закрытие видео, перетаскивание индикатора выполнения для регулировки хода видео.
  • Независимо от того, находится ли он в среде WiFi, вам нужно вручную щелкнуть, чтобы воспроизвести

Шагая по дороге

Первый этап

строить планы

  1. Использование HTML5<video>тег для воспроизведения видео
  2. установить толькоsrcАтрибуты

яма

  1. Стили ширины и высоты DOM нормальные, когда не воспроизводится, но нет обложки, и первый кадр видео не захватывается как обложка.
  2. После нажатия кнопки воспроизведения будет вызван системный проигрыватель по умолчанию для полноэкранного воспроизведения.Первоначальный интерфейс проигрывателя разнообразен.
  3. После завершения воспроизведения видео Android стиль DOM нарушается, а ширина и высота источника видео будут отображаться независимо от css.
  4. Android добавит после завершения видеоВидеорекомендация, и запись приложения в белый список закрыта

вторая стадия

строить планы

  1. УвеличиватьposterАтрибут, значение — адрес обложки, сгенерированный бэкендом на основе первого кадра видео.
  2. Добавьте слой маски и стиль значка, чтобы имитировать начальный интерфейс плеера.
  3. Буду<video>использование ярлыка<div>обернуть контейнер и установитьdisplay: noneСкрытый, вызывается, когда пользователь нажимает на обложкуvideoизplay()способ играть
  4. Босс Tencent заставил отображать видеорекомендации, поэтому я пока не буду этим заниматься

яма

  1. Спрятать<video>Вызывается в WeChat после элементаplay()Нет реакции
  2. На ПК только звук, а изображения нет. Это связано с тем, что на стороне ПК не будет открываться специальный проигрыватель, а будет воспроизводиться только непосредственно на узле DOM, а узел DOM в это время не устанавливает область отображения.
  3. Просто для воспроизведения видео ответом является метод video.play(), это не значит, что воспроизведение началось (будет процесс буферизации), пользователь ошибочно подумает, что клик недействителен

Третий этап

строить планы

  1. использоватьdisplay: none;илиwidth: 0; height: 0;способ скрыть видео, когда элемент неактивен и не отвечаетplay()метод, поэтому мы устанавливаем ширину и высоту на1px;
  2. Установите флажок, чтобы судить об окружающей среде. Если в среде ПК, разверните видеоконтейнер до полноэкранного размера после воспроизведения и добавьте кнопку закрытия. После нажатия приостановите воспроизведение видео и удалите стиль расширения.
  3. Эффект загрузки добавляется при нажатии на обложку, а среда ПК отменяется при воспроизведении видео; среда WeChat отменяется при паузе видео. (в iOSplay()Метод запускает событие воспроизведения, но проигрыватель в данный момент не открыт, а приостановка воспроизведения видео во время полноэкранного воспроизведения не приводит к выходу из проигрывателя. Таким образом, мы можем отменить загрузку, когда видео поставлено на паузу);

яма

  1. Версия WeChat для iPad и WindowsPC также не будет открывать новый проигрыватель, а будет открываться непосредственно вvideoИгра на метке, приводящая к звуку, но без изображения; iPad можно решить, изменив условия оценки ПК
  2. Некоторые устройства Android не могут воспроизводиться, вам необходимо установить браузер QQ или плагин для воспроизведения видео QQ, но все еще есть пользователи, которые не могут установить плагин или он по-прежнему недействителен после установки.

Этап 4: «Передовой опыт»

В настоящее время, используя собственные события и атрибуты тегов видео, нет никакого способа прорваться через вышеупомянутые ямы и решить совершенно другие проблемы совместимости. Поэтому обращаемся к другим схемам для достижения нужного эффекта.

строить планы

PS: Проект основан на Vue и scss, но функцию можно реализовать без опоры на эти

  1. Используйте различные свойства совместимости и расширенные свойства для браузеров ядра x5.webkit-playsinline, playsinline, x-webkit-airplay, x5-video-player-type, x5-video-player-fullscreen, x5-video-orientationи т. д. для устранения различий в воспроизведении различных типов устройств;
  2. Установите флаг, чтобы указать, воспроизводится ли он или находится в полноэкранном режиме.
<!-- 视频容器 -->
<div class="video"
     :class="{'full-screen': isFullScreen}">
  <!-- 视频主体 -->
  <div class="video-content">
    <video :controls="isFullScreen"
           :style="isFullScreen ? {} : img.style"
           :class="img.isVertical ? 'vertical-img' : 'horizontal-img'"
           :src="img.url"
           preload="metadata"
           :poster="img.preview_pic_url"
           :ref="`video${img.id}`"
           webkit-playsinline="true"
           playsinline="true"
           x-webkit-airplay="allow"
           x5-video-player-type="h5"
           x5-video-player-fullscreen="true"
           x5-video-orientation="portraint">
      抱歉,您的浏览器不支持内嵌视频!
    </video>
  </div>
  <!-- 遮罩层,显示播放按钮;仅在待播放状态显示 -->
  <div v-if="!isFullScreen"
       class="video-mask">
    <div>
      <img src="~images/play.png" />
    </div>
  </div>
  <!-- 全屏控制按钮;仅在非安卓高版本内核中显示 -->
  <div v-else-if="!inHighTBS"
       class="video-controls">
    <span class="video-controls-close"
          @click.stop="handleVideoControls('close')">
      &times;
    </span>
  </div>
</div>

Описание недвижимости

  1. controls: установите флажок, чтобы он отображался только во время воспроизведения, чтобы избежать различных начальных состояний воспроизведения.
  2. style: Вычислить смещение видео по абсолютному положению воспроизводимого дома; область отображения видео представляет собой квадратное окно, поэтому области отображения видео по горизонтали и вертикали должны быть посередине.
  3. class: установка высоты видео по горизонтали или ширины видео по вертикали.
  4. src: Источник видео
  5. preload: значение предварительно загружено, но не заблокировано; на каждый вопрос приходится не более одного видео, что гарантирует, что пользователь ответит сразу после нажатия кнопки воспроизведения и не блокирует отображение других вложенных изображений.
  6. poster: Обложка адрес
  7. ref:существуетvueполучить и работатьvideoэлемент
  8. webkit-playsinline: установлено в iOS 10, когда воспроизведение видео, локальное воспроизведение, без подробного потока; вы можете убедиться, что интерфейс воспроизведения соответствует ПК
  9. playsinline: Браузер IOS WeChat поддерживает воспроизведение в маленьком окне и совместим практически со всеми устройствами IOS при съедении вместе с предыдущим атрибутом
  10. x5-video-player-type: Включить однослойный проигрыватель H5, который является функцией версии wechat для Android.
  11. x5-video-player-fullscreen: При воспроизведении видео оно будет переходить в полноэкранный режим.Если не установить, то плеер все равно будет открываться, но размер исходный размер области просмотра (до этого видео не проигрывалось)
  12. x5-video-orientation: управление горизонтальным и вертикальным экраном
  /* 外层还有其他已定位容器 */
  .video {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
    transition: all 0.3s;
    background-color: rgba(0, 0, 0, 0.5);
    &.full-screen {
      position: fixed;
      z-index: 99;
      .video-content {
        width: 100%;
        height: 100%;
        video {
          position: initial;
          &.vertical-img {
            height: 100%;
            width: auto;
            margin: 0 auto;
          }
          &.horizontal-img {
            width: 100%;
            height: auto;
            max-height: 100%;
          }
        }
      }
    }
    &-mask {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      background-color: rgba(0, 0, 0, 0.5);
      div {
        width: 100%;
        text-align: center;
        img {
          width: 30%;
          position: inherit;
        }
      }
    }
    &-controls {
      position: absolute;
      right: 5%;
      top: 5%;
      display: flex;
      align-items: center;
      z-index: 1;
      &-close {
        width: 50px;
        height: 50px;
        line-height: 50px;
        color: rgba(255, 255, 255, 0.7);
        background: rgba(0, 0, 0, 0.3);
        text-align: center;
        border-radius: 50%;
        font-size: 2rem;
        cursor: pointer;
        transition: all 0.3s;
        &:hover {
          background: rgba(0, 0, 0, 0.5);
          color: #fff;
        }
      }
    }
    &-content {
      max-width: 768px; // 限制PC端不超过768px;如要PC全屏可不做设置
      margin: 0 auto;
      display: flex;
      align-items: center;
      video {
        display: block;
        position: absolute;
        object-fit: fill;
      }
    }
  }
  .horizontal-img {
    height: 100%;
    top: 0;
  }
  .vertical-img {
    width: 100%;
    left: 0;
  }

небольшая проблема

В Android WeChat, даже если добавить вышеперечисленные атрибуты, все равно будут черные рамки вверх и вниз, и он не может быть полноэкранным. решиться<video>плюсobject-fit: fill;стиль.

После того, как мод был запущен, пользователи, которые ранее сообщали об ошибках, сообщали об этом, никаких проблем, но...

Сообщить об ошибке?

Есть отзывы пользователей о том, что видео с использованием молотка Nut Pro не имеет отклика.После нахождения тестовой машины той же модели оно не воспроизведено!

После этого путем постоянного общения с пользователями было установлено, что на устройстве не используется браузер ядра X5 (для его открытия используйте WeChat)debugtbs.qq.comЯдро X5 можно отлаживать, если оно не установлено, будет подсказка)

Поэтому сообщается об ошибке при рассмотрении следующего события совместимости с Android, используйтеtry { } catch (e) {}Упакуйте его, он также может нормально воспроизводиться, но эффект воспроизведения от этого уже не является однородным.

Совместимость с событиями Android
// 高版本微信安卓环境下会自动加上返回按钮并且点击触发退出全屏事件
// 需做未使用X5内核容错处理
inHighTBS() {
  if (inAndroid) {
      try {
         const [, currentTbsVersion] = window.navigator.userAgent.match(/TBS\/(\d+)/);

        return currentTbsVersion > '036900';
      } catch() {
          return false;
      }
  } else {
    return false;
  }
}

// 安卓环境中会启用同层H5播放器,跳转新窗口,因此监听x5videoexitfullscreen事件可获取状态
// https://x5.tencent.com/tbs/guide/video.html
this.inHighTBS && vDom.addEventListener('x5videoexitfullscreen', () => {
  this.isFullScreen = false;
});

приложение

видео изначально поддерживает события

const mediaProperties = [
  'loadstart',  // 在媒体开始加载时触发。
  'progress',   // 告知媒体相关部分的下载进度时周期性地触发。有关媒体当前已下载总计的信息可以在元素的buffered属性中获取到。
  'suspend',    // 在媒体资源加载终止时触发,这可能是因为下载已完成或因为其他原因暂停。
  'abort',  //  在播放被终止时触发,例如, 当播放中的视频重新开始播放时会触发这个事件。
  'error',  // 在发生错误时触发。元素的error属性会包含更多信息。参阅Error handling获得详细信息。
  'emptied',    // 媒体被清空(初始化)时触发。
  'stalled',    // 在尝试获取媒体数据,但数据不可用时触发。
  'loadedmetadata', // 媒体的元数据已经加载完毕,现在所有的属性包含了它们应有的有效信息。
  'loadeddata', // 媒体的第一帧已经加载完毕。
  'canplay',    // 在媒体数据已经有足够的数据(至少播放数帧)可供播放时触发。这个事件对应CAN_PLAY的readyState。
  'canplaythrough', // 在媒体的readyState变为CAN_PLAY_THROUGH时触发,表明媒体可以在保持当前的下载速度的情况下不被中断地播放完毕。注意:手动设置currentTime会使得firefox触发一次canplaythrough事件,其他浏览器或许不会如此。
  'playing',    // 在媒体开始播放时触发(不论是初次播放、在暂停后恢复、或是在结束后重新开始)。
  'waiting',    // 在一个待执行的操作(如回放)因等待另一个操作(如跳跃或下载)被延迟时触发。
  'seeking',    // 在跳跃操作开始时触发。
  'seeked', // 在跳跃操作完成时触发。
  'ended',  // 播放结束时触发。
  'durationchange', // 元信息已载入或已改变,表明媒体的长度发生了改变。例如,在媒体已被加载足够的长度从而得知总长度时会触发这个事件。
  'timeupdate', // 元素的currentTime属性表示的时间已经改变。
  'play',   // 在媒体回放被暂停后再次开始时触发。即,在一次暂停事件后恢复媒体回放。
  'pause',  // 播放暂停时触发。
  'ratechange', // 在回放速率变化时触发。
  'resize',
  'volumechange',   // 在音频音量改变时触发(既可以是volume属性改变,也可以是muted属性改变).。
  'mozaudioavailable'   // 当音频数据缓存并交给音频层处理时
 ];

mediaProperties.forEach(item => {
  vDom.addEventListener(item, e => console.log(item));
});

Ссылаться на:

Автор: Команда доктора СирениГу Чжун