<template>
|
<div>
|
<div v-if="!this.$attrs.showTar">
|
正在播放: <span> {{playingVideoData.title}} </span>
|
</div>
|
<div class="myVideo fade" v-bind:class="{disabledPointer:disabledPointer}">
|
<div id="videoPlay" ref="myVdeoPlay"></div>
|
</div>
|
<div style="border-radius: 0 0 4px 4px;" v-if="!this.$attrs.showTar">
|
|
<div style="padding: 10px 0px;">
|
音量 :
|
<a-slider v-model="volumeInit" :default-value="0.1" :step="0.1" :max="1" @change="changeVolume" />
|
</div>
|
<div style="padding: 10px 0px;">
|
播放进度 : {{Math.floor(currentTime/60)}}:{{Math.floor(currentTime%60)}} /
|
{{Math.floor(duration/60)}}:{{Math.floor(duration%60)}}
|
<a-slider v-model="currentTime" :max="duration" @afterChange="changeTime" />
|
</div>
|
|
<a-collapse activeKey="playHistory">
|
<a-collapse-panel key="playHistory" header="播放记录">
|
<div v-for="(item,index) in playHistory">
|
<div v-if="index==0">
|
<a-tooltip placement="bottomRight" title="播放/暂停">
|
<div @click="togglePlay" class="playItem">
|
{{item.title}}
|
<span v-if="!isPlaying " class="myTip">(已暂停)</span>
|
<a-icon type="youtube" class="playIcon "
|
v-bind:class="{ activeElement: isPlaying }" />
|
</div>
|
</a-tooltip>
|
</div>
|
<div v-else>
|
<div @click="swichPlay(item.id)" class="playItem">
|
<a-tooltip placement="bottomRight" title="切换播放">
|
<div>
|
{{item.title}}
|
</div>
|
</a-tooltip>
|
</div>
|
</div>
|
</div>
|
</a-collapse-panel>
|
</a-collapse>
|
</div>
|
</div>
|
</template>
|
|
|
<script>
|
import Hls from 'hls.js'
|
import DPlayer from 'dplayer'
|
import myConstant from "../../config/myConstant.js"
|
|
export default {
|
data() {
|
return {
|
disabledPointer: false,
|
dp: null,
|
hls: null,
|
playHistory: [],
|
playRecordIds: [],
|
volumeInit: 0.1,
|
isPlaying: false,
|
swichLock: false,
|
currentTime: 0,
|
duration: 0,
|
playingVideoData: {
|
pic: "",
|
url: "",
|
type: "normal",
|
title: "",
|
id: ""
|
},
|
}
|
},
|
mounted() {
|
//弹窗初始化后先不加载视频,等待手动播放
|
this.init();
|
var _this = this;
|
|
//调整音量
|
//_this.$message.success("模块加载完成,请注意音量是否合适..")
|
|
this.dp.volume(this.volumeInit, true, false);
|
|
this.dp.on('pause', function() {
|
_this.$message.info("停止播放")
|
_this.isPlaying = false;
|
});
|
|
this.dp.on('play', function() {
|
_this.$message.info("开始播放..")
|
_this.isPlaying = true;
|
_this.duration = _this.dp.video.duration;
|
_this.currentTime = _this.dp.video.currentTime;
|
});
|
this.dp.on('timeupdate', function() {
|
//_this.$message.info("进度..")
|
_this.currentTime = _this.dp.video.currentTime;
|
});
|
this.dp.on('volumechange', function() {
|
_this.volumeInit = _this.dp.video.volume;
|
});
|
this.dp.on('loadedmetadata', function() {
|
_this.duration = _this.dp.video.duration;
|
});
|
this.dp.on('error', function() {
|
_this.duration = 0
|
_this.disabledPointer = true
|
});
|
|
},
|
methods: {
|
pauseMyVideo() {
|
this.dp.pause();
|
this.isPlaying = false;
|
},
|
togglePlay() {
|
this.dp.toggle();
|
this.isPlaying = !this.isPlaying;
|
},
|
changeVolume(value) {
|
this.dp.volume(value, true, false);
|
},
|
changeTime(time) {
|
this.dp.seek(time)
|
},
|
//切换视频源
|
swichPlay(videoId) {
|
|
if (this.swichLock) {
|
this.$message.info("切换太快啦,缓一缓..", 5)
|
return
|
}
|
|
if (videoId == this.playingVideoData.id) {
|
this.$message.info("同一个视频..", 1)
|
return
|
}
|
let tempData = this.playHistory.filter(item => item.id == videoId)[0]
|
|
this.$message.info("切换视频源..", 1)
|
this.swichLock = !this.swichLock;
|
|
|
this.startPlay(tempData)
|
|
setTimeout(() => {
|
this.swichLock = !this.swichLock;
|
}, 2000);
|
|
//通知父组件更换评论信息
|
this.$emit("swichPlay", tempData)
|
|
},
|
//调整播放记录
|
adjustOrder(videoData) {
|
if (this.playRecordIds.findIndex(id => id == videoData.id) == -1) {
|
//新纪录
|
this.playRecordIds.push(videoData.id)
|
this.playHistory.unshift(videoData)
|
} else {
|
//旧记录
|
this.playHistory = this.playHistory.filter(item => item.id != videoData.id);
|
this.playHistory.unshift(videoData)
|
}
|
},
|
//加载播放
|
startPlay(videoData) {
|
if (videoData == null || videoData == undefined) {
|
this.$message.error("无效资源..")
|
return
|
}
|
|
if (videoData.url != null && videoData.url != "" && videoData.url.endsWith("m3u8")) {
|
videoData.type = "customHls";
|
} else {
|
videoData.type = "normal";
|
}
|
|
if (videoData.pic === null || videoData.pic == ''){
|
videoData.pic = myConstant.defaultBGVideo;
|
}
|
|
//重要!!防止hls类型视频在切换后不停在后台缓存
|
if (this.hls != null) {
|
this.hls.destroy();
|
}
|
|
this.adjustOrder(videoData)
|
|
this.playingVideoData = videoData
|
|
this.disabledPointer = false;
|
this.isPlaying = false;
|
|
//重要!!防止hls类型视频在切换后不停在后台缓存
|
if (videoData.type == "customHls") {
|
this.hls = new Hls();
|
|
}
|
|
this.dp.notice("播放器加载完成..", 3)
|
|
this.dp.switchVideo(this.playingVideoData)
|
|
},
|
//播放器初始化
|
init() {
|
var _this = this;
|
this.dp = new DPlayer({
|
element: document.getElementById("videoPlay"),
|
//logo: "https://qczh-1252727916.cos.ap-nanjing.myqcloud.com/pic/273658f508d04d488414fd2b84c9f923.png", // 在视频左上角上打一个logo
|
hotkey: true, // 是否支持热键,调节音量,播放,暂停等
|
mutex: false, // 防止同时播放多个用户,在该用户开始播放时暂停其他用户
|
theme: "#b7daff", // 风格颜色,例如播放条,音量条的颜色
|
loop: false, // 是否自动循环
|
lang: "zh-cn", // 语言,'en', 'zh-cn', 'zh-tw'
|
// screenshot: true, // 是否允许截图(按钮),点击可以自动将截图下载到本地
|
preload: "metadata", // 自动预加载 'none', 'metadata', 'auto'
|
volume: _this.volumeInit, // 初始化音量
|
playbackSpeed: [2, 1, 0.5], //可选的播放速度,可自定义
|
contextmenu: [
|
//右键菜单
|
{
|
text: "b站",
|
link: "https://www.bilibili.com"
|
},
|
|
],
|
highlight: [
|
//进度条上的自定义时间标记
|
// 进度条时间点高亮
|
// {
|
// text: "10M",
|
// time: 60
|
// },
|
],
|
video: {
|
pic: _this.defalutImg, // 视频封面
|
// url: videoInfo.url,
|
//url: "http://t.inleft.com/share/mp3/EOPMusic%282%29.mp3",
|
type: "normal",
|
customType: {
|
customHls: function(video, player) {
|
//const hls = new Hls()
|
if (_this.hls != null) {
|
_this.hls.loadSource(video.src)
|
_this.hls.attachMedia(video)
|
|
// 监听Hls.Events.ERROR事件,
|
// DNS解析、下载超时,都会触发manifestLoadError错误
|
_this.hls.on(Hls.Events.ERROR, function(eventName, data) {
|
// 埋点上报,可以追踪data.details
|
// track()
|
_this.$message.error("hls加载异常", 5)
|
console.log(eventName);
|
console.log(data);
|
})
|
}
|
|
}
|
}
|
}
|
})
|
|
// 以下为隐藏一些作者的信息和视频播放源 如不需要可删除
|
// document.querySelector(".dplayer-menu").remove(); //隐藏右键菜单
|
|
document.querySelector(".dplayer-mask").remove();
|
document.querySelector(".dplayer-info-panel-item-url").remove(); //隐藏播放源
|
let length = document.querySelectorAll(".dplayer-menu-item").length;
|
document.querySelectorAll(".dplayer-menu-item")[length - 1].remove(); // 去掉作者信息
|
document.querySelectorAll(".dplayer-menu-item")[length - 2].remove(); // 去掉作者信息
|
},
|
}
|
|
}
|
</script>
|
<style lang="less" scoped>
|
.playItem {
|
border: 1px solid #d9d9d9;
|
padding: 10px;
|
border-radius: 5px;
|
margin: 10px;
|
transition: all .3s;
|
position: relative;
|
}
|
|
.mark {
|
border-radius: 14px;
|
background: #00000073;
|
width: 100%;
|
height: 100%;
|
pointer-events: none;
|
}
|
|
.playItem:hover {
|
//transform: scale(1.1) translate3d(0, 0, 0);
|
}
|
|
.playItem:active {
|
// transform: scale(0.75) translate3d(0, 0, 0);
|
box-shadow: 8px 8px 18px rgba(0, 0, 0, 0.1), -8px -8px 18px #ffffff;
|
}
|
|
|
.playIcon {
|
transform: scale(1.3);
|
position: absolute;
|
top: 35%;
|
right: 10px;
|
}
|
|
.myVideo {
|
position: relative;
|
width: 315px;
|
height: 180px;
|
background-color: #565656;
|
border-radius: 10px;
|
margin: 20px auto;
|
display: grid;
|
}
|
|
|
.myVideo /deep/ .dplayer {
|
border-radius: 5px;
|
}
|
|
.activeElement {
|
-webkit-animation: free_download 1s linear alternate infinite;
|
animation: free_download 1s linear alternate infinite;
|
}
|
|
@-webkit-keyframes free_download {
|
0% {
|
-webkit-transform: scale(1);
|
}
|
|
100% {
|
-webkit-transform: scale(1.2);
|
}
|
}
|
|
@keyframes free_download {
|
0% {
|
transform: scale(1);
|
}
|
|
100% {
|
transform: scale(1.2);
|
}
|
}
|
</style>
|