video下danmu-listBUG
发布于 6 年前 作者 yang69 8859 次浏览 来自 问答

我的想法:我要用 danmu-list 做一个动态的视频弹幕

思路:我通过 bindtimeupdate 这个事件,一直在监听当前视频的进度,来获取弹幕的发送时间,从而把弹幕显示在视频上,我中间给了2s的延迟,在我监听到当前视频进度秒的时候,会向上取整,并且加2s作为弹幕在视频上的显示时间。让用户输入文字后,点击发送,我会构建一个数组,对 danmu-list 进行setdata,重新渲染页面。

问题:这样的写法在模拟器上没有任何问题,但是在手机端会出先失效、混乱的问题

手机设备:Android 华为 V9

手机端出现的问题:

1:当这个视频之前没有任何弹幕的时候,在手机端进行操作,可以把输入的弹幕显示在视频上,但是每次显示最新一条的时候,会把上一条的弹幕内容带上。

2:当这个视频存在弹幕的时候,也就是本身具有弹幕列表了,然后再进行操作,这个时候手机端输入文字,不能显示到视频列表中,只要把视频暂停后,然后拖回之前的时间,再进行一次播放,方可显示出来。

猜想:

我自己调试了很长时间,做了好几种假设,比如是否是我延迟时间给的太短,是否是数组的顺序不对。但是我发现都不是这些问题,最后,我再想,是否是setdata后 setdata进行页面渲染的时候,在手机端因为计算能力没电脑那么强,所以渲染的时间比较长,会让我错过弹幕该显示的时间点。如果是这个样子,我想请求官方告诉我,小程序setdata后 在自己渲染页面的时候会使用多久的时间才能完全渲染完,这样我就知道我改如何去控制用户在一定的时间范围内,才能发送弹幕。

代码:

wxml

<view class=“vid”>

<video class=‘videos’ id=“myVideo” src=’{{ImageServiceUrl+param.url}}’ controls=‘controls’ autoplay=“true” poster="{{ImageServiceUrl+param.pic}}" objectFit=“fill” danmu-list="{{danmu_list}}" danmu-btn=“true” enable-danmu=“true” bindtimeupdate=“VideoChange”></video>

</view>

<scroll-view scroll-y=“true” class=‘list’ style=‘height:{{windowHeight-260}}px;’ scroll-into-view="{{Toview}}">

<view class=‘list1’ id=‘ID-{{index}}’ wx:for="{{danmu_list}}" wx:key=“itme”>

<text style=‘color:#9b9b9b;’>{{item.name}}-{{item.time}}:</text>

<text style=‘color:#000;’>{{item.text}}</text>

</view>

</scroll-view>

<view class=‘inps’>

<form bindreset=“formReset”>

<input class=‘skl’ id=‘DanMuContentID’ placeholder=‘说点什么吧。。’ adjust-position=“false” bindinput=“CompleteContent” confirm-type=“发送” ></input>

<button class=‘send’ wx:if="{{!user_info}}" bindgetuserinfo=‘SendContentH’ open-type=“getUserInfo” form-type=‘reset’>发送</button>

<button class=‘send’ wx:if="{{user_info}}" bindtap=‘SendContentQ’ form-type=‘reset’ >发送</button>

</form>

</view>

JS:

// pages/video/play_video.js

const app = getApp()

