vue+vue-video-play 修改样式 及解决浏览器倍速播放卡住问题

为什么浏览器设置倍速播放视频卡住不动啊啊啊

苦寻解决方式无果,试了好多api,最后用statechanged事件+重置currentTime解决的
video.js API

video.js API-详细

<template>
  <el-dialog :visible.sync="visible" title="视频播放" width="1390px" append-to-body @close="onClose">
    <div class="video-wrap">
        <video-player v-if="playerOptions.sources[0].src" ref="videoPlayer" class="vjs-custom-skin" :options="playerOptions" @ready="handleReady" @loadeddata="handleLoad" @statechanged="handleEvent($event, 'statechanged')" />
    </div>
  </ics-dialog>
</template>

<script>
import { videoPlayer, videojs } from 'vue-video-player'
import zhCN from './lang'; // 设置中文,文件从videojs中拷贝来的(只导出文本对象),直接引用videojs中的文件设置报错
import 'vue-video-player/src/custom-theme.css';
import 'video.js/dist/video-js.css'
videojs.addLanguage('zh-CN', zhCN)


export default {
  components: {
    videoPlayer
  },
  data() {
    return {
      visible: false,
      playerOptions: {
        muted: true,
        loop: true,
        height: '100%',
        width: '100%',
        language: 'zh-CN',
        sources: [{
          type: "video/mp4",
          src: ""
        }],
        controlBar: {
          volumePanel: false,
          pictureInPictureToggle: false,
          remainingTimeDisplay: false //是否显示剩余时间功能
        }
      },
      initSpeed: 4,
      playSpeed: 4,
      currentPlayer: null,
      timeout: null
    }
  },
  methods: {
    show(data) {
		// 设置播放地址
      this.playerOptions.sources[0].src = data.videoPath
      this.visible = true
    },
    // 在 ready 到 load 期间渲染 loading动画
    handleReady(player) {
      player.play()
    },
    // 有时候ready触发不到play()
    handleLoad(player) {
      if (player.paused()) player.play()
      player.playbackRate(this.playSpeed)
      this.currentPlayer = player
    },
	// 试了好几个事件发现暂停时会触发waiting 且player的paused状态不是false,所以在这里判断 卡住时延时一会儿重置currentTime,触发player再播放
    handleEvent(e) {
      if (!this.currentPlayer) return
      if (e.waiting && !this.currentPlayer.paused()) {
        this.clearTimeout()
        this.timeout = setTimeout(() => {
          const timeout = this.currentPlayer.currentTime()
          this.currentPlayer.currentTime(timeout)
        }, 800)
      }
    },
    onClose() {
      this.clearTimeout()
      this.visible = false
      this.currentPlayer.pause()
      this.currentPlayer.currentTime(0)
      this.currentPlayer = null
      this.playerOptions.sources[0].src = ''
      this.current = {}
    },
    clearTimeout() {
      this.timeout && clearTimeout(this.timeout)
      this.timeout = null
    }
  }
}
</script>

<style lang="scss" scoped>
.video-wrap {
  position: relative;
  height: 65vh;
  background: #070707;
  width: 1000px;
}

.video-player {
  height: 100%;
  width: 100%;
  ::v-deep {
    .video-js .vjs-big-play-button {
      display: none !important;
    }
    .video-js .vjs-loading-spinner {
      border-color: rgba($color: #3265DE, $alpha: 0.7)
    }
    .vjs-icon-fullscreen-enter, .video-js .vjs-fullscreen-control .vjs-icon-placeholder, .video-js .vjs-play-control.vjs-playing .vjs-icon-placeholder,.video-js .vjs-play-control .vjs-icon-placeholder {
      font-family: VideoJS !important; // 如果项目有重置字体 这里需要重新设置,不然icon显示异常
    }
    .video-js .vjs-play-progress {
      font-family: VideoJS !important;
      &::before {
        top: 0;
      }
    }
    .video-js .vjs-control-bar {
      opacity: 1 !important;
      padding-bottom: 40px;
      height: 80px;
      background: linear-gradient(rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.8));
    }
    .vjs-play-progress {
      background-color: #3265DE;
    }
    .video-js {
      height: 100%;
      width: 100%;
    }
  }
}

.el-dialog {
  ::v-deep {
    .el-dialog:not(.is-fullscreen) {
      max-width: 1390px;
    }
    .el-dialog__body {
      padding: 0;
    }
  }
}
</style>

posted @ 2025-04-24 15:46  总是被使用  阅读(76)  评论(0)    收藏  举报