在堆栈中加载视频元素之间存在明显的延迟

时间:2017-06-09 19:12:20

标签: javascript jquery video ember.js handlebars.js

我正在开发一款小型应用,可以使用视频播放器组件以多种方式显示视频。 目前我正在实现一个堆栈列表,它是一个容纳视频堆栈组件的容器,每个堆栈包含一个或多个视频播放器组件。

虽然从DOM加载了正确的视频,但是有一个明显的多秒滞后(在键盘响应方面),这似乎与当前播放的视频的结束和下一个视频的获取有关。叠加。

如何摆脱这种滞后?可以通过鼠标悬停或WASD键盘命令切换/选择视频(A:上一个,D:下一个),滞后可能导致键盘输入被注册延迟。

视频stack.hbs

{{video-player highlightedStyle=(string-append stackStyle borderStyle)
looping=(is-single-video videos) videoPos=selectedVidPos 
isMuted=(if (video-selected key selectedStackIndex) isMuted true) 
url=(if curVideo.teaser.isUrl curVideo.teaser.fileIdentifier 
(make-local-url modelIdentifier curVideo.teaser.fileIdentifier)) 
onClickCallback=(action 'stackClicked') 
onHoverCallback=(action 'stackHovered')
onEndedCallback=(action 'getNextVid')}}

视频stack.js

import Ember from 'ember';

export default Ember.Component.extend({
selectedVidPos: 0,
selectedStackIndex: 0,
stackStyle: '',
playerSize: '',
isMuted: true,

init() {
    this._super(...arguments);

    switch(this.get('videos').length){
        case 1:
            break;
        case 2:
            this.set('stackStyle', 'vid-shadows--2');
            break;
        case 3:
            this.set('stackStyle', 'vid-shadows--3');
            break;
        case 4:
            this.set('stackStyle', 'vid-shadows--4');
            break;
        default:
            this.set('stackStyle', 'vid-shadows--4');
            break;
    }
},
curVideo: Ember.computed('videos', 'selectedVidPos', function () {
    return this.get('videos')[this.get('selectedVidPos')];
}),
actions: {
    stackClicked() {
        this.get('onClickCallback') (this.get('videos'),      this.get('selectedVidPos'));

    },
    getNextVid() {
        let arrayLength = this.get('videos').length;
//check if there is only 1 video in the stack
        if (arrayLength === 1) {
            return;
        }
        let curArrayPos = parseInt(this.get('selectedVidPos'));
        this.set('selectedVidPos', (curArrayPos + 1) % arrayLength);
    },
    stackHovered() {
        this.get('onHoverCallback') (this.get('videos'), this.get('selectedStackIndex'));
    }
}
});

视频player.hbs

<video oncanplay={{action 'play'}} looping=true 
onended={{action 'ended'}} src={{url}} 
class="video-player__video {{highlightedStyle}} {{if playing '' 'video-
player__darken'}}" muted={{muted}} />

视频player.js

import Ember from 'ember';

export default Ember.Component.extend({
url: null,
looping: false,
playing: true,
muted: true,
highlightedStyle: '',

click(event) {
    this.get('onClickCallback') (this.get('videoPos'));
    event.stopPropagation();
},
mouseEnter() {
    this.get('onHoverCallback') (this.get('videoPos'));
},
willClearRender() {
this.set('playingObserver', null);
this.set('urlObserver', null);
},
playingObserver: Ember.observer('playing', function() {
if (this) {
  var p = this.get("playing");
  var videoElement = this.$().find("video").get(0);
  if (videoElement) {
    if (p) {
      videoElement.play();
    }
    else {
      videoElement.pause();
    }
  }
  else {
    console.log("No video element found!");
  }
}
}),
urlObserver: Ember.observer('url', function() {
if (this) {
  var videoElement = this.$().find("video").get(0);
  if (videoElement) {
    videoElement.load();
  }
  else {
    console.log("No video element found");
  }
}
}),
actions: {
  ended() {
    if (this.get('looping')) {
        this.$().find("video").get(0).play();
        console.log("video-player ended");
    }
    else {
        console.log(this.get('videoPos'));
        this.get('onEndedCallback') (this.get('videoPos'));
    }
},
play() {
  if (this.get('playing')) {
    this.$().find("video").get(0).play();
   }
  }
 }
});

我可以发布更多代码,如果它有助于揭示罪魁祸首,谢谢!

1 个答案:

答案 0 :(得分:0)

我找到了滞后的罪魁祸首。问题发生在父容器content-area.js中,它有一个被错误调用的resetTimeout操作,导致焦点不必要地循环,导致滞后。

还实现了关于渲染视频的关闭,以确保在视频堆栈中从一个视频到下一个视频的平滑加载。现在有2个视频对象,A&amp; B,从blob对象中获取并预加载,显示一个而另一个被隐藏。一旦显示的视频结束,它们就会换出,然后加载堆栈中的下一个视频。

视频stack.js

import Ember from 'ember';
import KeyboardControls from '../mixins/keyboard-controls';

export default Ember.Component.extend(KeyboardControls, {
displayVideoSelect: false,
displayVideoSelectTimeout: null,
displayVideo: false,
video: null,
videoPlaying: false,
keyboard: null,
backgroundVideoPos: 0,
backgroundVideoUrl: null,
backgroundVideoKeys: null,
selectionVideos: [],
stackListData: null,

showVideoSelect: function() {
  this.set('displayVideoSelect', true);
  this.send('resetTimeout');
},
hideVideoSelect: function() {
  this.set('displayVideoSelect', false);
  clearTimeout(this.get('displayVideoSelectTimeout'));
},
pauseVideo: function() {
  this.set('videoPlaying', !this.get('videoPlaying'));
  this.set('displayVideoSelect', !this.get('videoPlaying'));
  this.set('focus', this.get('videoPlaying'));
},
select: function() {
  this.set('videoPlaying', false);
  this.set('focus', false);
  this.showVideoSelect();
  this.send('resetTimeout');
},
cancel: function() {
  this.pauseVideo();
  this.send('resetTimeout');
},
goNext: function() {
  this.pauseVideo();
  this.send('resetTimeout');
},
goPrevious: function() {
  this.pauseVideo();
  this.send('resetTimeout');
},
updateFocus: function(param) {
if (param) {
  this.$().attr('tabindex', 2);
  this.$().focus();
}//if
else {
  this.$().attr('tabindex', -2);
  this.$().blur();
}//else
},

init() {
...
},

click() {
  this.set('focus', false);
  this.showVideoSelect();
},
actions: {
  videoSelected(sender, videoData) {
    ...
  },
  videoEnded() {
    this.set('focus', false);
    this.showVideoSelect();
    this.set('displayVideo', false);
  },
  cycleBackground() {
    ...
  },
  cancelPressed() {
    this.cancel();
  },
  resetTimeout() {
    let component = this;
    clearTimeout(this.get('displayVideoSelectTimeout'));

    let timeout = setTimeout(() => {
                  component.hideVideoSelect();
                  //This set command was responsible for the lag
                  component.set('focus', true);
                  }, this.get('data.config.ui.idle') * 1000);
    this.set('displayVideoSelectTimeout', timeout);
    }
  }
});

内容area.js

"scripts": [
    "../node_modules/jspdf/dist/jspdf.min.js",
     "../node_modules/jspdf-autotable/dist/jspdf.plugin.autotable.src.js"
  ],