Vue實(shí)現(xiàn)視頻播放vue-video-player、dplayer方式
一、vue-video-player
1、安裝及引入
// 安裝 npm install vue-video-player@5.0.1 --save
// 在main.js中全局引入 import VideoPlayer from 'vue-video-player/src'; import 'vue-video-player/src/custom-theme.css' import 'video.js/dist/video-js.css' Vue.use(VideoPlayer)
2、一些常見(jiàn)的屬性、方法和事件
屬性:
videoWidth
:返回音頻/視頻源文件本身的寬度。videoHeight
:返回音頻/視頻源文件本身的高度。audioTracks
:返回表示可用音頻軌道的 AudioTrackList 對(duì)象。autoplay
:設(shè)置或返回是否在加載完成后隨即播放音頻/視頻。buffered
:返回表示音頻/視頻已緩沖部分的 TimeRanges 對(duì)象。controller
:返回表示音頻/視頻當(dāng)前媒體控制器的 MediaController 對(duì)象。controls
:設(shè)置或返回音頻/視頻是否顯示控件(比如播放/暫停等)。crossOrigin
:設(shè)置或返回音頻/視頻的 CORS 設(shè)置。currentSrc
:返回當(dāng)前音頻/視頻的URL。currentTime
:設(shè)置或返回音頻/視頻中的當(dāng)前播放位置(以秒計(jì))。defaultMuted
:設(shè)置或返回音頻/視頻默認(rèn)是否靜音。defaultPlaybackRate
:設(shè)置或返回音頻/視頻的默認(rèn)播放速度。duration
:返回當(dāng)前音頻/視頻的長(zhǎng)度(以秒計(jì))。ended
:返回音頻/視頻的播放是否已結(jié)束。error
:返回表示音頻/視頻錯(cuò)誤狀態(tài)的 MediaError 對(duì)象。loop
:設(shè)置或返回音頻/視頻是否應(yīng)在結(jié)束時(shí)重新播放。mediaGroup
:設(shè)置或返回音頻/視頻所屬的組合(用于連接多個(gè)音頻/視頻元素)。muted
:設(shè)置或返回音頻/視頻是否靜音。networkState
:返回音頻/視頻的當(dāng)前網(wǎng)絡(luò)狀態(tài)。paused
:設(shè)置或返回音頻/視頻是否暫停。playbackRate
:設(shè)置或返回音頻/視頻播放的速度。played
:返回表示音頻/視頻已播放部分的 TimeRanges 對(duì)象。preload
:設(shè)置或返回音頻/視頻是否應(yīng)該在頁(yè)面加載后進(jìn)行加載。readyState
:返回音頻/視頻當(dāng)前的就緒狀態(tài)。seekable
:返回表示音頻/視頻可尋址部分的 TimeRanges 對(duì)象。seeking
:返回用戶是否正在音頻/視頻中進(jìn)行查找。src
:設(shè)置或返回音頻/視頻元素的當(dāng)前來(lái)源。startDate
:返回表示當(dāng)前時(shí)間偏移的 Date 對(duì)象。textTracks
:返回表示可用文本軌道的 TextTrackList對(duì)象。videoTracks
:返回表示可用視頻軌道的 VideoTrackList 對(duì)象。volume
:設(shè)置或返回音頻/視頻的音量。
方法
addTextTrack()
:向音頻/視頻添加新的文本軌道。canPlayType()
:檢測(cè)瀏覽器是否能播放指定的音頻/視頻類(lèi)型。load()
:重新加載音頻/視頻元素。play()
:開(kāi)始播放音頻/視頻。pause()
:暫停當(dāng)前播放的音頻/視頻。
事件
abort
:當(dāng)音頻/視頻的加載已放棄時(shí)觸發(fā)。canplay
:當(dāng)瀏覽器可以開(kāi)始播放音頻/視頻時(shí)觸發(fā)。canplaythrough
:當(dāng)瀏覽器可在不因緩沖而停頓的情況下進(jìn)行播放時(shí)觸發(fā)。durationchange
:當(dāng)音頻/視頻的時(shí)長(zhǎng)已更改時(shí)觸發(fā)。emptied
:當(dāng)目前的播放列表為空時(shí)觸發(fā)。ended
:當(dāng)目前的播放列表已結(jié)束時(shí)觸發(fā)。error
:當(dāng)在音頻/視頻加載期間發(fā)生錯(cuò)誤時(shí)觸發(fā)。loadeddata
:當(dāng)瀏覽器已加載音頻/視頻的當(dāng)前幀時(shí)觸發(fā)。loadedmetadata
:當(dāng)瀏覽器已加載音頻/視頻的元數(shù)據(jù)時(shí)觸發(fā)。loadstart
:當(dāng)瀏覽器開(kāi)始查找音頻/視頻時(shí)觸發(fā)。pause
:當(dāng)音頻/視頻已暫停時(shí)觸發(fā)。play
:當(dāng)音頻/視頻已開(kāi)始或不再暫停時(shí)觸發(fā)。playing
:當(dāng)音頻/視頻在因緩沖而暫?;蛲V购笠丫途w時(shí)觸發(fā)。progress
:當(dāng)瀏覽器正在下載音頻/視頻時(shí)觸發(fā)。ratechange
:當(dāng)音頻/視頻的播放速度已更改時(shí)觸發(fā)。seeked
:當(dāng)用戶已移動(dòng)/跳躍到音頻/視頻中的新位置時(shí)觸發(fā)。seeking
:當(dāng)用戶開(kāi)始移動(dòng)/跳躍到音頻/視頻中的新位置時(shí)觸發(fā)。stalled
:當(dāng)瀏覽器嘗試獲取媒體數(shù)據(jù),但數(shù)據(jù)不可用時(shí)觸發(fā)。suspend
:當(dāng)瀏覽器刻意不獲取媒體數(shù)據(jù)時(shí)觸發(fā)。timeupdate
:當(dāng)目前的播放位置已更改時(shí)觸發(fā)。volumechange
:當(dāng)音量已更改時(shí)觸發(fā)。waiting
:當(dāng)視頻由于需要緩沖下一幀而停止時(shí)觸發(fā)。
3、關(guān)于不可快進(jìn)、定位到上次播放位置的基本使用
完整代碼如下:
<template> <div class="player"> <video-player ref="videoPlayer" class="player-video" :playsinline="false" :options="playOptions" @ready="onPlayerReady" @play="onPlayerPlay($event)" @pause="onPlayerPause($event)" @ended="onPlayerEnd($event)" @waiting="onPlayerWaiting($event)" @playing="onPlayerPlaying($event)" @loadeddata="onPlayerLoadeddata($event)" @timeupdate="onPlayerTimeupdate($event)" @statechanged="playerStateChanged($event)" /> </div> </template> <script> export default { props: { path: { // 傳入的地址 type: String, default: "", }, lastTime: { // 傳入的上次播放位置 type: Number, default: 0, }, }, components: {}, data() { return { playedTime: this.lastTime, currentTime: 0, maxTime: 0, playOptions: { height: "200px", width: "100%", playbackRates: [1.0], // 可選的播放速度 autoplay: true, // 如果為true,瀏覽器準(zhǔn)備好時(shí)開(kāi)始回放 muted: false, // 默認(rèn)情況下靜音播放 loop: false, // 是否視頻一結(jié)束就重新開(kāi)始 preload: "auto", // 建議瀏覽器在<video>加載元素后是否應(yīng)該開(kāi)始下載視頻數(shù)據(jù),auto瀏覽器選擇最佳行為,立即開(kāi)始加載視頻(如果瀏覽器支持) language: "zh-CN", aspectRatio: "16:9", // 將播放器置于流暢模式,并在計(jì)算播放器的動(dòng)態(tài)大小時(shí)使用該值,值應(yīng)該代表一個(gè)比例 - 用冒號(hào)分隔的兩個(gè)數(shù)字(例如"16:9"或"4:3") fluid: true, // 當(dāng)true時(shí),Video.js player將擁有流體大小,換句話說(shuō),它將按比例縮放以適應(yīng)其容器 sources: [ { type: "video/mp4", // 類(lèi)型 src: require("./1.mp4"), // url地址,在使用本地的資源時(shí),需要用require()引入,否則控制臺(tái)會(huì)報(bào)錯(cuò) }, ], poster: "./gcy-logo-200.png", // 設(shè)置封面地址 notSupportedMessage: "此視頻暫無(wú)法播放,請(qǐng)稍后再試", // 允許覆蓋Video.js無(wú)法播放媒體源時(shí)顯示的默認(rèn)信息 controlBar: { currentTimeDisplay: true, progressControl: true, // 是否顯示進(jìn)度條 playbackRateMenuButton: true, // 是否顯示調(diào)整播放倍速按鈕 timeDivider: true, // 當(dāng)前時(shí)間和持續(xù)時(shí)間的分隔符 durationDisplay: true, // 顯示持續(xù)時(shí)間 remainingTimeDisplay: true, // 是否顯示剩余時(shí)間功能 fullscreenToggle: true, // 是否顯示全屏按鈕 }, }, }; }, computed: { }, mounted() { this.getData() // 調(diào)用獲取地址的接口,然后修改播放器配置中的src屬性 }, methods: { // 準(zhǔn)備好了 onPlayerReady() { console.log("準(zhǔn)備好了"); }, // 視頻播放 onPlayerPlay(player) { console.log('播放了'); console.log(player); let playTime = 0; if ( Number(Math.floor(this.playedTime)) === Number(Math.floor(player.duration())) ) { this.playedTime = 0; playTime = 0; } else if ( Number(Math.floor(player.currentTime())) !== Number(Math.floor(this.playedTime)) ) { playTime = this.playedTime; player.currentTime(playTime) } }, // 視頻暫停的 onPlayerPause(player) { console.log('暫停中'); console.log(player); this.playedTime = player.currentTime(); }, // 視頻播放完 onPlayerEnd(player) { console.log('播放結(jié)束了'); console.log(player); }, // DOM元素上的readyState更改導(dǎo)致播放停止 onPlayerWaiting(player) { console.log("播放停止中"); console.log(player); }, // 視頻已開(kāi)始播放 onPlayerPlaying(player) { console.log("開(kāi)始播放了"); console.log(player); }, // 當(dāng)播放器在當(dāng)前播放位置下載數(shù)據(jù)時(shí)觸發(fā) onPlayerLoadeddata(player) { console.log("開(kāi)始下載數(shù)據(jù)"); console.log(player); }, // 當(dāng)前播放位置發(fā)生變化時(shí)觸發(fā) onPlayerTimeupdate(player) { console.log("播放位置變化了"); console.log(player); let timeDisplay = player.currentTime(); if (timeDisplay - this.currentTime > 1) { player.currentTime(this.currentTime > this.maxTime ? this.currentTime : this.maxTime); } this.currentTime = player.currentTime(); this.maxTime = this.currentTime > this.maxTime ? this.currentTime : this.maxTime; }, //播放狀態(tài)改變 playerStateChanged(playerCurrentState) { console.log("播放狀態(tài)變化了"); console.log(playerCurrentState); }, // 手動(dòng)暫停視頻的播放 pause() { // 視頻播放器的方法調(diào)用,要使用this.$refs.videoPlayer.player這個(gè)對(duì)象去調(diào)用 this.$refs.videoPlayer.player.pause() } }, }; </script> <style lang="scss" scoped> </style>
注意:
vue-video-player 是基于 video.js 實(shí)現(xiàn)的,所以 api 地址:Video.js API docs
調(diào)用的時(shí)候使用這個(gè)對(duì)象進(jìn)行操作:this.$refs.videoPlayer.player
二、dplayer
1、安裝
// 安裝 npm install dplayer --save
2、關(guān)于不可快進(jìn)、定位到上次播放位置的基本使用
完整代碼如下:
// 直接在組件中引入 // dplayer.vue <template> <div :id="flag"></div> </template> <script> import DPlayer from "dplayer"; export default { props: { flag: { // 每個(gè)dplayer的id不可以重復(fù) type: String, default: "", }, lastTime: { // 上次播放到的時(shí)間 type: Number, default: 0, }, }, data() { return { dp: null, playedTime: this.lastTime, }; }, mounted() {}, methods: { async init(id) { let currentTime = 0; let maxTime = 0; let res = await api(); // 調(diào)用獲取視頻的地址 let src = res.data.path; this.dp = new DPlayer({ container: document.getElementById(this.flag), // 播放器容器元素 hotkey: true, // 開(kāi)啟熱鍵,支持快進(jìn)、快退、音量控制、播放暫停,默認(rèn)是true lang: "zh-cn", // 可選值:'en'、'zh-cn'、'zh-tw' screenshot: false, // 開(kāi)啟截圖,如果開(kāi)啟,視頻和視頻封面需要允許跨域 playbackSpeed: [0.75, 1, 1.25, 1.5, 2, 3], // 可選的視頻播放倍速,可以設(shè)置自定義的數(shù)組 video: { // 視頻信息,更多可以參考官網(wǎng):https://dplayer.diygod.dev/zh/guide.html url: src, // 視頻地址 }, }); // 監(jiān)聽(tīng)視頻開(kāi)始播放 this.dp.on("play", () => { let playTime = 0; if ( Number(Math.floor(this.playedTime)) === Number(Math.floor(this.dp.video.duration)) ) { this.playedTime = 0; playTime = 0; } else if ( Number(Math.floor(this.dp.video.currentTime)) !== Number(Math.floor(this.playedTime)) ) { playTime = this.playedTime; this.dp.seek(playTime); } }); // 監(jiān)聽(tīng)視頻暫停 this.dp.on("pause", () => { this.playedTime = this.dp.video.currentTime; }); // 設(shè)置不可以快進(jìn)(timeupdate:當(dāng)前播放位置更改時(shí)觸發(fā)) this.dp.on("timeupdate", () => { let timeDisplay = this.dp.video.currentTime; if (timeDisplay - currentTime > 1) { this.dp.video.currentTime = currentTime > maxTime ? currentTime : maxTime; this.dp.notice("禁止快進(jìn)", 2000); } currentTime = this.dp.video.currentTime; maxTime = currentTime > maxTime ? currentTime : maxTime; }); // 快進(jìn)的提示,在禁止快進(jìn)的提醒存在時(shí)不顯示 this.dp.on("notice_show", function (e) { var text = e.innerHTML; if ( "禁止快進(jìn)" != text && (text.indexOf("快進(jìn)") > -1 || text.indexOf("快退") > -1) ) { e.style.display = "none"; } }); }, }, }; </script> <style lang="scss" scoped> </style>
想要了解更多的功能可以參考dplayer的官網(wǎng):DPlayer
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue實(shí)現(xiàn)購(gòu)物車(chē)詳情頁(yè)面的方法
這篇文章主要介紹了Vue實(shí)戰(zhàn)之購(gòu)物車(chē)詳情頁(yè)面的實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08vue子元素綁定的事件, 阻止觸發(fā)父級(jí)上的事件處理方式
這篇文章主要介紹了vue子元素綁定的事件, 阻止觸發(fā)父級(jí)上的事件處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11npm安裝vue@cli報(bào)錯(cuò)的簡(jiǎn)單處理方式
最近工作中遇到了報(bào)錯(cuò),現(xiàn)在將解決的辦法分享給大家,下面這篇文章主要給大家介紹了關(guān)于npm安裝vue@cli報(bào)錯(cuò)的簡(jiǎn)單處理方式,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12vue + typescript + 極驗(yàn)登錄驗(yàn)證的實(shí)現(xiàn)方法
這篇文章主要介紹了vue + typescript + 極驗(yàn) 登錄驗(yàn)證的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06vue實(shí)現(xiàn)用v-bind給src和href賦值
這篇文章主要介紹了vue實(shí)現(xiàn)用v-bind給src和href賦值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04vue + element-ui實(shí)現(xiàn)簡(jiǎn)潔的導(dǎo)入導(dǎo)出功能
Element-UI是餓了么前端團(tuán)隊(duì)推出的一款基于Vue.js 2.0 的桌面端UI框架,手機(jī)端有對(duì)應(yīng)框架是 Mint UI,下面這篇文章主要給大家介紹了關(guān)于利用vue + element-ui如何實(shí)現(xiàn)簡(jiǎn)潔的導(dǎo)入導(dǎo)出功能的相關(guān)資料,需要的朋友可以參考下。2017-12-12vue實(shí)現(xiàn)添加標(biāo)簽demo示例代碼
本篇文章主要介紹了vue實(shí)現(xiàn)添加標(biāo)簽demo示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01Ant Design Upload 文件上傳功能的實(shí)現(xiàn)
這篇文章主要介紹了Ant Design Upload 文件上傳功能的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04