|  | @@ -15,7 +15,10 @@ import { ref } from 'vue';
 | 
	
		
			
				|  |  |  import styles from './video.module.less';
 | 
	
		
			
				|  |  |  import iconplay from '../image/icon-pause.png';
 | 
	
		
			
				|  |  |  import iconpause from '../image/icon-play.png';
 | 
	
		
			
				|  |  | -import iconReplay from '../image/icon-replay.png';
 | 
	
		
			
				|  |  | +// import iconReplay from '../image/icon-replay.png';
 | 
	
		
			
				|  |  | +import iconLoop from '../image/icon-loop.svg';
 | 
	
		
			
				|  |  | +import iconLoopActive from '../image/icon-loop-active.svg';
 | 
	
		
			
				|  |  | +import iconSpeed from '../image/icon-speed.png';
 | 
	
		
			
				|  |  |  import { NSlider } from 'naive-ui';
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  export default defineComponent({
 | 
	
	
		
			
				|  | @@ -55,11 +58,18 @@ export default defineComponent({
 | 
	
		
			
				|  |  |        durationNum: 0,
 | 
	
		
			
				|  |  |        duration: '00:00',
 | 
	
		
			
				|  |  |        showBar: true,
 | 
	
		
			
				|  |  | -      showAction: true
 | 
	
		
			
				|  |  | +      showAction: true,
 | 
	
		
			
				|  |  | +      loop: false,
 | 
	
		
			
				|  |  | +      speedControl: false,
 | 
	
		
			
				|  |  | +      speedStyle: {
 | 
	
		
			
				|  |  | +        left: '1px'
 | 
	
		
			
				|  |  | +      },
 | 
	
		
			
				|  |  | +      defaultSpeed: 1 // 默认速度
 | 
	
		
			
				|  |  |      });
 | 
	
		
			
				|  |  |      const videoRef = ref();
 | 
	
		
			
				|  |  |      const videoItem = ref();
 | 
	
		
			
				|  |  |      const videoID = ref('video' + Date.now() + Math.floor(Math.random() * 100));
 | 
	
		
			
				|  |  | +    const speedBtnId = 'speed' + Date.now() + Math.floor(Math.random() * 100);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // 对时间进行格式化
 | 
	
		
			
				|  |  |      const timeFormat = (num: number) => {
 | 
	
	
		
			
				|  | @@ -86,6 +96,7 @@ export default defineComponent({
 | 
	
		
			
				|  |  |      };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      const onReplay = () => {
 | 
	
		
			
				|  |  | +      videoFroms.speedControl = false;
 | 
	
		
			
				|  |  |        if (!videoItem.value) return;
 | 
	
		
			
				|  |  |        videoItem.value.currentTime(0);
 | 
	
		
			
				|  |  |      };
 | 
	
	
		
			
				|  | @@ -103,18 +114,15 @@ export default defineComponent({
 | 
	
		
			
				|  |  |        emit('togglePlay', videoFroms.paused);
 | 
	
		
			
				|  |  |      };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    onMounted(() => {
 | 
	
		
			
				|  |  | -      videoItem.value = TCPlayer(videoID.value, {
 | 
	
		
			
				|  |  | -        appID: '',
 | 
	
		
			
				|  |  | -        controls: false
 | 
	
		
			
				|  |  | -      }); // player-container-id 为播放器容器 ID,必须与 html 中一致
 | 
	
		
			
				|  |  | +    const __init = () => {
 | 
	
		
			
				|  |  |        if (videoItem.value) {
 | 
	
		
			
				|  |  |          videoItem.value.poster(props.item.coverImg); // 封面
 | 
	
		
			
				|  |  |          videoItem.value.src(item.value.content); // url 播放地址
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +        videoItem.value.playbackRate(videoFroms.defaultSpeed);
 | 
	
		
			
				|  |  |          // 初步加载时
 | 
	
		
			
				|  |  |          videoItem.value.one('loadedmetadata', () => {
 | 
	
		
			
				|  |  | -          console.log(' Loading metadata');
 | 
	
		
			
				|  |  | +          // console.log(' Loading metadata');
 | 
	
		
			
				|  |  | +          videoItem.value.playbackRate(videoFroms.defaultSpeed);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |            // 获取时长
 | 
	
		
			
				|  |  |            videoFroms.duration = timeFormat(
 | 
	
	
		
			
				|  | @@ -171,6 +179,20 @@ export default defineComponent({
 | 
	
		
			
				|  |  |            console.log(e, 'error');
 | 
	
		
			
				|  |  |          });
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    onMounted(() => {
 | 
	
		
			
				|  |  | +      videoItem.value = TCPlayer(videoID.value, {
 | 
	
		
			
				|  |  | +        appID: '',
 | 
	
		
			
				|  |  | +        controls: false
 | 
	
		
			
				|  |  | +      }); // player-container-id 为播放器容器 ID,必须与 html 中一致
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      __init();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      document.getElementById(speedBtnId)?.addEventListener('click', e => {
 | 
	
		
			
				|  |  | +        e.stopPropagation();
 | 
	
		
			
				|  |  | +        videoFroms.speedControl = !videoFroms.speedControl;
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  |      });
 | 
	
		
			
				|  |  |      const stop = () => {
 | 
	
		
			
				|  |  |        videoItem.value.currentTime(0);
 | 
	
	
		
			
				|  | @@ -191,11 +213,13 @@ export default defineComponent({
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      watch(
 | 
	
		
			
				|  |  |        () => props.item,
 | 
	
		
			
				|  |  | -      (val, oldVal) => {
 | 
	
		
			
				|  |  | +      () => {
 | 
	
		
			
				|  |  |          videoItem.value.pause();
 | 
	
		
			
				|  |  |          videoItem.value.currentTime(0);
 | 
	
		
			
				|  |  | -        videoItem.value.poster(props.item.coverImg); // 封面
 | 
	
		
			
				|  |  | -        videoItem.value.src(item.value.content); // url 播放地址
 | 
	
		
			
				|  |  | +        // videoItem.value.poster(props.item.coverImg); // 封面
 | 
	
		
			
				|  |  | +        // videoItem.value.src(item.value.content); // url 播放地址
 | 
	
		
			
				|  |  | +        __init();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          videoFroms.paused = true;
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      );
 | 
	
	
		
			
				|  | @@ -204,6 +228,7 @@ export default defineComponent({
 | 
	
		
			
				|  |  |        () => {
 | 
	
		
			
				|  |  |          // console.log(props.showModel, 'props.showModel')
 | 
	
		
			
				|  |  |          videoFroms.showAction = props.showModel;
 | 
	
		
			
				|  |  | +        videoFroms.speedControl = false;
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      );
 | 
	
		
			
				|  |  |      expose({
 | 
	
	
		
			
				|  | @@ -223,6 +248,7 @@ export default defineComponent({
 | 
	
		
			
				|  |  |            playsinline
 | 
	
		
			
				|  |  |            webkit-playsinline
 | 
	
		
			
				|  |  |            x5-video-player-type="h5"></video>
 | 
	
		
			
				|  |  | +        <div class={styles.videoPop}></div>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          <div
 | 
	
		
			
				|  |  |            class={[
 | 
	
	
		
			
				|  | @@ -240,6 +266,7 @@ export default defineComponent({
 | 
	
		
			
				|  |  |                <div
 | 
	
		
			
				|  |  |                  class={styles.actionBtn}
 | 
	
		
			
				|  |  |                  onClick={() => {
 | 
	
		
			
				|  |  | +                  videoFroms.speedControl = false;
 | 
	
		
			
				|  |  |                    onToggleVideo();
 | 
	
		
			
				|  |  |                  }}>
 | 
	
		
			
				|  |  |                  {videoFroms.paused ? (
 | 
	
	
		
			
				|  | @@ -248,18 +275,13 @@ export default defineComponent({
 | 
	
		
			
				|  |  |                    <img class={styles.playIcon} src={iconpause} />
 | 
	
		
			
				|  |  |                  )}
 | 
	
		
			
				|  |  |                </div>
 | 
	
		
			
				|  |  | -            </div>
 | 
	
		
			
				|  |  | -            <div class={styles.time}>
 | 
	
		
			
				|  |  | -              <div
 | 
	
		
			
				|  |  | -                class="plyr__time plyr__time--current"
 | 
	
		
			
				|  |  | -                aria-label="Current time">
 | 
	
		
			
				|  |  | -                {videoFroms.currentTime}
 | 
	
		
			
				|  |  | -              </div>
 | 
	
		
			
				|  |  | -              <span class={styles.line}>/</span>
 | 
	
		
			
				|  |  | -              <div
 | 
	
		
			
				|  |  | -                class="plyr__time plyr__time--duration"
 | 
	
		
			
				|  |  | -                aria-label="Duration">
 | 
	
		
			
				|  |  | -                {videoFroms.duration}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +              <button class={styles.iconReplay} onClick={onReplay}>
 | 
	
		
			
				|  |  | +                <img src={iconLoop} />
 | 
	
		
			
				|  |  | +              </button>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +              <div class={styles.actionBtnSpeed} id={speedBtnId}>
 | 
	
		
			
				|  |  | +                <img src={iconSpeed} />
 | 
	
		
			
				|  |  |                </div>
 | 
	
		
			
				|  |  |              </div>
 | 
	
		
			
				|  |  |            </div>
 | 
	
	
		
			
				|  | @@ -271,6 +293,7 @@ export default defineComponent({
 | 
	
		
			
				|  |  |                max={videoFroms.durationNum}
 | 
	
		
			
				|  |  |                tooltip={false}
 | 
	
		
			
				|  |  |                onUpdate:value={(val: number) => {
 | 
	
		
			
				|  |  | +                videoFroms.speedControl = false;
 | 
	
		
			
				|  |  |                  videoItem.value.currentTime(val);
 | 
	
		
			
				|  |  |                  videoFroms.currentTimeNum = val;
 | 
	
		
			
				|  |  |                  videoFroms.currentTime = timeFormat(Math.round(val || 0));
 | 
	
	
		
			
				|  | @@ -280,12 +303,82 @@ export default defineComponent({
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |            <div class={styles.actions}>
 | 
	
		
			
				|  |  |              <div class={styles.actionWrap}>
 | 
	
		
			
				|  |  | -              <button class={styles.iconReplay} onClick={onReplay}>
 | 
	
		
			
				|  |  | -                <img src={iconReplay} />
 | 
	
		
			
				|  |  | -              </button>
 | 
	
		
			
				|  |  | +              <div class={styles.time}>
 | 
	
		
			
				|  |  | +                <div
 | 
	
		
			
				|  |  | +                  class="plyr__time plyr__time--current"
 | 
	
		
			
				|  |  | +                  aria-label="Current time">
 | 
	
		
			
				|  |  | +                  {videoFroms.currentTime}
 | 
	
		
			
				|  |  | +                </div>
 | 
	
		
			
				|  |  | +                <span class={styles.line}>/</span>
 | 
	
		
			
				|  |  | +                <div
 | 
	
		
			
				|  |  | +                  class="plyr__time plyr__time--duration"
 | 
	
		
			
				|  |  | +                  aria-label="Duration">
 | 
	
		
			
				|  |  | +                  {videoFroms.duration}
 | 
	
		
			
				|  |  | +                </div>
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  |              </div>
 | 
	
		
			
				|  |  |            </div>
 | 
	
		
			
				|  |  |          </div>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        <div
 | 
	
		
			
				|  |  | +          style={{
 | 
	
		
			
				|  |  | +            display: videoFroms.speedControl ? 'block' : 'none'
 | 
	
		
			
				|  |  | +          }}>
 | 
	
		
			
				|  |  | +          <div
 | 
	
		
			
				|  |  | +            class={styles.sliderPopup}
 | 
	
		
			
				|  |  | +            onClick={(e: Event) => {
 | 
	
		
			
				|  |  | +              e.stopPropagation();
 | 
	
		
			
				|  |  | +            }}>
 | 
	
		
			
				|  |  | +            <i
 | 
	
		
			
				|  |  | +              class={styles.iconAdd}
 | 
	
		
			
				|  |  | +              onClick={() => {
 | 
	
		
			
				|  |  | +                if (videoFroms.defaultSpeed >= 1.5) {
 | 
	
		
			
				|  |  | +                  return;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                if (videoItem.value) {
 | 
	
		
			
				|  |  | +                  videoFroms.defaultSpeed =
 | 
	
		
			
				|  |  | +                    (videoFroms.defaultSpeed * 10 + 1) / 10;
 | 
	
		
			
				|  |  | +                  videoItem.value.playbackRate(videoFroms.defaultSpeed);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +              }}></i>
 | 
	
		
			
				|  |  | +            <NSlider
 | 
	
		
			
				|  |  | +              value={videoFroms.defaultSpeed}
 | 
	
		
			
				|  |  | +              step={0.1}
 | 
	
		
			
				|  |  | +              max={1.5}
 | 
	
		
			
				|  |  | +              min={0.6}
 | 
	
		
			
				|  |  | +              vertical
 | 
	
		
			
				|  |  | +              tooltip={false}
 | 
	
		
			
				|  |  | +              onUpdate:value={(val: number) => {
 | 
	
		
			
				|  |  | +                videoFroms.defaultSpeed = val;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                if (videoItem.value) {
 | 
	
		
			
				|  |  | +                  videoItem.value.playbackRate(videoFroms.defaultSpeed);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +              }}>
 | 
	
		
			
				|  |  | +              {{
 | 
	
		
			
				|  |  | +                thumb: () => (
 | 
	
		
			
				|  |  | +                  <div class={styles.sliderPoint}>
 | 
	
		
			
				|  |  | +                    {videoFroms.defaultSpeed}
 | 
	
		
			
				|  |  | +                    <span>x</span>
 | 
	
		
			
				|  |  | +                  </div>
 | 
	
		
			
				|  |  | +                )
 | 
	
		
			
				|  |  | +              }}
 | 
	
		
			
				|  |  | +            </NSlider>
 | 
	
		
			
				|  |  | +            <i
 | 
	
		
			
				|  |  | +              class={[styles.iconCut]}
 | 
	
		
			
				|  |  | +              onClick={() => {
 | 
	
		
			
				|  |  | +                if (videoFroms.defaultSpeed <= 0.6) {
 | 
	
		
			
				|  |  | +                  return;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if (videoItem.value) {
 | 
	
		
			
				|  |  | +                  videoFroms.defaultSpeed =
 | 
	
		
			
				|  |  | +                    (videoFroms.defaultSpeed * 10 - 1) / 10;
 | 
	
		
			
				|  |  | +                  videoItem.value.playbackRate(videoFroms.defaultSpeed);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +              }}></i>
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  |        </div>
 | 
	
		
			
				|  |  |      );
 | 
	
		
			
				|  |  |    }
 |