Vue使用EasyPlayerPro播放本地MP4視頻
加載本地mp4需指定協(xié)議http://localhost:5100/(如 http:、https:、webrtc:、ws: 等)來正確處理媒體流。
目錄結(jié)構(gòu)
├── public/
│ ├──static
│ │ ├── video.mp4
├── components/
│ ├── EasyWebRTC.vue
├── views/
│ ├── test/
│ │ ├── index.vue
組件封裝
<template> <div class="easy-player-container"> <!-- 為每個(gè)播放器容器添加唯一的類 --> <div id="player_box1" class="player-box"></div> </div> </template> <script> /* global EasyPlayerPro */ export default { name: 'EasyPlayerPro', props: { initialConfig: { type: Object, default: () => ({}), }, }, data () { return { player: '', playerInstances: {}, // 存儲(chǔ)播放器實(shí)例 config: { hasAudio: true, isLive: true, MSE: false, WCS: false, demuxType: 'auto', ...this.initialConfig, }, }; }, methods: { setVideoUrl (url, id, changeId) { const resolveUrl = (url) => { if ( url.startsWith('http:') || url.startsWith('https:') || url.startsWith('webrtc:') || url.startsWith('ws:') || url.startsWith('wss:') || url.startsWith('wt:') || url.startsWith('artc:') ) { return url; } const baseUrl = `${window.location.protocol}//${window.location.host}`; return `${baseUrl}${url}`; }; // 轉(zhuǎn)換 URL const resolvedUrl = resolveUrl(url); console.log(`解析后的 URL: ${resolvedUrl}`); if (!resolvedUrl) { console.error('URL 不能為空'); return; } // 動(dòng)態(tài)設(shè)置 demuxType let demuxType = 'auto'; // 默認(rèn)值 if (url.endsWith('.mp4')) { demuxType = 'mp4'; } else if (url.startsWith('webrtc://')) { demuxType = 'native'; // WebRTC 流 } else if (url.startsWith('ws://') || url.startsWith('wss://')) { demuxType = 'flv'; // WebSocket 流通常為 FLV } // 更新播放器配置 this.config = { ...this.config, demuxType, isLive: url.startsWith('webrtc://') || url.includes('live'), }; const player = this.playerInstances[id]; if (player) { player.play(resolvedUrl).catch((e) => { console.error(`播放失敗 (播放器${id}):`, e); this.$emit('play-error', e); }); } else { // 使用箭頭函數(shù)確保上下文 this.$nextTick(() => { this.createPlayer(id, resolvedUrl); }); } }, createPlayer (id, url) { const container = document.getElementById(id); if (!container) { console.error(`未找到容器, ID: ${id}`); return; } const player = new EasyPlayerPro(container, { demuxType: this.config.demuxType || 'auto', autoplay: this.config.autoplay || true, muted: this.config.muted || true, isLive: this.config.isLive || true, }); player .play(url) .then(() => { console.log(`播放成功: ${url}`); this.$emit('play-started', id); }) .catch((e) => { console.error(`播放失敗: ${e.message || e}`, e); this.$emit('play-error', { id, error: e }); }); // 添加事件監(jiān)聽器:循環(huán)播放 player.on('ended', () => { console.log(`播放結(jié)束,準(zhǔn)備循環(huán)播放: ${url}`); player.play(url).catch((e) => { console.error(`循環(huán)播放失敗: ${e.message || e}`, e); }); }); this.playerInstances[id] = player; // 添加事件解除靜音 document.addEventListener('click', () => { player.unmute(); // 用戶交互后解除靜音 }); }, // 銷毀所有播放器實(shí)例 destroyAllPlayers () { Object.keys(this.playerInstances).forEach(id => { this.destroyPlayer(id); }); }, // 銷毀單個(gè)播放器實(shí)例 destroyPlayer (id) { const player = this.playerInstances[id]; if (player) { player.destroy(); delete this.playerInstances[id]; } }, handleUnmute () { Object.values(this.playerInstances).forEach((player) => { if (player) { player.unmute(); } }); }, }, beforeUnmount () { // 銷毀所有播放器實(shí)例 this.destroyAllPlayers(); // 清除全局事件監(jiān)聽器 document.removeEventListener('click', this.handleUnmute); }, }; </script> <style scoped> .easy-player-container { width: 100%; background: #000; height: 100%; position: relative; } .player-box { background: #000; } </style>
應(yīng)用:
<template> <div class="video-content"> <EasyWebRTC ref="baseVideoRef" :initialConfig="{ demuxType: 'native', isLive: false, hasAudio: true, autoplay: true, muted: true }"> </EasyWebRTC> <EasyWebRTC ref="videoRef" :initialConfig="{ demuxType: 'flv', isLive: true, hasAudio: true, }"></EasyWebRTC> </div> </template> <script setup> import { ref, onMounted, nextTick } from "vue"; import EasyWebRTC from "../components/EasyWebRTC.vue"; // 定義組件引用 const baseVideoRef = ref(null); const videoRef = ref(null); onMounted(() => { nextTick(() => { // 配置 baseVideoRef if (baseVideoRef.value) { const baseVideoUrl = "/video.mp4"; // 替換為實(shí)際的視頻文件路徑 const baseContainerId = "baseVideo"; try { baseVideoRef.value.setVideoUrl(baseVideoUrl, baseContainerId, baseContainerId); console.log("baseVideoRef:", baseVideoRef.value); // 修改 DOM 元素 ID const targetChild = baseVideoRef.value.$el?.firstElementChild; if (targetChild) { targetChild.id = baseContainerId; // 修改 ID console.log(`成功修改 baseVideo 的 ID 為: ${baseContainerId}`); } else { console.warn("未找到 baseVideoRef 的子節(jié)點(diǎn)"); } } catch (error) { console.error("設(shè)置 baseVideo URL 時(shí)出錯(cuò):", error); } } else { console.error("baseVideoRef 未掛載"); } // 配置 videoRef if (videoRef.value) { const videoUrl = "http://sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-360p.mp4"; const videoContainerId = "video"; try { videoRef.value.setVideoUrl(videoUrl, videoContainerId, videoContainerId); // 修改父元素中的 ID const parentElement = document.querySelector(".video-content"); if (parentElement) { const targetChild = parentElement.querySelector("#player_box1"); if (targetChild) { targetChild.id = videoContainerId; // 修改 ID console.log(`成功修改 video 的 ID 為: ${videoContainerId}`); } else { console.warn("未找到 ID 為 'player_box1' 的子節(jié)點(diǎn)"); } } else { console.warn("未找到父元素 .video-content"); } } catch (error) { console.error("設(shè)置 video URL 時(shí)出錯(cuò):", error); } } else { console.error("videoRef 未掛載"); } }); }); </script> <style> .video-content { width: 100%; height: 100vh; display: flex; flex-direction: column; justify-content: space-between; } </style>
效果:
到此這篇關(guān)于Vue使用EasyPlayerPro播放本地MP4視頻的文章就介紹到這了,更多相關(guān)Vue EasyPlayerPro播放視頻內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue keep-alive 動(dòng)態(tài)刪除組件緩存的例子
今天小編就為大家分享一篇vue keep-alive 動(dòng)態(tài)刪除組件緩存的例子,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11vue-cli構(gòu)建的項(xiàng)目如何手動(dòng)添加eslint配置
這篇文章主要介紹了vue-cli構(gòu)建的項(xiàng)目如何手動(dòng)添加eslint配置,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04vue之el-menu-item如何更改導(dǎo)航菜單欄選中的背景顏色
這篇文章主要介紹了vue之el-menu-item如何更改導(dǎo)航菜單欄選中的背景顏色問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05Vue中使用event的坑及解決event is not defined
這篇文章主要介紹了Vue中使用event的坑及解決event is not defined,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03vue-router之nuxt動(dòng)態(tài)路由設(shè)置的兩種方法小結(jié)
今天小編就為大家分享一篇vue-router之nuxt動(dòng)態(tài)路由設(shè)置的兩種方法小結(jié),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09