Page({

    /**

       * 页面的初始数据

       */

    data: {

    ImageServiceUrl: app.globalService.ImageServiceUrl,

    MaxCount:1,

    ContentTime: 0,

    },

    

    /**

       * 生命周期函数–监听页面加载

       */

    onLoad: function (options) {

    var that = this;

    console.log(options);

    var pt_user = wx.getStorageSync(‘pt_user’);

    var user_info = wx.getStorageSync(‘user_info’);

    wx.setNavigationBarTitle({

    title: pt_user.hospital_title,

    });

    

    var CurrentTime = Date.parse(new Date());

    var CurrentContentTime = CurrentTime / 1000;

    

    wx.getSystemInfo({

    success(Winres) {

    wx.request({

    url: app.globalApiList.SelectDanMu,

    data:{‘id’:options.id,‘type’:options.type},

    success:function(res){

    that.setData({

    windowHeight: Winres.windowHeight,

    param: options,

    user_info: user_info,

    Toview: ‘ID-’ + res.data.data.MaxCount,

    MaxCount: res.data.data.MaxCount,

    ContentTime: CurrentContentTime,

    danmu_list: res.data.data.list,

    })

    }

    })

    }

    })

    var videoContext = wx.createVideoContext(‘myVideo’);

    //videoContext.requestFullScreen();

    },

    /**

         * 发送弹幕-获取信息

         */

    SendContentH:function(e){

    app.SetUserInfo(e.detail.userInfo);

    this.SendContentApi(e.detail.userInfo);

    },

    SendContentQ:function(){

    this.SendContentApi(this.data.user_info);

    },

    /**

         * 发送内容与后台交互

         */

    SendContentApi:function(userinfo){

    

    if (this.globalData.user_text){

    

    var ContentTime = this.data.ContentTime;

    var CurrentTime = Date.parse(new Date()) / 1000;

    var DiffentTime = CurrentTime - ContentTime;

    

    if (DiffentTime > 3){

    var pt_user = wx.getStorageSync(‘pt_user’);

    var MaxTime = this.globalData.MaxTime;

    var color_key = Math.floor(Math.random() * app.globalData.color.length);

    var danmu_list = this.data.danmu_list;

    var MaxCount = this.data.MaxCount + 1;

    

    var danmu = {

    text: this.globalData.user_text,

    color: app.globalData.color[color_key].number,

    time: MaxTime,

    name: userinfo.nickName

    };

    danmu_list.push(danmu);

    this.setData({

    user_info: userinfo,

    danmu_list: danmu_list,

    Toview: ‘ID-’ + MaxCount,

    MaxCount: MaxCount,

    });

    app.HideNoticeMessage(MaxTime.toString());

    console.log(this.data.danmu_list);

    wx.request({

    url: app.globalApiList.SaveDanMu,

    data:{

    text: this.globalData.user_text,

    name: userinfo.nickName,

    type:this.data.param.type,

    userid:pt_user.user_id,

    id:this.data.param.id,

    color: app.globalData.color[color_key].number,

    time: MaxTime,

    },

    success:function(res){

    

    }

    })

    }else{

    app.HideNoticeMessage(‘请’+DiffentTime+‘秒后再进行发言’);

    }

    }else{

    app.HideNoticeMessage(‘说点什么嘛~’);

    }

    },

    /**

         * 文字输入完毕的时候

         */

    CompleteContent:function(res){

    this.globalData.user_text=res.detail.value;

    },

    globalData: {

    user_text:null,

    videoObject:null,

    MaxTime:0,

    },

    /**

         * 视频播放进度变化时出发

         * 间隔 250ms

         */

    VideoChange:function(res){

    this.globalData.MaxTime = Math.ceil(res.detail.currentTime) + 3;

    },

    /**

         * 重置表单

         * 其实我搞不懂什么都不需要写

         * 为什么不可以用JS直接调用某个方法呢?

         * 很尴尬

         * 感觉像是要去某一个地方,但是我必须要绕一个圈子才能到达

         * 或许这是因为某些机制

         * 但是希望微信可以尽快让开发者别再绕来绕去

         * 其实我本意只是想清空input里面的值

         * 但是走这么多的步骤。

         */

    formReset:function(res){

    }

})

6 回复

我用过 sendDanmu 这个API来发送弹幕,但是这个API很不稳定,容易发不出来

@楼主,你可以尝试一下使用sendDanmu这个api来发送弹幕,而不是setData

@你剑哥,我还真没注意这种情况,谢谢提醒,我自己测试下

我也是在添加 bindtimeupdata 事件后,弹幕出现错乱的问题,不监听这个事件是没有问题的,但存储弹幕的时候又需要这个时间戳,楼主怎么解决的

我今天发现new Date(),在真机打印出来的时间和在模拟器上打印出来的时间差几个小时,你有这种情况么?百思不得其解。

回到顶部