diff --git a/bigbluebutton-html5/imports/ui/components/external-video-player/component.jsx b/bigbluebutton-html5/imports/ui/components/external-video-player/component.jsx
index 3655917ed3..3c5b5db631 100644
--- a/bigbluebutton-html5/imports/ui/components/external-video-player/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/external-video-player/component.jsx
@@ -150,7 +150,8 @@ class VideoPlayer extends Component {
if (this.lastMessage === msg && msg === 'presenterReady') {
logger.debug("Ignoring a repeated presenterReady message");
} else {
- sendMessage(msg, params);
+ const timestamp = Date.now();
+ sendMessage(msg, { ...params, timestamp });
this.lastMessage = msg;
}
}
@@ -243,26 +244,26 @@ class VideoPlayer extends Component {
}, SYNC_INTERVAL_SECONDS * 1000);
} else {
- onMessage('play', ({ time }) => {
+ onMessage('play', ({ time, timestamp }) => {
const { hasPlayedBefore, player } = this;
if (!player || !hasPlayedBefore) {
return;
}
- player.seekTo(time);
+ this.seekTo(time, timestamp);
this.setState({ playing: true });
logger.debug({ logCode: 'external_video_client_play' }, 'Play external video');
});
- onMessage('stop', ({ time }) => {
+ onMessage('stop', ({ time, timestamp }) => {
const { hasPlayedBefore, player } = this;
if (!player || !hasPlayedBefore) {
return;
}
- player.seekTo(time);
+ this.seekTo(time, timestamp);
this.setState({ playing: false });
logger.debug({ logCode: 'external_video_client_stop' }, 'Stop external video');
@@ -281,38 +282,53 @@ class VideoPlayer extends Component {
onMessage('playerUpdate', (data) => {
const { hasPlayedBefore, player } = this;
const { playing } = this.state;
+ const { time, timestamp, rate, state } = data;
if (!player || !hasPlayedBefore) {
return;
}
- if (data.rate !== this.getCurrentPlaybackRate()) {
- this.setPlaybackRate(data.rate);
+ if (rate !== this.getCurrentPlaybackRate()) {
+ this.setPlaybackRate(rate);
logger.debug({
logCode: 'external_video_client_update_rate',
extraInfo: {
- newRate: data.rate,
+ newRate: rate,
},
}, 'Change external video playback rate.');
}
- if (Math.abs(this.getCurrentTime() - data.time) > SYNC_INTERVAL_SECONDS) {
- player.seekTo(data.time, true);
- logger.debug({
- logCode: 'external_video_client_update_seek',
- extraInfo: {
- time: data.time,
- },
- }, 'Seek external video to:');
- }
+ this.seekTo(time, timestamp);
- if (playing !== data.state) {
- this.setState({ playing: data.state });
+ if (playing !== state) {
+ this.setState({ playing: state });
}
});
}
}
+ seekTo(time, timestamp) {
+ const { player } = this;
+
+ if (!player) {
+ return Logger.error("No player on seek");
+ }
+
+ const curTimestamp = Date.now();
+ const timeDiff = time + (curTimestamp - timestamp)/1000;
+
+ if (Math.abs(this.getCurrentTime() - timeDiff) > SYNC_INTERVAL_SECONDS) {
+ player.seekTo(timeDiff, false);
+ logger.debug({
+ logCode: 'external_video_client_update_seek',
+ extraInfo: {
+ time,
+ timestamp,
+ },
+ }, 'Seek external video to:');
+ }
+ }
+
handleOnReady() {
const { hasPlayedBefore, playerIsReady } = this;