场景:
vue 实现服务器本地视频的播放
功能:
- 展示本地视频列表
- 播放选定的视频文件
遇到的坑:
-
确定当前 vue 项目的版本。毕竟从 Vue 2.x 开始就 static 目录换成 public。
-
指定视频文件存放的路径。如果是固定几个视频文件,可以考虑放在 assets 目录下。assets 目录会被 webpack 当做模块依赖处理,项目构建后,只能在已知的视频文件之间动态切换。如果是需要增加、删除、修改的视频文件,则需要放在 static 目录或者是__public__目录下。assets 目录下视频文件切换的方法示例:
<script> import 'video.js/dist/video-js.css' import { videoPlayer } from 'vue-video-player' export default { components: { "video-player" : videoPlayer }, name:"VPlayer", data() { return { playerOptions: { // 视频配置项 muted: true, language: 'zh', sources: [{ type: "video/mp4", src: require('../assets/video/810020027.mp4'), }], }, message:'', } }, methods: { get_url(){ // 改变视频 let video_path = '../assets/video/' + String(this.message) this.playerOptions.sources[0].src = this.message; }, } } </script>
-
视频格式的支持。在将视频转换为 .mp4 格式文件时,需要指定视频的编码格式为h264,因此要明确视频的编码格式,否则vue-dplayer和vue-video-player会无法播放转换后的mp4视频文件。此次项目中需要转换的是 .h264 文件,使用ffmpeg进行视频格式转换时,根据当前环境使用不同的转换命令:
-
linux 环境中:
ffmpeg -r 10 -i 1637742863.h264 -vcodec h264 -y 1202s7n.mp4
-
windows 环境中:
ffmpeg -r 10 -i 1637742863.h264 -vcodec h264_qsv -y 1202s7n.mp4
-
实现:
1. 将 vue dplayer 使用自定义为 VideoPlayer 组件:
<template xmlns="http://www.w3.org/1999/html">
<div id="VideoPlayer">
<p>
<span>
<el-select v-model="video_path" @change="show_btn" @focus="get_video_list" @clear="show_btn" clearable placeholder="请选择">
<el-option
v-for="item in video_list"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</span>
<span>
<el-button :disabled=btn_status class="btnplayer" @click="switchHandle">
<span>切换视频</span>
</el-button>
</span>
<span style="font-size: 18px">当前视频:{{options.video.url}}</span>
</p>
<d-player :options="options"
@play="play"
ref="player">
</d-player>
</div>
</template>
<script>
import VueDPlayer from "vue-dplayer"
import "vue-dplayer/dist/vue-dplayer.css"
import {networkErr} from "../../Utils";
export default {
name : "VideoPlayer",
components : {
'd-player' : VueDPlayer,
},
data () {
return {
options : {
container: document.getElementById('VideoPlayer'),
video : {
url: 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4',
type: 'auto',
defaultQuality : 0,
},
theme : '#FADFA3',
loop : true,
lang : 'zh-cn',
preload : 'auto',
volume : 0.7,
autoplay : false,
player : null,
},
video_path : null,
video_list : [],
btn_status : true,
}
},
mounted () {
console.log(this.$refs.player)
this.player = this.$refs.player.dp;
this.get_video_list();
},
methods:{
// 切换视频按钮操作状态
show_btn(){
if (this.video_path == null | this.video_path == ''){
this.btn_status = true;
} else {
this.btn_status = false;
}
console.log('btn 状态:', this.btn_status)
console.log('video_path :', this.video_path)
},
// 视频列表, 调用后端接口 video/download,获取本地视频列表
get_video_list () {
this.video_list = [];
let url = this.$store.state.host + 'video/download'
this.$axios.get(url)
.then((res) => {
if (res.data.code == 0) {
console.log(res.data)
let videos = res.data.data;
if (videos.length > 0) {
videos.forEach((video) => {
// 获取视频名称
let video_name = video.split('/').pop()
// 将组合为 el-select 列表数据,label视频名,value视频路径
this.video_list.push({label : video_name, value : video})
});
} else {
this.$message.error('文件下载失败. ' + res.data.msg);
}
console.log(this.video_list)
}
}).catch((err) => {
this.$message.error(networkErr);
console.log(err);
})
},
// 播放视频
play () {
console.log('play callback')
console.log(this.player)
},
// 切换视频
switchHandle () {
if (this.video_path != null) {
console.debug('切换视频为: ' + this.video_path)
this.player.switchVideo({
// 改变当前视频路径为 vue 的静态资源存放路径.
// vue 2.x :video/xx.mp4;
// vue 1.x : static/video/xx.mp4
url : this.video_path.substr(this.video_path.indexOf('static')),
type : 'atuo'
})
this.options.video.url = this.video_path
}
},
}
}
</script>
<style scoped>
.dplayer {
/*width: 800px;*/
margin: 10px auto;
}
</style>
效果:
2. 将 vue-video-player 的使用自定义为 VideoPlayer 组件
和 dplayer 用法类似:
<template>
<div>
<input v-model="message" placeholder="edit me">
<button @click="get_url">
获取视频地址
</button>
<video-player class="video-player-box"
ref="videoPlayer"
:options="playerOptions"
:playsinline="true"
customEventName="customstatechangedeventname"
@play="onPlayerPlay($event)">
</video-player>
</div>
</template>
<script>
import 'video.js/dist/video-js.css'
import { videoPlayer } from 'vue-video-player'
export default {
components: {
"video-player" : videoPlayer
},
name:"VPlayer",
data() {
return {
playerOptions: {
// videojs options
muted: true,
language: 'en',
playbackRates: [0.7, 1.0, 1.5, 2.0],
sources: [{
type: "video/mp4",
src: "https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm"
}],
},
message:'',
publicPath: process.env.BASE_URL,
}
},
computed: {
player() {
return this.$refs.videoPlayer.player
}
},
methods: {
// 获取的视频地址
get_url(){
let video_path = 'video/' + String(this.message)
console.log(video_path)
this.playerOptions.sources[0].src = video_path;
console.log(this.playerOptions.sources)
},
// listen event
onPlayerPlay(player) {
console.log('player play!', player)
},
}
}
</script>
<style scoped>
</style>