Vue使用EasyPlayerPro播放本地MP4視頻
加載本地mp4需指定協(xié)議http://localhost:5100/(如 http:、https:、webrtc:、ws: 等)來正確處理媒體流。
目錄結構
├── public/
│ ├──static
│ │ ├── video.mp4
├── components/
│ ├── EasyWebRTC.vue
├── views/
│ ├── test/
│ │ ├── index.vue
組件封裝
<template>
<div class="easy-player-container">
<!-- 為每個播放器容器添加唯一的類 -->
<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: {}, // 存儲播放器實例
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}`;
};
// 轉換 URL
const resolvedUrl = resolveUrl(url);
console.log(`解析后的 URL: ${resolvedUrl}`);
if (!resolvedUrl) {
console.error('URL 不能為空');
return;
}
// 動態(tài)設置 demuxType
let demuxType = 'auto'; // 默認值
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(`播放結束,準備循環(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(); // 用戶交互后解除靜音
});
},
// 銷毀所有播放器實例
destroyAllPlayers () {
Object.keys(this.playerInstances).forEach(id => {
this.destroyPlayer(id);
});
},
// 銷毀單個播放器實例
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 () {
// 銷毀所有播放器實例
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>應用:
<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"; // 替換為實際的視頻文件路徑
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é)點");
}
} catch (error) {
console.error("設置 baseVideo URL 時出錯:", 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é)點");
}
} else {
console.warn("未找到父元素 .video-content");
}
} catch (error) {
console.error("設置 video URL 時出錯:", error);
}
} else {
console.error("videoRef 未掛載");
}
});
});
</script>
<style>
.video-content {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: space-between;
}
</style>效果:

到此這篇關于Vue使用EasyPlayerPro播放本地MP4視頻的文章就介紹到這了,更多相關Vue EasyPlayerPro播放視頻內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue keep-alive 動態(tài)刪除組件緩存的例子
今天小編就為大家分享一篇vue keep-alive 動態(tài)刪除組件緩存的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11
vue之el-menu-item如何更改導航菜單欄選中的背景顏色
這篇文章主要介紹了vue之el-menu-item如何更改導航菜單欄選中的背景顏色問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05
Vue中使用event的坑及解決event is not defined
這篇文章主要介紹了Vue中使用event的坑及解決event is not defined,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03
vue-router之nuxt動態(tài)路由設置的兩種方法小結
今天小編就為大家分享一篇vue-router之nuxt動態(tài)路由設置的兩種方法小結,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09

