Краткий обзор практического применения видеокомпонента мини-программы WeChat

Апплет WeChat

Нашей программе WeChat Store + Mini недавно потребовалось добавить функцию видео в сведения о продукте, поэтому мы воспользовались официальной программой WeChat.VideoКомпоненты, я столкнулся с некоторыми проблемами во время использования, и некоторые проблемы особенно жалки. Я думаю, что необходимо обобщить и поделиться ими для справки с коллегами, у которых есть такие потребности. В этой статье я в основном объясняю окончательное решение, которое я использую, с лучшей совместимостью ., Я надеюсь помочь нуждающимся детям.

В процессе использования видеокомпонента я в основном столкнулся со следующими проблемами:

  • Нестабильная производительность макета
  • Автоматическое воспроизведение по Wi-Fi, черный экран воспроизведения видео (часто на Android)
  • Список видео не прокручивается вместе со страницей
  • Видео воспроизводится глобально, нажмите кнопку «Назад», положение макета ненормальное.
  • Видео нужно перезагружать каждый раз

Пример исходного кода

Макет пользовательского интерфейса

Макет, который мы хотим получить

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

В соответствии с традиционным методом записи наша структура кода может быть следующей:

<view>
    <!-- 视频 -->
    <video></video>
    <!-- 覆盖视频的图片 -->
    <view>
        <image/>
        <!-- 播放按钮 -->
        <view></view>
    </view>
    <!-- 底部视频和图片切换按钮 -->
    <view></view>
</view>

потом через картинкуposition:absoluteабсолютное позиционирование,z-indexКаскадные контексты для завершения макета, этот метод хорошо работает в системе ios, на некоторых устройствах Android изображения и кнопки будут покрыты компонентом видео, потому чтоvideoКомпоненты являются нативными компонентами, и на их использование существуют некоторые ограничения. Конкретные ограничения см. здесь.Официальная документация WeChat, основная причина, которая влияет на нас, заключается в том, что уровень нативных компонентов самый высокий, поэтому независимо от того, какой установлен z-index, другие компоненты на странице не могут покрывать нативные компоненты.

К счастью, WeChat официально предоставилcover-viewа такжеcover-imageКомпоненты, которые могут накладываться на собственные компоненты. При использовании наша схема выглядит следующим образом:

<view>
    <video>
        <cover-view>
            <!-- 覆盖图片 -->
            <cover-image></cover-image>
            <!-- 播放按钮 -->
            <cover-image></cover-image>
        </cover-view>
    </video>
</view>

Функция воспроизведения

Одно видео, нажмите, чтобы воспроизвести

Существует несколько конфигураций, связанных с воспроизведением видеокомпонента, в основном в том числе

  • src Адрес ресурса видео для воспроизведения
  • autoplay, играть ли автоматически

Кроме того, WeChat также предоставляет функцииconst video = wx.createVideoContext()Метод может получить экземпляр видео и управлять воспроизведением с помощью метода video.play().

Итак, есть несколько вариантов:

Первое решение, после получения адреса видео пройтиsetDataМетод обновляет адрес видео компонента и автовоспроизведение верно Преимущество этого метода в том, что время начала видео контролируется самим компонентом, которого в принципе не существует.Черный экран или когда видео загружается и не воспроизводится, но недостаток в том, что когда вы переключаетесь на другие страницы, а затем возвращаетесь, вам нужно каждый раз перезагружать видео, а производительность и опыт не очень хороши.

<!--方案一-->

<!--js-->
this.setData({
    src:url,
    autoplay:true
})
<!--html-->
<video src="{{src}}" autoplay="{{autoplay}}"></video>

Во второй схеме, через управление API, проблема в тайминге воспроизведения видео, потому что требуется время для загрузки адреса видео.Если мы нажмем кнопку воспроизведения после рендеринга страницы, если видео еще не загружено, вызовем это напрямую.videoContext.play()Метод может быть недействительным, поэтому мы должны дождаться загрузки видео, прежде чем вызыватьplay()метод, вот метод обратного вызова setData для вызоваplay()способ начать воспроизведение, в дополнение кpause()Пауза,stop()Остановка и другие методы управления состоянием воспроизведения видео. Это решение может загружать видео только один раз, а затем воспроизводить его без перезагрузки, а пользовательский опыт лучше.Кроме того, была решена проблема неконтролируемого времени воспроизведения, чего в принципе не происходит.черный экранСлучай

<!--方案一-->

<!--js-->
data:{
    autoplay:false
}
const { videoContext } = this.data;

<!--视频播放,关键代码-->
this.setData({
    autoplay:true,
    url:videoUrl
},()=>{
    videoContext.play()
})
<!--html-->
<video src="{{url}}" autoplay="{{autoplay}}"></video>

