播放器播放條 鬥魚、Youtobe等
https://web-streaming.github.io/ppbar/
使用 使用 ppbar,需要導入 ProgressBar 類和 ppbar 的樣式。 import ProgressBar from 'ppbar'; import 'ppbar/dist/index.min.css'; const div = document.createElement('div'); const bar = new ProgressBar(div, { // 參數 }) document.body.appendChild(div) ProgressBar 構造函數接收兩個參數,第一個它的容器,第二個是 ppbar 的參數。如果設置第一個參數會自動將 ppbar 的 DOM 元素添加到傳入容器中。 當然希望手動添加 ppbar 的 DOM 元素,可以不傳入第一個參數。 import ProgressBar from 'ppbar'; import 'ppbar/dist/index.min.css'; const bar = new ProgressBar(undefined, { // 參數 }) document.body.appendChild(bar.el) ppbar 有一個 updateConfig 方法,可以隨時通過它來動態更新參數。 import ProgressBar from 'ppbar'; import 'ppbar/dist/index.min.css'; const bar = new ProgressBar(undefined, { // 參數 }) document.body.appendChild(bar.el) bar.updateConfig({ /* 新參數 */ }) // 如果不需要 bar 對象了請銷燬它 bar.destroy() 章節 章節可以設置進度條分段效果,每個章節必須有一個標題,鼠標 hover 進度條時會被展示出來。 章節應該有個 time 屬性,表示該章節的結尾,最後一個章節可以省略 time 屬性。 import ProgressBar from 'ppbar'; import 'ppbar/dist/index.min.css'; new ProgressBar(document.body, { chapters: [ { time: 10, title: 'chapter1' }, { time: 20, title: 'chapter2' }, { title: 'chapter3' }, ] }) 上面一共設置 3 個章節,分別是: 0s - 10s chapter1 10s - 20s chapter2 20s - duration chapter3 標記 該功能允許你在進度條上設置標記點,每個標記點可以放入自定義的 DOM 或一張圖片。 import ProgressBar from 'ppbar'; import 'ppbar/dist/index.min.css'; new ProgressBar(document.body, { markers: [ { time: 10, title: 'marker1', image: './img.jpg', size: [30, 30] }, ] }) 上面代碼在進度條 10 秒位置,設置了一個標記點,標記點中有一個圖片,它的大小是 30x30。 除了圖片還可以使用自定義的 dom 元素。 import ProgressBar from 'ppbar'; import 'ppbar/dist/index.min.css'; const div = document.createElement('div') new ProgressBar(document.body, { markers: [ { time: 10, title: 'marker1', el: div }, ] }) 當標記點被點擊時會觸發 markerClick 事件。 import { EVENT, ProgressBar } from 'ppbar' const bar = new ProgressBar(document.body, { markers: [ { time: 10, title: 'marker1' }, ] }) bar.on(EVENT.MARKER_CLICK, (marker) => console.log(marker)) 熱力圖 熱力圖用於標記整個視頻不同時間段觀看量的變化。比如 0 到 5 秒觀看量是 100,5 到 10 秒觀看量是 200 ... 然後將這些觀看量繪製成曲線就是 ppbar 的熱力圖了。 const bar = new ProgressBar(document.body, { heatMap: { points: [1, 2, 3], defaultDuration: 5, } }) 上面代碼配置表示,每個點表示的時長爲 5 秒,也就是 0 - 5 的值是 1,5 - 10 爲 2,10 - 15 爲 3。 另外還支持給每個點單獨設置時長。 const bar = new ProgressBar(document.body, { heatMap: { points: [{ duration: 10, score: 1 }, { score: 2 }, { duration: 2, score: 3 }], defaultDuration: 5, } }) 上面配置中,第一個和第三個有自己的時長,第二個則是使用 defaultDuration。 如果希望熱力圖和 Youtube 一樣,只有 hover 的時候才顯示,可以設置 hoverShow。 const bar = new ProgressBar(document.body, { heatMap: { points: [1, 2, 3], defaultDuration: 5, hoverShow: true } }) 縮略圖 縮略圖用於預覽視頻的不同時間點的畫面。一張縮略圖由多張小縮略圖拼接而成。 const bar = new ProgressBar(document.body, { thumbnail: { start: 0, // 縮略圖開始時間,單位秒 gap: 10, // 單個小縮略圖表示的時長 row: 5, // 大縮略圖是又幾行小縮略圖組成 col: 5, // 大縮略圖是又幾列小縮略圖組成 width: 160, // 單個小縮略圖寬度 height: 90, // 單個小縮略圖的高度 images: [], // 縮略圖地址數組 } }) 以上參數的值都是默認參數。 另外如果你不希望展示縮略圖可以將它設置爲 false。 const bar = new ProgressBar(document.body, { thumbnail: false }) 直播 ppbar 還支持直播時移,在直播模式下進度條的時間展示將會是負數。 new ProgressBar(document.body, { live: true }) 另外還可以使用 updateConfig 方法動態開啓關閉直播模式。 const bar = new Progress(document.body) bar.updateConfig({ live: true }) 旋轉 ppbar 還支持被旋轉,例如在移動端不使用全屏,但是希望視頻橫着播放,這是就會對播放器設置 transform: rotate(90deg)。這時候就需要手動更新 ppbar 的旋轉來防止 ppbar 交互失效。 const div = document.createElement('div') div.style.transform = 'rotate(90deg)' new ProgressBar(div, { rotate: 90 }) 你還可以通過 updateRotate 方法來動態更新參數。 const bar = new ProgressBar(document.body) bar.updateRotate(90) 事件 ppbar 還會拋出事件,你可以使用 on 方法監聽事件,once 方法監聽一次事件,off 取消監聽事件。 import { EVENT, ProgressBar } from 'ppbar' const bar = new ProgressBar(document.body) bar.once(EVENT.DRAGGING, console.log) bar.on(EVENT.DRAGEND, console.log) bar.off(EVENT.DRAGEND, console.log) 具體的事件描述請查看 API 事件章節 自定義樣式 ppbar 支持自定義修改樣式。 new ProgressBar(document.body, { dot: '<svg>...</svg>' }) 參數 dot 可以自定進度條原點,可以是自定義 DOM 元素、字符串,爲字符串時將直接設置 innerHTML。 另外還可以通過 CSS 變量來設置 ppbar 的主題色。 const bar = new ProgressBar(document.body) bar.el.style.setProperty('--primary-color', 'rgba(35,173,229, 1)'); --primary-color 是 ppbar 的主題色,默認爲 #f00。 最後你還可以通過 Sass 變量來自定義樣式。 @use '~ppbar/lib/index.scss' with ( $primaryColor: #0f0, $markerDotBg: #f00, $heatMapHeight: 30px ) 在 scss 文件中導入並覆蓋樣式。 import ProgressBar from 'ppbar' import './index.scss' 導入上面自定義的樣式。 目前一共支持 3 種自定義 sass 變量。 $primaryColor 進度條的主題色,默認 #f00 $markerDotBg 標記點的背景色,默認 #fff $heatMapHeight 熱力圖高度,默認 40px 集成到播放器 你可以使用 ppbar 打造自己的播放器,或者將它集成到現成的播放器中,下面以 nplayer 爲例。 import ProgressBar, { EVENT as BAR_EVENT } from 'ppbar'; import Player, { EVENT } from 'nplayer'; import 'ppbar/dist/index.min.css' const div = document.createElement('div') div.style.width = '100%' const progress = new ProgressBar(div, { chapters: [ { time: 10, title: 'chapter-a' }, { time: 28, title: 'chapter-b' }, { time: 51, title: 'chapter-c' }, { title: 'chapter-d' }, ], markers: [{ time: 15, title: 'title1', image: 'https://github.com/web-streaming/ppbar/blob/main/demo/m1.png?raw=true', size: [32, 34], }, { time: 30, title: 'title2', image: 'https://github.com/web-streaming/ppbar/blob/main/demo/m2.png?raw=true', size: [32, 34], }, { time: 55, title: 'title3', image: 'https://github.com/web-streaming/ppbar/blob/main/demo/m3.png?raw=true', size: [32, 34], }], heatMap: { points: [9592,9692,10063,41138,30485,23905,10966.5,10316.5,8533.5,7249,7181,6813,5929,18046.5,8817,3684.5], defaultDuration: 3.75 }, thumbnail: { images: ['https://github.com/woopen/nplayer/blob/main/website/static/img/M1.jpg?raw=true'] } }) const MyProgress = { el: div, init(player) { player.on(EVENT.DURATION_CHANGE, () => progress.updateDuration(player.duration)) player.on(EVENT.TIME_UPDATE, () => progress.updatePlayed(player.currentTime)) player.on(EVENT.PROGRESS, () => progress.updateBuffer(player.buffered.end(player.buffered.length - 1))) // 監聽播放器事件,關聯到 ppbar } } const player = new Player({ src: 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4', controls: [ ['play', 'volume', 'time', 'spacer', 'settings', 'web-fullscreen', 'fullscreen'], [MyProgress] ] }) progress.on(BAR_EVENT.DRAGEND, (time) => { player.currentTime = time }) progress.on(BAR_EVENT.MARKER_CLICK, (marker) => { player.currentTime = marker.time }) // 將 ppbar 事件關聯到 player player.mount(document.body) 效果如下。 API 配置 參數名 類型 描述 live boolean 是否是直播模式 duration number 進度條的時長 rotate 0 | 90 | -90 進度條要被旋轉的度數 dot HTMLElement | string | true 進度條標記點,true 表示使用默認 chapters {time?:number,title:string}[] 章節,time 是一個章節的結束時間,最後一個章節可以不設置 heatMap Object 熱力圖 heatMap.points (number|{duration?:number;score:number})[] 熱力圖分數點 heatMap.defaultDuration Object 默認單點時長 heatMap.hoverShow Object 是否要 hover 的時候才展示 markers Object[] 標記數組 markers[].time number 必填,標記對應的時間點 markers[].title string 標記點標題 markers[].el HTMLElement 標記點自定義 DOM 元素 markers[].image string 標記點圖片 markers[].size number[] 標記點圖片大小 thumbnail Object | false 縮略圖,false 爲不展示 thumbnail.start number 縮略圖開始時間,默認 0 thumbnail.gap number 每個縮略圖的時長,默認 10 thumbnail.row number 雪碧圖由幾行圖片組成,默認 5 thumbnail.col number 雪碧圖由幾列圖片組成,默認 5 thumbnail.width number 縮略圖寬度,默認 160 thumbnail.height number 縮略圖高度,默認 90 thumbnail.images string[] 縮略圖地址數組 屬性 屬性 類型 描述 el HTMLElement 進度條的 DOM 元素 config ProgressConfig 進度條參數 rect Rect 進度條盒子大小,類似 DOMRect duration number 時長,默認 0 rotate number 被旋轉的角度,默認 0 live boolean 是否是直播模式 方法 updateSize() 更新進度條大小,一般在修改容器大小位置時調用,防止進度條中元素對不齊。 updateSize(): void; updateRotate() 更新進度條旋轉角度。 updateRotate(r: 0 | 90 | -90): void updateDuration() 更新時長 updateDuration(duration?: number): void updateConfig() 更新進度條參數,參數可以部分更新,一般在切換視頻時使用。 updateConfig(config?: Partial<ProgressConfig>): void updateMarkerPosition() 更新標記點的位置,在直播中隨着時間推移可以標記點位置會發生變化,可以使用該函數。參數是相對時間,表示所有標記點都移動多少時間距離。 updateMarkerPosition(relativeTime: number): void updatePlayed() 更新播放進度。 updatePlayed(time: number): void updateBuffer() 更新緩存進度。 updateBuffer(time: number): void updateHover() 更新 hover 進度。 updateHover(time: number): void destroy() 銷燬進度條。 destroy(): void 事件 事件名 描述 markerClick 標記點被點擊,參數是標記點對象 dragging 正在拖動進度條,頻繁觸發 dragend 拖動結束 mousemove 鼠標在進度條上移動,頻繁觸發 mouseleave 鼠標離開