Fix sync loop

This commit is contained in:
Ayushya Amitabh
2020-05-05 22:27:52 -04:00
parent 8aef416eda
commit c4bb242d7a
3 changed files with 43 additions and 42 deletions
+1 -1
View File
@@ -384,7 +384,7 @@ const updatePlayer = async (req, res) => {
.add({ .add({
uid: '<system>', uid: '<system>',
name: '', name: '',
text: `${userName} changed show to \n${player.showName}`, text: `${userName} changed show \n${player.showName ? 'to ' + player.showName : ''}`,
time: new Date(), time: new Date(),
}); });
} }
+2 -9
View File
@@ -16,14 +16,7 @@ import Delete from '@material-ui/icons/Delete';
import Gif from '@material-ui/icons/Gif'; import Gif from '@material-ui/icons/Gif';
import { Carousel } from '@giphy/react-components'; import { Carousel } from '@giphy/react-components';
import { GiphyFetch } from '@giphy/js-fetch-api'; import { GiphyFetch } from '@giphy/js-fetch-api';
import { import { SendMessageApi, LeaveRoomApi, DeleteRoomApi, UpdatePlayerApi, PLAYER_STATUS } from './Api';
SendMessageApi,
LeaveRoomApi,
DeleteRoomApi,
UpdatePlayerApi,
getPlayerSource,
PLAYER_STATUS,
} from './Api';
import { goTo } from 'route-lite'; import { goTo } from 'route-lite';
import Create from './Create'; import Create from './Create';
import VideoListener from './VideoListener'; import VideoListener from './VideoListener';
@@ -105,7 +98,7 @@ export default class Chat extends Component {
showChanged: showName !== this.state.player.showName, showChanged: showName !== this.state.player.showName,
userName: window.localStorage.getItem('watchPartyUserName'), userName: window.localStorage.getItem('watchPartyUserName'),
player: { player: {
status: showName !== this.state.player.showName ? PLAYER_STATUS.PAUSED : status, status,
showName, showName,
time, time,
source, source,
+40 -32
View File
@@ -11,6 +11,9 @@ export default class VideoListener {
source: '', source: '',
element: null, element: null,
}; };
this.server = {
status: PLAYER_STATUS.NOT_PLAYING,
};
this.listener = listener; this.listener = listener;
this.updateStatus = this.updateStatus.bind(this); this.updateStatus = this.updateStatus.bind(this);
this.firstTimeSync = this.firstTimeSync.bind(this); this.firstTimeSync = this.firstTimeSync.bind(this);
@@ -18,23 +21,34 @@ export default class VideoListener {
this.start = this.start.bind(this); this.start = this.start.bind(this);
} }
updateStatus(newStatus) { updateStatus(newStatus) {
const oldVideo = this.video;
this.video = Object.assign({}, this.video, newStatus); this.video = Object.assign({}, this.video, newStatus);
if (oldVideo.status !== this.video.status || Math.abs(this.video.time - oldVideo.time) > 1) if (this.server.status !== this.video.status) {
this.listener(this.video); if (this.video.showName) this.listener(this.video);
}
} }
doUpdate(serverPlayer) { doUpdate(serverPlayer) {
// SEEK this.server = serverPlayer;
if (serverPlayer.updatedBy !== window.localStorage.getItem('watchPartyUserUid')) { if (serverPlayer.updatedBy === window.localStorage.getItem('watchPartyUserUid')) return;
if (this.video.element && Math.abs(this.video.time - serverPlayer.time) > 1) { else {
// SEEK
console.log('GETTING UPDATE', serverPlayer, this.video);
if (this.video.element) {
switch (this.video.source) { switch (this.video.source) {
case PLAYER_SOURCE.NETFLIX: case PLAYER_SOURCE.NETFLIX:
if (
this.server.status === PLAYER_STATUS.PAUSED &&
this.video.status === PLAYER_STATUS.PLAYING
)
this.video.element.pause();
window.postMessage({ type: 'SEEK', time: serverPlayer.time * 1000 }, '*'); window.postMessage({ type: 'SEEK', time: serverPlayer.time * 1000 }, '*');
break; break;
case PLAYER_SOURCE.AMAZON: case PLAYER_SOURCE.AMAZON:
this.video.element.play(); this.video.element.play();
this.video.element.currentTime = serverPlayer.time; this.video.element.currentTime = serverPlayer.time;
break; break;
case PLAYER_SOURCE.DISNEY:
this.video.element.currentTime = serverPlayer.time;
break;
default: default:
break; break;
} }
@@ -89,29 +103,26 @@ export default class VideoListener {
const hepisode = document.querySelector('.metadata-area__third-line').innerHTML; const hepisode = document.querySelector('.metadata-area__third-line').innerHTML;
return hshow === '' && hepisode === '' ? null : hshow + '\n' + hepisode; return hshow === '' && hepisode === '' ? null : hshow + '\n' + hepisode;
case PLAYER_SOURCE.DISNEY: case PLAYER_SOURCE.DISNEY:
this.video.element.click(); this.video.element.parentElement.click();
await this.timeout(200); await this.timeout(200);
const dshow = document.querySelector('.title-field').innerHTML; const dshow = document.querySelector('.title-field')
const depisode = document.querySelector('.subtitle-field').innerHTML; ? document.querySelector('.title-field').innerHTML
: '';
const depisode = document.querySelector('.subtitle-field')
? document.querySelector('.subtitle-field').innerHTML
: '';
return dshow === '' && depisode === '' ? null : dshow + '\n' + depisode; return dshow === '' && depisode === '' ? null : dshow + '\n' + depisode;
default: default:
break; break;
} }
} }
async firstTimeSync(videoElement) { async firstTimeSync(videoElement) {
console.log('INSIDE FIRST TIME SYNC', videoElement);
this.updateStatus({ this.updateStatus({
element: videoElement, element: videoElement,
}); });
this.updateStatus({ this.updateStatus({
showName: await this.getShowName(), showName: await this.getShowName(),
}); });
if (videoElement.paused) {
this.updateStatus({
time: videoElement.currentTime,
status: PLAYER_STATUS.PAUSED,
});
}
if (videoElement.currentTime > 0 && !videoElement.paused) { if (videoElement.currentTime > 0 && !videoElement.paused) {
this.updateStatus({ this.updateStatus({
time: videoElement.currentTime, time: videoElement.currentTime,
@@ -132,12 +143,12 @@ export default class VideoListener {
time: videoElement.currentTime, time: videoElement.currentTime,
showName: await this.getShowName(), showName: await this.getShowName(),
}); });
videoElement.onended = (ev) => { videoElement.onended = async (ev) => {
this.updateStatus({ status: PLAYER_STATUS.NOT_PLAYING, showName: '', time: 0 }); this.updateStatus({ status: PLAYER_STATUS.NOT_PLAYING, showName: '', time: 0 });
}; };
} }
start() { async start() {
this.updateStatus({ source: getPlayerSource(), showName: this.getShowName() }); this.updateStatus({ source: getPlayerSource(), showName: await this.getShowName() });
switch (this.video.source) { switch (this.video.source) {
case PLAYER_SOURCE.NETFLIX: case PLAYER_SOURCE.NETFLIX:
const seekInject = `window.seekScriptLoaded=!0;var getVideoPlayer=function(){var e=window.netflix.appContext.state.playerApp.getAPI().videoPlayer,t=e.getAllPlayerSessionIds()[0];return e.getVideoPlayerBySessionId(t)},seekInteraction=function(e){if(e.source==window){if(e.data.type&&"SEEK"==e.data.type)getVideoPlayer().seek(e.data.time);e.data.type&&"teardown"==e.data.type&&(window.removeEventListener("message",seekInteraction,!1),window.seekScriptLoaded=!1)}};window.addEventListener("message",seekInteraction,!1);`; const seekInject = `window.seekScriptLoaded=!0;var getVideoPlayer=function(){var e=window.netflix.appContext.state.playerApp.getAPI().videoPlayer,t=e.getAllPlayerSessionIds()[0];return e.getVideoPlayerBySessionId(t)},seekInteraction=function(e){if(e.source==window){if(e.data.type&&"SEEK"==e.data.type)getVideoPlayer().seek(e.data.time);e.data.type&&"teardown"==e.data.type&&(window.removeEventListener("message",seekInteraction,!1),window.seekScriptLoaded=!1)}};window.addEventListener("message",seekInteraction,!1);`;
@@ -191,20 +202,17 @@ export default class VideoListener {
if (disneyVideoElement) { if (disneyVideoElement) {
this.firstTimeSync(disneyVideoElement); this.firstTimeSync(disneyVideoElement);
} else { } else {
document.addEventListener('DOMNodeInserted', (e) => { setInterval(
if (e.target && e.target.classList) { this.video.element
if (e.target.classList.contains('btm-media-player')) { ? null
const videoElement = document.querySelector('video.btm-media-client-element'); : () => {
if (videoElement) { var dve = document.querySelector('video.btm-media-client-element');
console.log(videoElement, this.video.element); if (dve !== null && (this.video.element !== dve || this.video.element === null)) {
if (!this.video.element || this.video.element !== videoElement) { this.firstTimeSync(dve);
console.log('FIRST TIME SYNC', videoElement);
this.firstTimeSync(videoElement);
} }
} },
} 1000
} );
});
} }
break; break;
case PLAYER_SOURCE.LOCAL: case PLAYER_SOURCE.LOCAL: