收藏
评论

同一页面存在多个video时,video无法正常播放一直在加载转圈官方

不建议同个页面使用多个video组件,建议不超过3个video,如果要实现video列表功能,请进行优化(image列表,选中时将image替换成video)

113145浏览
最后一次编辑于  2019-08-29
知识库内容非实时更新,可能已过期、失效或不适用于当前情形,请谨慎参考
收藏
反馈

7 个评论

  • 周18
    周18
    2020-04-02
      <block wx:for='{{videoList}}'>
                <image src="{{item.titleImage}}" style="display: {{ _index == index ? 'none' : 'block' }};" bindtap="videoPlay" data-id="{{index}}" class="video_imagemode='aspectFill'></image>
          <video src="{{item.videoUrl}}"  controls wx:if="{{_index == index}}" objectFit='contain' data-id="{{index}}" autoplay></video>
        </block>
    // image是视频封面图 取一下
    // video就是video
    // 自己排下样式,图片盖在video上,video播放的时候,image消失
    
     // 点击播放视频
      videoPlay(e){
        var _index = e.currentTarget.dataset.id
        this.setData({
            _index: _index
        })
        //停止正在播放的视频
        var videoContextPrev = wx.createVideoContext(_index + "")
        videoContextPrev.stop();
    
    
        setTimeout(function () {
            //将点击视频进行播放
            var videoContext = wx.createVideoContext(_index + "")
            videoContext.play();
        }, 500)
      },
    
    
    
    
    
    2020-04-02
    赞同 5
    回复 8
    • 中峰
      中峰
      2020-05-02
      怎么写了两遍一样的wx.createVideoContext,先stop,再play?什么意思
      2020-05-02
      回复
    • 周18
      周18
      2020-05-27回复中峰
      stop当前视频 播放下条视频
      2020-05-27
      1
      回复
    • 哆啦a梦你别跑
      哆啦a梦你别跑
      2020-06-17
      请问你有没有出现 图片点击之后变为视频,需要再次点击视频才可以播放视频 的问题?
      2020-06-17
      1
      回复
    • 东
      2020-06-18回复哆啦a梦你别跑
      给video 搞个id 就行了
      2020-06-18
      回复
    • 哆啦a梦你别跑
      哆啦a梦你别跑
      2020-06-18回复
      这个问题已经解决了,是可以播放视频的,只是需要点击两次才能播放,后来加了个autoPlay就可以点击一次播放了
      2020-06-18
      2
      回复
    查看更多(3)
  • 木木
    木木
    2022-05-07

    对于需要保留播放进度的视频切换,我这边做了改进,仅供参考,希望能帮到大家!

    这里在image优化的基础上,使用到了官方的api组件bindtimeupdate来实时获取视频的播放进度,并加以保存在AppData中的videoUpdateTime(这个名字是自定义的)中。

    之后在触发视频播放的handlePlay()方法中, 判断是否有videoUpdateTime是否由对应的该视频的播放记录(也就是记录的播放时长currentTime),如果有记录,在setTimeout()中开异步任务,延时200ms(我这边测试200ms可行,足够界面渲染),创建videoContext实例,并调用seek()方法,传入之前保留的currentTime,达到视频在播放进度处继续播放。

    注意:这里我用到了两个延时定时器setTimeout,分别处理首次播放及再次播放,避免出现同一个视频同时有多个实例在播放(就是会有多个视频声音在放),这个多视频同时播放的问题,也困扰了我好久,最后我采用两个定时器的方法解决了。

    Wxml中的相关代码:

    <view class="videoItem" wx:for="{{videoList}}" wx:key="id">
      <video src="{{item.data.urlInfo.url}}"
    	id="{{item.data.vid}}"
    	poster="{{item.data.coverUrl}}"
    	class="video"
    	wx:if='{{videoId === item.data.vid}}'
    	object-fit="fill"
    	bindtimeupdate="handleTimeUpdate"
    	bindended="handleEnded"
      ></video>
      <!-- 性能优化,使用image图片代替video标签 -->
      <!-- 一开始video隐藏,所以需要image传入id -->
      <image wx:else src="{{item.data.coverUrl}}"
       class="image" bindtap="handlerPlay"id="{{item.data.vid}}"></image>
    </view>
    


    Js中的相关代码:

    handlerPlay(event) {
        // 获取当前视频的id
        let vid = event.currentTarget.id
        // 更新data中的videoId的状态数据
        this.setData({
            videoId: vid
        })
        // 创建控制video标签的实例对象
        this.videoContextPrev = wx.createVideoContext(vid)
        // 关闭当前播放的视频
        this.videoContextPrev.stop()
        // 判断当前视屏是否有播放记录,如果有,跳转至指定播放位置
        let { videoUpdateTime } = this.data
        let videoItem = videoUpdateTime.find(item => item.vid === vid)
        // 情况一:如果有播放记录,从记录处继续播放
        if (videoItem) {
            // 获取播放的时间点,单位/s
            let timepoint = videoItem.currentTime
            this.timer1 = setTimeout(() => {
                let videoContext1 = wx.createVideoContext(vid)
                // 跳转到指定的时间位置
                videoContext1.seek(timepoint)
                videoContext1.play()
            }, 200)
        }
        // 情况二:如果没有播放记录,开始新的播放
        else {
            this.timer2 = setTimeout(() => {
                let videoContext2 = wx.createVideoContext(vid)
                videoContext2.play()
            }, 200)
        }
    },
    
    // 监听视频播放进度的回调
    handleTimeUpdate(event) {
        let { videoUpdateTime } = this.data
        let videoTimeObj = {
            vid: event.currentTarget.id,
            currentTime: event.detail.currentTime
        }
        /* 
          判断记录播放时长的videoUpdateTime数组中是否有当前视频的播放记录
          如果有修改原有播放记录,如果没有需要在数组中添加当前视频的播放记录
        */
        let videoItem = videoUpdateTime.find(item => item.vid === videoTimeObj.vid);
        if (videoItem) { // 之前有播放记录
            videoItem.currentTime = videoTimeObj.currentTime;
        } else { // 之前没有播放记录
            videoUpdateTime.push(videoTimeObj);
        }
        // 更新videoUpdateTime的状态
        this.setData({
            videoUpdateTime
        })
    },
    
    // 视频播放结束调用的回调
    handleEnded(event) {
        // 移除播放记录时长数组中当前视频的对象
        let { videoUpdateTime } = this.data
        let index = videoUpdateTime.findIndex(item => item.vid === event.currentTarget.id)
        // splice(index,howmany) ——> 删除从index位置开始的数,howmany为删除的个数
        // 若 howmany 小于等于 0,则不删除
        videoUpdateTime.splice(index, 1)
        this.setData({
            videoUpdateTime: videoUpdateTime,
            // 这里将videoId重置,使页面渲染的视频均为image封面图覆盖
            videoId: ''
        })
    },
    


    2022-05-07
    赞同 1
    回复 1
    • 晴天
      晴天
      2022-12-09
      不能播放???
      2022-12-09
      回复
  • 宇众不同
    宇众不同
    2020-03-05

    请问有没有demo,如何替换

    2020-03-05
    赞同 1
    回复
  • hh
    hh
    2022-09-01

    我这里在滑动结束video组件切换为image组件之后,还是在继续加载已替换掉的视频,大家有遇到过的吗

    2022-09-01
    赞同
    回复 2
    • 风色幻想
      风色幻想
      2022-09-20
      同问。。。已经划走的video,即使设置src为空、调用videoContext.stop()、v-if重置,它还是傻乎乎的继续加载
      2022-09-20
      回复
    • 凉凉
      凉凉
      2023-10-26回复风色幻想
      哥咋解决的
      2023-10-26
      回复
  • 月亮是我杀的
    月亮是我杀的
    2021-09-15

    能不能贴一个完整的代码

    2021-09-15
    赞同
    回复
  • 哈哈哈
    哈哈哈
    2021-04-20

    感谢!已copy走

    2021-04-20
    赞同
    回复
  • 蜜风🐝💤
    蜜风🐝💤
    2020-03-12

    同问~

    2020-03-12
    赞同
    回复
登录 后发表内容