視頻剪輯軟件手機app「video自動播放的屬性」

前言
我利用空餘時間研究了一下javascriptIntersection Observer API,發現其有很大的應用場景,比如圖片或者內容的懶加載,視差動畫等。筆者也在之前的文章中詳細介紹了3種Observer(觀察者)的用法,包括位置監聽dom變化監聽以及窗口變化監聽,它們有非常多的應用場景,所以很有必要研究明白, 感興趣的可以讀完本篇文章之後學習一下.

這裡有一個很常見的例子,平時喜歡看短視頻的朋友可能會注意到,我們在瀏覽某視頻頭條時,滾動視頻列表,當某一個視頻滾動到手機的一定位置時(一般可以看成是屏幕中心),該視頻會自動播放,當移出指定區域後視頻會自動關閉並播放移入指定區域的下一個視頻,如下:

前端如何實現類似西瓜視頻的視頻隊列自動播放?

作為一名好奇心極強的前端工程師,有必要好好研究一下其內部實現。
筆者的第一思路就是監聽滾動位置來判斷某個視頻元素是否到達指定區域內,但是這種方式需要處理的條件很多,比如邊界條件判斷,滾動方向判斷等,而且頻繁觸發還會出現性能問題。
好在我之前深入研究過Intersection Observer API,發現可以使用它提供的API,很方便的監聽到元素在指定根元素下的位置變化,並做一些自定義操作:

前端如何實現類似西瓜視頻的視頻隊列自動播放?

接下來我將直接利用Intersection Observer提供的api來實現視頻在滾動的過程中自動播放的功能,如果對該api不太熟悉的朋友可以移步幾個非常有意思的javascript知識點總結
視頻播放插件筆者將使用比較流行的Dplayer,它可以很方便的操作視頻的展現並實現很好的排他性播放控制,並且支持彈幕。
正文
根據以上的介紹我們大致了解了具體的需求,接下來我們就來基於Intersection Observer API實現一下它。思路大致如下圖所示:

前端如何實現類似西瓜視頻的視頻隊列自動播放?

具體思路就是我們可以把Intersection Observer的根元素的rootMargin(即根元素的外邊距)設置為如上圖藍色所示區域,然後當視頻完全進入該區域內後(也就是thresholds閾值為1時),觸發當前視頻的播放即可。因為我們使用的是Dplayer,所以我們只要將其配置屬性中的mutex屬性設置為true(為true時會阻止多個播放器同時播放,當前播放器播放時暫停其他播放器)。 有關設置rootMargin的知識,可以參考下圖介紹:

前端如何實現類似西瓜視頻的視頻隊列自動播放?

rootMargin接收格式如下:”10px 0px 10px 0px”,從左到右數字依次代表top(上) right(右) bottom(下) left(左)邊距,當然我們單位也可以使用百分比(%),為正值時代表擴大更元素的邊距範圍,負值代表縮小根元素的邊距範圍,這裡我們應該縮小範圍,所以rootMargin我們可以這麼設置”-180px 0px -180px 0px”,這樣上下的邊距就會縮小,當然大家也可以根據需求設置不同的值。
有了以上思路之後我們就可以實現上文動圖所展示的效果了。筆者將採用react來實現,在實現之前我們先準備幾個視頻素材,然後實現列表基本框架:

import React, { useEffect, useState } from 'react'
import VideoItem from 'components/VideoItem'
import styles from './videoList.less'

const data = [
    // 視頻列表
]

function VideoList(props) {
  useEffect(() => {
    let observerVideo = new IntersectionObserver(
        (entries, observer) => {
            entries.forEach(entry => {
                // 當移入指定區域內後,播放視頻
                if(entry.intersectionRatio === 1) {
                    // 一些操作
                    return
                }
                // 停止監聽
                // observer.unobserve(entry.target);
              });
            }, 
            {
              root: document.getElementById('scrollView'),
              rootMargin: '-180px 0px -180px 0px',
              threshold: 1
            }
        );
        document.querySelectorAll('.video-item').forEach(video => { observerVideo.observe(video) });
  }, [])
  return <div className={styles.videoWrap}>
    <div className={styles.list} id="scrollView">
        {
            data.map(item => {
                return <VideoItem src={item} groupName="video-item" key={item} />
            })
        } 
    </div>
  </div>
}

export default VideoList

以上代碼中VideoItem組件我們後面會介紹,現在有個問題是我們已經監聽到了需要自動播放的視頻元素,但是我們如何通知VideoItem組件讓其播放呢?這裡筆者實現思路是給VideoItem添加一個自定義屬性,該屬性的值就是當前video的src,我們在監聽到某個視頻元素需要播放時,我們可以獲取到之前設置的自定義屬性,然後作為prop傳給VideoItem,當VideoItem組件監聽到該prop變化時,並且等於自身的src,此時則觸發視頻播放。代碼如下:

import React, { useEffect, useState } from 'react'
import VideoItem from 'components/VideoItem'
import styles from './videoList.less'

const data = [
    // 視頻列表
]

function VideoList(props) {
  useEffect(() => {
    let observerVideo = new IntersectionObserver(
        (entries, observer) => {
            entries.forEach(entry => {
                // 當移入指定區域內後,播放視頻
                if(entry.intersectionRatio === 1) {
                    // 一些操作
                    return
                }
                // 停止監聽
                // observer.unobserve(entry.target);
              });
            }, 
            {
              root: document.getElementById('scrollView'),
              rootMargin: '-180px 0px -180px 0px',
              threshold: 1
            }
        );
        document.querySelectorAll('.video-item').forEach(video => { observerVideo.observe(video) });
  }, [])
  return <div className={styles.videoWrap}>
    <div className={styles.list} id="scrollView">
        {
            data.map(item => {
                return <VideoItem src={item} groupName="video-item" key={item} />
            })
        } 
    </div>
  </div>
}

export default VideoList

以上步驟即完成了基於指定區域自動播放視頻的功能,效果如下:

前端如何實現類似西瓜視頻的視頻隊列自動播放?

最後
如果想學習更多H5遊戲, webpacknodegulpcss3javascriptnodeJScanvas數據可視化等前端知識和實戰,歡迎在《趣談前端》專欄學習討論,共同探索前端的邊界。

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/269337.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-16 13:15
下一篇 2024-12-16 13:15

相關推薦

發表回復

登錄後才能評論