Одиночное видео, автоматическое воспроизведение через Wi-Fi

WeChat предоставляет апи для суждения о сетевом окружении.Судя по апи, если он под вайфаем, то будет активно звонитьvideoContext.play()метод.

wx.getNetworkType({
        success(res) {
            const networkType = res.networkType;
            if (networkType === 'wifi') {
                that.videoPlay();
            }
        },
    });
    
videoPlay(){
    this.setData({
        autoplay:true,
        url:videoUrl
    },()=>{
    videoContext.play()
    })
}

Видео недоступно для просмотра, остановить воспроизведение

Предоставлено WeChatIntersectionObserverОбъект, используемый для определения того, видны ли пользователю определенные узлы и какая часть может быть видна пользователем.Ранее мы использовали, чтобы определить, был ли элемент в представлении.getBoundingClientRect, Этот метод также можно использовать в среде WeChat, но этот метод должен вычислять положение элемента, вызывая перерисовку страницы, что влияет на производительность. а такжеIntersectionObserverНативно определять положение само по себе, и проблем с этим не будет.Вы можете следить за положением элемента через этот апи, чтобы контролировать, играть или нет.

wx.createIntersectionObserver(that)
    .relativeToViewport()
        .observe('.video--wrap', res => {
            if (res && res.intersectionRatio > 0) {
                that.videoPlay();
            } else {
                that.videoPause();
            }
        });

Воспроизведение видео без звука

может быть измененmutedЭто свойство определяет, отключено ли видео. Например, оно отключено по умолчанию в начале. Нажмите кнопку громкости, чтобы включить функцию звука.

data:{
    muted:true //初始为true,静音
}
methods:{
    handleMuted(){
        this.setData({
            muted:false
        })
    }
}


Список видео

Я использовал его сначалаwx:forПеречислите компонент воспроизведения видео, воспроизводится дочерний компонент, инициируйте событие, родительский компонент прослушивает событие дочернего компонента, обновляет значение списка видео, а затем дочерний компонент прослушивает изменения свойств для обновления состояния воспроизведения Это решение работает хорошо на ios, но ставится на Android. ,Страница не может прокручиваться, после проверки данных компонент списка видео не может быть напрямую похож на обычный список изображений Реальное решение состоит в том, чтобы использовать первый кадр видео в качестве списка, а затем щелкнуть первый кадр изображения, чтобы перейти на новую страницу или маску для воспроизведения видео.

Проведите пальцем влево и вправо по апплету

Нам также нужна функция скольжения влево и вправо, чтобы переключить изображение и видео дисплей, который необходимо контролировать путем мониторингаtouchstartа такжеtouchmoveчтобы определить направление скольжения мобильного телефона, чтобы переключить положение отображения видео и изображения.

touchstart: function(e) {
        this.setData({
            startX: e.changedTouches[0] && e.changedTouches[0].clientX,
            startY: e.changedTouches[0] && e.changedTouches[0].clientY,
        });
    },
touchmove: function(e) {
        var that = this,
        startX = that.data.startX, //开始X坐标
        startY = that.data.startY, //开始Y坐标
        touchMoveX = e.changedTouches[0].clientX, //滑动变化坐标
        touchMoveY = e.changedTouches[0].clientY, //滑动变化坐标
    },
//根据起点和终点返回方向 1:向上,2:向下,3:向左,4:向右,0:未滑动
GetSlideDrection: function(startX, startY, endX, endY) {
    var dy = endY - startY;

    var dx = endX - startX;

    var result = 0;

    //如果滑动距离太短

    if (Math.abs(dx) < 2 && Math.abs(dy) < 2) {
        return result;
    }

    var angle = this.GetSlideAngle(dx, dy);

    if (angle >= -45 && angle < 45) {
        result = 4;
    } else if (angle >= 45 && angle < 135) {
        result = 1;
    } else if (angle >= -135 && angle < -45) {
        result = 2;
    } else if ((angle >= 135 && angle <= 180) || (angle >= -180 && angle < -135)) {
        result = 3;
    }

    return result;
    },
GetSlideAngle: function(dx, dy) {
    return (Math.atan2(dy, dx) * 180) / Math.PI;
},

Все вышеперечисленные решения можно просмотреть через фрагмент кода апплета.

Нажмите, чтобы посмотреть план

отладка

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

Суммировать

На самом деле я столкнулся с довольно многими проблемами в процессе разработки.В видеосоставляющей апплета еще довольно много подводных камней.Я не описывал их по одному.Если вы столкнулись с другими проблемами,оставляйте комментарии. Если я сталкивался с ними, может быть, я могу высказать некоторые мнения. Цель написания этой статьи - позволить большему количеству разработчиков мелких программ наступать на ямы как можно меньше. Если это поможет вам, спасибо за вашу поддержку!