|
@@ -15,8 +15,10 @@ import iconLoop from '../../image/icon-loop.svg';
|
|
import iconLoopActive from '../../image/icon-loop-active.svg';
|
|
import iconLoopActive from '../../image/icon-loop-active.svg';
|
|
import iconplay from '../../image/icon-play.svg';
|
|
import iconplay from '../../image/icon-play.svg';
|
|
import iconpause from '../../image/icon-pause.svg';
|
|
import iconpause from '../../image/icon-pause.svg';
|
|
|
|
+import iconSpeed from '../../image/icon-speed.png';
|
|
import { NSlider } from 'naive-ui';
|
|
import { NSlider } from 'naive-ui';
|
|
import { getSecondRPM } from '@/helpers/utils';
|
|
import { getSecondRPM } from '@/helpers/utils';
|
|
|
|
+import { Slider } from 'vant';
|
|
|
|
|
|
export default defineComponent({
|
|
export default defineComponent({
|
|
name: 'video-play',
|
|
name: 'video-play',
|
|
@@ -47,6 +49,7 @@ export default defineComponent({
|
|
emits: ['canplay', 'pause', 'togglePlay', 'ended', 'reset', 'close', 'error'],
|
|
emits: ['canplay', 'pause', 'togglePlay', 'ended', 'reset', 'close', 'error'],
|
|
setup(props, { emit, expose }) {
|
|
setup(props, { emit, expose }) {
|
|
const videoID = 'video' + Date.now() + Math.floor(Math.random() * 100);
|
|
const videoID = 'video' + Date.now() + Math.floor(Math.random() * 100);
|
|
|
|
+ const speedBtnId = 'speed' + Date.now() + Math.floor(Math.random() * 100);
|
|
const videoItem = ref();
|
|
const videoItem = ref();
|
|
const { item, isEmtry } = toRefs(props);
|
|
const { item, isEmtry } = toRefs(props);
|
|
const data = reactive({
|
|
const data = reactive({
|
|
@@ -56,7 +59,12 @@ export default defineComponent({
|
|
loop: false,
|
|
loop: false,
|
|
playState: 'pause' as 'play' | 'pause',
|
|
playState: 'pause' as 'play' | 'pause',
|
|
vudio: null as any,
|
|
vudio: null as any,
|
|
- reload: false
|
|
|
|
|
|
+ reload: false,
|
|
|
|
+ speedControl: false,
|
|
|
|
+ speedStyle: {
|
|
|
|
+ left: '1px'
|
|
|
|
+ },
|
|
|
|
+ defaultSpeed: 1 // 默认速度
|
|
});
|
|
});
|
|
const contetRef = ref();
|
|
const contetRef = ref();
|
|
|
|
|
|
@@ -78,6 +86,7 @@ export default defineComponent({
|
|
let playTimer = null as any;
|
|
let playTimer = null as any;
|
|
// 切换音频播放
|
|
// 切换音频播放
|
|
const onToggleAudio = (state: 'play' | 'pause') => {
|
|
const onToggleAudio = (state: 'play' | 'pause') => {
|
|
|
|
+ data.speedControl = false;
|
|
clearTimeout(playTimer);
|
|
clearTimeout(playTimer);
|
|
if (state === 'play') {
|
|
if (state === 'play') {
|
|
playTimer = setTimeout(() => {
|
|
playTimer = setTimeout(() => {
|
|
@@ -93,6 +102,7 @@ export default defineComponent({
|
|
|
|
|
|
// 如果视屏异常后,需要重新播放视屏
|
|
// 如果视屏异常后,需要重新播放视屏
|
|
const onPlay = () => {
|
|
const onPlay = () => {
|
|
|
|
+ data.speedControl = false;
|
|
if (videoItem.value) {
|
|
if (videoItem.value) {
|
|
videoItem.value.src(item.value.content);
|
|
videoItem.value.src(item.value.content);
|
|
emit('reset');
|
|
emit('reset');
|
|
@@ -101,6 +111,7 @@ export default defineComponent({
|
|
|
|
|
|
/** 改变播放时间 */
|
|
/** 改变播放时间 */
|
|
const handleChangeTime = (val: number) => {
|
|
const handleChangeTime = (val: number) => {
|
|
|
|
+ data.speedControl = false;
|
|
data.currentTime = val;
|
|
data.currentTime = val;
|
|
clearTimeout(data.timer);
|
|
clearTimeout(data.timer);
|
|
data.timer = setTimeout(() => {
|
|
data.timer = setTimeout(() => {
|
|
@@ -112,18 +123,14 @@ export default defineComponent({
|
|
};
|
|
};
|
|
|
|
|
|
const __init = () => {
|
|
const __init = () => {
|
|
- videoItem.value = TCPlayer(videoID, {
|
|
|
|
- appID: '',
|
|
|
|
- controls: false
|
|
|
|
- }); // player-container-id 为播放器容器 ID,必须与 html 中一致
|
|
|
|
if (videoItem.value) {
|
|
if (videoItem.value) {
|
|
- console.log(videoItem.value);
|
|
|
|
|
|
+ // console.log(videoItem.value);
|
|
videoItem.value.poster(props.item.coverImg); // 封面
|
|
videoItem.value.poster(props.item.coverImg); // 封面
|
|
videoItem.value.src(item.value.content); // url 播放地址
|
|
videoItem.value.src(item.value.content); // url 播放地址
|
|
-
|
|
|
|
|
|
+ videoItem.value.playbackRate(data.defaultSpeed);
|
|
// 初步加载时
|
|
// 初步加载时
|
|
videoItem.value.one('loadedmetadata', (e: any) => {
|
|
videoItem.value.one('loadedmetadata', (e: any) => {
|
|
- console.log(' Loading metadata', e);
|
|
|
|
|
|
+ videoItem.value.playbackRate(data.defaultSpeed);
|
|
data.reload = false;
|
|
data.reload = false;
|
|
// 获取时长
|
|
// 获取时长
|
|
data.duration = videoItem.value.duration();
|
|
data.duration = videoItem.value.duration();
|
|
@@ -132,13 +139,13 @@ export default defineComponent({
|
|
});
|
|
});
|
|
// 视频开始播放
|
|
// 视频开始播放
|
|
videoItem.value.on('play', () => {
|
|
videoItem.value.on('play', () => {
|
|
- emit('close')
|
|
|
|
- emit('canplay')
|
|
|
|
|
|
+ emit('close');
|
|
|
|
+ emit('canplay');
|
|
});
|
|
});
|
|
//
|
|
//
|
|
videoItem.value.on('pause', () => {
|
|
videoItem.value.on('pause', () => {
|
|
data.playState = 'pause';
|
|
data.playState = 'pause';
|
|
- emit('pause')
|
|
|
|
|
|
+ emit('pause');
|
|
});
|
|
});
|
|
|
|
|
|
// 视频播放时加载
|
|
// 视频播放时加载
|
|
@@ -150,16 +157,16 @@ export default defineComponent({
|
|
videoItem.value.on('ended', () => {
|
|
videoItem.value.on('ended', () => {
|
|
data.playState = 'pause';
|
|
data.playState = 'pause';
|
|
// emit('ended');
|
|
// emit('ended');
|
|
- });
|
|
|
|
|
|
+ });
|
|
|
|
|
|
videoItem.value.on('playing', () => {
|
|
videoItem.value.on('playing', () => {
|
|
data.playState = 'play';
|
|
data.playState = 'play';
|
|
});
|
|
});
|
|
|
|
|
|
videoItem.value.on('canplay', (e: any) => {
|
|
videoItem.value.on('canplay', (e: any) => {
|
|
- console.log('canplay', );
|
|
|
|
|
|
+ // console.log('canplay');
|
|
data.duration = videoItem.value.duration();
|
|
data.duration = videoItem.value.duration();
|
|
- emit('canplay')
|
|
|
|
|
|
+ emit('canplay');
|
|
});
|
|
});
|
|
|
|
|
|
// 视频播放异常
|
|
// 视频播放异常
|
|
@@ -170,20 +177,38 @@ export default defineComponent({
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
- watch(() => props.item, (val, oldVal) => {
|
|
|
|
- videoItem.value.currentTime(0)
|
|
|
|
- videoItem.value.poster(props.item.coverImg); // 封面
|
|
|
|
- videoItem.value.src(item.value.content); // url 播放地址
|
|
|
|
- data.playState = 'pause';
|
|
|
|
- })
|
|
|
|
|
|
+ watch(
|
|
|
|
+ () => props.item,
|
|
|
|
+ () => {
|
|
|
|
+ videoItem.value.currentTime(0);
|
|
|
|
+ __init();
|
|
|
|
+ data.playState = 'pause';
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ watch(
|
|
|
|
+ () => props.showModel,
|
|
|
|
+ () => {
|
|
|
|
+ console.log(props.showModel, 'showModel');
|
|
|
|
+ data.speedControl = false;
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
|
+ videoItem.value = TCPlayer(videoID, {
|
|
|
|
+ appID: '',
|
|
|
|
+ controls: false
|
|
|
|
+ }); // player-container-id 为播放器容器 ID,必须与 html 中一致
|
|
__init();
|
|
__init();
|
|
|
|
+
|
|
|
|
+ document.getElementById(speedBtnId)?.addEventListener('click', e => {
|
|
|
|
+ e.stopPropagation();
|
|
|
|
+ data.speedControl = !data.speedControl;
|
|
|
|
+ });
|
|
});
|
|
});
|
|
|
|
|
|
const pause = () => {
|
|
const pause = () => {
|
|
videoItem.value.pause();
|
|
videoItem.value.pause();
|
|
- }
|
|
|
|
|
|
+ };
|
|
|
|
|
|
expose({
|
|
expose({
|
|
onPlay,
|
|
onPlay,
|
|
@@ -208,14 +233,13 @@ export default defineComponent({
|
|
class={[styles.controls, props.showModel ? '' : styles.hide]}
|
|
class={[styles.controls, props.showModel ? '' : styles.hide]}
|
|
onClick={(e: Event) => {
|
|
onClick={(e: Event) => {
|
|
e.stopPropagation();
|
|
e.stopPropagation();
|
|
- if(videoItem.value.paused()) return
|
|
|
|
- emit('close')
|
|
|
|
- }}
|
|
|
|
- onTouchmove={(e: Event) => {
|
|
|
|
- if(videoItem.value.paused()) return
|
|
|
|
- emit('close')
|
|
|
|
|
|
+ if (videoItem.value.paused()) return;
|
|
|
|
+ emit('close');
|
|
}}
|
|
}}
|
|
- >
|
|
|
|
|
|
+ onTouchmove={(e: Event) => {
|
|
|
|
+ if (videoItem.value.paused()) return;
|
|
|
|
+ emit('close');
|
|
|
|
+ }}>
|
|
<div class={styles.time}>
|
|
<div class={styles.time}>
|
|
<div>{getSecondRPM(data.currentTime)}</div>
|
|
<div>{getSecondRPM(data.currentTime)}</div>
|
|
<div>{getSecondRPM(data.duration)}</div>
|
|
<div>{getSecondRPM(data.duration)}</div>
|
|
@@ -241,11 +265,73 @@ export default defineComponent({
|
|
<div
|
|
<div
|
|
class={styles.actionBtn}
|
|
class={styles.actionBtn}
|
|
onClick={() => {
|
|
onClick={() => {
|
|
- data.loop = !data.loop
|
|
|
|
- videoItem.value.loop(data.loop)
|
|
|
|
|
|
+ data.loop = !data.loop;
|
|
|
|
+ data.speedControl = false;
|
|
|
|
+ videoItem.value.loop(data.loop);
|
|
}}>
|
|
}}>
|
|
<img src={data.loop ? iconLoopActive : iconLoop} />
|
|
<img src={data.loop ? iconLoopActive : iconLoop} />
|
|
</div>
|
|
</div>
|
|
|
|
+
|
|
|
|
+ <div class={styles.actionBtn} id={speedBtnId}>
|
|
|
|
+ <img src={iconSpeed} />
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div
|
|
|
|
+ style={{
|
|
|
|
+ display: data.speedControl ? 'block' : 'none'
|
|
|
|
+ }}>
|
|
|
|
+ <div
|
|
|
|
+ class={styles.sliderPopup}
|
|
|
|
+ onClick={(e: Event) => {
|
|
|
|
+ e.stopPropagation();
|
|
|
|
+ }}>
|
|
|
|
+ <i
|
|
|
|
+ class={styles.iconAdd}
|
|
|
|
+ onClick={() => {
|
|
|
|
+ if (data.defaultSpeed >= 1.5) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (videoItem.value) {
|
|
|
|
+ data.defaultSpeed = (data.defaultSpeed * 10 + 1) / 10;
|
|
|
|
+ videoItem.value.playbackRate(data.defaultSpeed);
|
|
|
|
+ }
|
|
|
|
+ }}></i>
|
|
|
|
+ <Slider
|
|
|
|
+ min={0.6}
|
|
|
|
+ max={1.5}
|
|
|
|
+ step={0.1}
|
|
|
|
+ v-model={data.defaultSpeed}
|
|
|
|
+ vertical
|
|
|
|
+ barHeight={5}
|
|
|
|
+ reverse
|
|
|
|
+ onChange={() => {
|
|
|
|
+ if (videoItem.value) {
|
|
|
|
+ videoItem.value.playbackRate(data.defaultSpeed);
|
|
|
|
+ }
|
|
|
|
+ }}>
|
|
|
|
+ {{
|
|
|
|
+ button: () => (
|
|
|
|
+ <div class={styles.sliderPoint}>
|
|
|
|
+ {data.defaultSpeed}
|
|
|
|
+ <span>x</span>
|
|
|
|
+ </div>
|
|
|
|
+ )
|
|
|
|
+ }}
|
|
|
|
+ </Slider>
|
|
|
|
+ <i
|
|
|
|
+ class={[styles.iconCut]}
|
|
|
|
+ onClick={() => {
|
|
|
|
+ if (data.defaultSpeed <= 0.6) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (videoItem.value) {
|
|
|
|
+ data.defaultSpeed = (data.defaultSpeed * 10 - 1) / 10;
|
|
|
|
+ videoItem.value.playbackRate(data.defaultSpeed);
|
|
|
|
+ }
|
|
|
|
+ }}></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|