YouTube API 和 Websockets 确保两个视频同步(视频 1 在视频 2 缓冲时暂停)

YouTube API & Websockets Make sure two videos are in sync (Video 1 pauses when Video 2 buffers)

背景

我正在尝试将视频集成到幻灯片演示应用程序中。我已经禁用了学生端的控件,并有一个连接到 YouTube API 的 play/pause 按钮,这样当它被点击时,一个事件会通过推送器触发,视频开始出现在教师屏幕上,然后学生屏幕。

困难

当其中一位用户的互联网连接速度较慢时,就会出现问题。如果老师的网速比学生快,那么视频就会不同步。

我的方法

我有一个功能,它使用 YouTube API 来控制视频的播放和暂停。

/**
 *
 */
togglePlay: function(){
    var videoId = this.videoId;
    if (this.isPlaying) {
        this.players[videoId].pauseVideo(); // Pauses the video
        this.isPlaying = false;
    } else {
        this.players[videoId].playVideo(); // Starts the video
        this.isPlaying = true;
    }
},

我在视频对象中添加了一个 onStateChange 事件侦听器,当视频 playing/paused/buffering 时会触发该事件侦听器。事件发送到此函数。

/**
 *
 */
emittStateChange: function(e){
    switch(e.data) {
        // if the teachers video is...
        case 1: // playing
            pusher.channel4.trigger('client-youtube-triggered', {
                videoId: youtube.videoId,
                status: 1, // start the students video
            });
        break;
        case 2: // paused
            pusher.channel4.trigger('client-youtube-triggered', {
                videoId: youtube.videoId,
                status: 2, // pause the students video
            });
        break;
        case 3: // buffering
            pusher.channel4.trigger('client-youtube-triggered', {
                videoId: youtube.videoId,
                status: 2, // pause the students video
            });
    }
},

因此,当教师按下播放键时,视频开始播放并触发一个播放事件,该事件被发送到上述函数。此函数向学生浏览器发送一个推送事件,状态为 1,表示播放视频。此函数接收此事件:

/**
 * 
 */
receiveStateChange: function(data){
    this.videoId = data.videoId;
    switch(data.status) {
        // if the teachers video is...
        case 1: // playing
            this.isPlaying = false;
            this.togglePlay();
        break;
        case 2: // paused
            this.isPlaying = true;
            this.togglePlay();
        break;
        case 2: // buffering
            this.isPlaying = true;
            this.togglePlay();
    }
},

我的理解

  1. 老师按下播放按钮
  2. togglePlay()被称为
  3. this.isPlaying = false 所以 playVideo() 被称为
  4. 开始为老师播放视频
  5. 然后 YouTube api 触发了一个 onStateChange 事件
  6. 这被发送到状态为 1 的 emittStateChange() 函数 (播放)
  7. 此状态通过推送器发送给学生 receiveStateChange() 函数
  8. 对于 case = 1 this.isPlaying() 设置为 false
  9. 调用切换播放以启动学生视频
  10. 学生视频开始缓冲,触发了 youtube api 再次发生 onStateChange 事件
  11. 状态 3(缓冲)然后通过推送器发送回老师
  12. 这会暂停教师视频以等待学生

问题:

  1. 教师视频停止时onStateChange事件还未触发 再次 在学生视频完成缓冲 并发送给学生之前。
  2. 这会停止学生视频,现在两个视频都暂停。

我想要的:

当学生视频正在缓冲时,我只想暂时暂停教师视频直到学生正在播放,然后同时播放。我只是不明白我应该如何打破这个以两个视频都被暂停而结束的循环。

我相信您一次可以发送多个事件。
因此,您可以向老师发送关于哪个学生的信息 "buffering" 以及任何其他相关信息。
然后在教师端,设置一个条件语句来评估消息。这样在函数中,如果存在这种情况,教师播放器就不会向学生发送控制指令。

以及在教师方面设置旁路,如果他们认为需要,他们可以随时 stop/pause 所有播放器上的视频。