videojs-player icon indicating copy to clipboard operation
videojs-player copied to clipboard

点击页面其他地方(checkbox,tab页),video视频会抖动,刷新

Open yanqic opened this issue 6 years ago • 7 comments

英文不好抱歉,使用vue-video-player控件的时候,切换tab页,如果页面有多个video控件,会刷新多次, 点击checkbox,关闭弹窗(或相关dom)操作,video控件都会重新加载或刷新,请问该怎么解决呢?

<li class="lists" v-for="(item,index) in contentData" :key="index">
        <div class="content-wrap">
          <h3 class="title">{{item.content.title}}</h3>
          <p v-if="item.atype === 1" class="context" v-html="item.content.context"></p>
          <div class="video-wrap" v-else-if="item.atype === 2">
            <video-player class="vjs-custom-skin" ref="videoPlayer" :options="getOptions(item.content.video_url)" :playsinline="true">
            </video-player>
          </div>

yanqic avatar May 19 '18 05:05 yanqic

我也要类似的问题,请问你解决了吗

ghost avatar Jun 01 '18 02:06 ghost

我在做SSR时也遇到了同样问题,切换tab时播放器刷新了一下 重新播了一遍 版本v5.0.2 截屏地址

Deeeeeee avatar Jan 07 '19 13:01 Deeeeeee

遇到一模一样的问题, 只要操作列表里面的数据, 其他视频就会刷新

SpanishOnion avatar Mar 18 '19 14:03 SpanishOnion

遇到同样的问题,有人解决了吗

StevenShaoYY avatar May 13 '19 03:05 StevenShaoYY

我碰到的问题形式:页面上有个输入框,输入字符的时候,以及点击其他按钮的时候,视频画面四边会抖动,但感觉应该也不至于引起重绘。后来摸索到一个诡异的解决方案:拉长界面上某个不可见的div,使出现纵向滚动条,就好了。。。

sagittaria avatar Oct 30 '19 12:10 sagittaria

我把tab这块封装到组件里再用才可以....

649683137 avatar Dec 11 '19 06:12 649683137

遇到这个问题已解决,源码player.vue中会deep watch option参数,当参数变化时会重新渲染video,将监听去掉就行了

<template>
  <div class="video-player" v-if="reseted">
    <video class="video-js" ref="video">
      <track v-for="(crtTrack,index) in trackList" :key="index" :kind="crtTrack.kind" :label="crtTrack.label" :src="crtTrack.src" :srcLang="crtTrack.srcLang" :default="crtTrack.default"/>
    </video>
  </div>
</template>
<script>
  // lib
  import _videojs from 'video.js'
  const videojs = window.videojs || _videojs
  // pollfill
  if (typeof Object.assign !== 'function') {
    Object.defineProperty(Object, 'assign', {
      value (target, varArgs) {
        if (target == null) {
          throw new TypeError('Cannot convert undefined or null to object')
        }
        const to = Object(target)
        for (let index = 1; index < arguments.length; index++) {
          const nextSource = arguments[index]
          if (nextSource !== null) {
            for (const nextKey in nextSource) {
              if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
                to[nextKey] = nextSource[nextKey]
              }
            }
          }
        }
        return to
      },
      writable: true,
      configurable: true
    })
  }
  // as of videojs 6.6.0
  const DEFAULT_EVENTS = [
    'loadeddata',
    'canplay',
    'canplaythrough',
    'play',
    'pause',
    'waiting',
    'playing',
    'ended',
    'error'
  ]
  // export
  export default {
    name: 'my-player',
    props: {
      start: {
        type: Number,
        default: 0
      },
      crossOrigin: {
        type: String,
        default: ''
      },
      playsinline: {
        type: Boolean,
        default: false
      },
      customEventName: {
        type: String,
        default: 'statechanged'
      },
      options: {
        type: Object,
        required: true
      },
      events: {
        type: Array,
        default: () => []
      },
      globalOptions: {
        type: Object,
        default: () => ({
          // autoplay: false,
          controls: true,
          // preload: 'auto',
          // fluid: false,
          // muted: false,
          controlBar: {
            remainingTimeDisplay: false,
            playToggle: {},
            progressControl: {},
            fullscreenToggle: {},
            volumeMenuButton: {
              inline: false,
              vertical: true
            }
          },
          techOrder: ['html5'],
          plugins: {}
        })
      },
      globalEvents: {
        type: Array,
        default: () => []
      },
      trackList: {
        type: Array,
        default: () => []
      }
    },
    data () {
      return {
        player: null,
        reseted: true
      }
    },
    mounted () {
      if (!this.player) {
        this.initialize()
      }
    },
    beforeDestroy () {
      if (this.player) {
        this.dispose()
      }
    },
    methods: {
      initialize () {
        // videojs options
        const videoOptions = Object.assign({}, this.globalOptions, this.options)
        // ios fullscreen
        if (this.playsinline) {
          this.$refs.video.setAttribute('playsinline', this.playsinline)
          this.$refs.video.setAttribute('webkit-playsinline', this.playsinline)
          this.$refs.video.setAttribute('x5-playsinline', this.playsinline)
          this.$refs.video.setAttribute('x5-video-player-type', 'h5')
          this.$refs.video.setAttribute('x5-video-player-fullscreen', false)
        }
        // cross origin
        if (this.crossOrigin !== '') {
          this.$refs.video.crossOrigin = this.crossOrigin
          this.$refs.video.setAttribute('crossOrigin', this.crossOrigin)
        }
        // emit event
        const emitPlayerState = (event, value) => {
          if (event) {
            this.$emit(event, this.player)
          }
          if (value) {
            this.$emit(this.customEventName, { [event]: value })
          }
        }
        // avoid error "VIDEOJS: ERROR: Unable to find plugin: __ob__"
        if (videoOptions.plugins) {
          delete videoOptions.plugins.__ob__
        }
        // videoOptions
        // console.log('videoOptions', videoOptions)

        // player
        const self = this
        this.player = videojs(this.$refs.video, videoOptions, function () {
          // events
          const events = DEFAULT_EVENTS.concat(self.events).concat(self.globalEvents)
          // watch events
          const onEdEvents = {}
          for (let i = 0; i < events.length; i++) {
            if (typeof events[i] === 'string' && onEdEvents[events[i]] === undefined) {
              (event => {
                onEdEvents[event] = null
                this.on(event, () => {
                  emitPlayerState(event, true)
                })
              })(events[i])
            }
          }
          // watch timeupdate
          this.on('timeupdate', function () {
            emitPlayerState('timeupdate', this.currentTime())
          })
          // player readied
          self.$emit('ready', this)
        })
      },
      dispose (callback) {
        if (this.player && this.player.dispose) {
          if (this.player.techName_ !== 'Flash') {
            this.player.pause && this.player.pause()
          }
          this.player.dispose()
          this.player = null
          this.$nextTick(() => {
            this.reseted = false
            this.$nextTick(() => {
              this.reseted = true
              this.$nextTick(() => {
                callback && callback()
              })
            })
          })
          /*
          if (!this.$el.children.length) {
            const video = document.createElement('video')
            video.className = 'video-js'
            this.$el.appendChild(video)
          }
          */
        }
      }
    },
   //watch: {
   //   options: {
   //     deep: true,
   //     handler(options, oldOptions) {
   //       this.dispose(() => {
   //         if (options && options.sources && options.sources.length) {
   //           this.initialize()
   //         }
   //       })
   //     }
   //   }
   // }
  }
</script>

weiyuc avatar Jul 09 '20 09:07 weiyuc