change(ui/player): make video state observable
This commit is contained in:
parent
3b60b6d5f3
commit
7a309c529d
2 changed files with 92 additions and 20 deletions
|
|
@ -1,10 +1,11 @@
|
|||
import React, { useEffect, useRef } from 'react'
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { videoFeeds } from 'Player/MessageDistributor/managers/AssistManager';
|
||||
|
||||
interface Props {
|
||||
stream: MediaStream | null
|
||||
muted?: boolean,
|
||||
height?: number | string,
|
||||
setRemoteEnabled?: (isEnabled: boolean) => void
|
||||
stream: MediaStream | null;
|
||||
muted?: boolean;
|
||||
height?: number | string;
|
||||
setRemoteEnabled?: (isEnabled: boolean) => void;
|
||||
}
|
||||
|
||||
function VideoContainer({ stream, muted = false, height = 280, setRemoteEnabled }: Props) {
|
||||
|
|
@ -15,28 +16,55 @@ function VideoContainer({ stream, muted = false, height = 280, setRemoteEnabled
|
|||
if (ref.current) {
|
||||
ref.current.srcObject = stream;
|
||||
}
|
||||
}, [ ref.current, stream, stream.getVideoTracks()[0]?.getSettings().width ])
|
||||
}, [ref.current, stream, stream.getVideoTracks()[0]?.getSettings().width]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!stream) { return }
|
||||
if (!stream) {
|
||||
return;
|
||||
}
|
||||
const iid = setInterval(() => {
|
||||
const settings = stream.getVideoTracks()[0]?.getSettings()
|
||||
const isDummyVideoTrack = settings ? (settings.width === 2 || settings.frameRate === 0 || !settings.frameRate && !settings.width) : true
|
||||
const shouldBeEnabled = !isDummyVideoTrack
|
||||
console.log(stream.getVideoTracks())
|
||||
const settings = stream.getVideoTracks()[0]?.getSettings();
|
||||
const isDummyVideoTrack = settings
|
||||
? settings.width === 2 ||
|
||||
settings.frameRate === 0 ||
|
||||
(!settings.frameRate && !settings.width)
|
||||
: true;
|
||||
const shouldBeEnabled = !isDummyVideoTrack;
|
||||
console.log(stream.getVideoTracks());
|
||||
if (isEnabled !== shouldBeEnabled) {
|
||||
setEnabled(shouldBeEnabled)
|
||||
setRemoteEnabled?.(shouldBeEnabled)
|
||||
setEnabled(shouldBeEnabled);
|
||||
setRemoteEnabled?.(shouldBeEnabled);
|
||||
}
|
||||
}, 500)
|
||||
return () => clearInterval(iid)
|
||||
}, [ stream, isEnabled ])
|
||||
}, 500);
|
||||
return () => clearInterval(iid);
|
||||
}, [stream, isEnabled]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!stream) return;
|
||||
// @ts-ignore
|
||||
videoFeeds.observe((key, value) => {
|
||||
const track = stream.getVideoTracks()[0];
|
||||
if (key === track.id) {
|
||||
track.enabled = value;
|
||||
setEnabled(value);
|
||||
setRemoteEnabled?.(value);
|
||||
}
|
||||
});
|
||||
}, [stream]);
|
||||
|
||||
return (
|
||||
<div className={"flex-1"} style={{ display: isEnabled ? undefined : 'none', width: isEnabled ? undefined : "0px!important" , height: isEnabled ? undefined : "0px!important" , border: "1px solid grey" }}>
|
||||
<video autoPlay ref={ ref } muted={ muted } style={{ height: height }} />
|
||||
<div
|
||||
className={'flex-1'}
|
||||
style={{
|
||||
display: isEnabled ? undefined : 'none',
|
||||
width: isEnabled ? undefined : '0px!important',
|
||||
height: isEnabled ? undefined : '0px!important',
|
||||
border: '1px solid grey',
|
||||
}}
|
||||
>
|
||||
<video autoPlay ref={ref} muted={muted} style={{ height: height }} />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default VideoContainer
|
||||
export default VideoContainer;
|
||||
|
|
|
|||
|
|
@ -72,6 +72,41 @@ export const INITIAL_STATE: State = {
|
|||
|
||||
const MAX_RECONNECTION_COUNT = 4;
|
||||
|
||||
let handlers = Symbol('handlers');
|
||||
|
||||
interface VideoFeeds {
|
||||
[key: string]: boolean
|
||||
}
|
||||
|
||||
type ProxyResult<T extends {}> = T & {
|
||||
observe: (handler: (args: any) => any) => void
|
||||
[key: typeof handlers]: Function[]
|
||||
}
|
||||
|
||||
function makeObservable<T extends {}>(target: T): ProxyResult<T> {
|
||||
// @ts-ignore
|
||||
target[handlers] = [];
|
||||
|
||||
// @ts-ignore
|
||||
target.observe = function(handler) {
|
||||
this[handlers].push(handler);
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
return new Proxy(target, {
|
||||
set(target, property, value) {
|
||||
// @ts-ignore
|
||||
let success = Reflect.set(...arguments);
|
||||
if (success) {
|
||||
// @ts-ignore
|
||||
target[handlers].forEach(handler => handler(property, value));
|
||||
}
|
||||
return success;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const videoFeeds = makeObservable<VideoFeeds>({})
|
||||
|
||||
export default class AssistManager {
|
||||
|
||||
|
|
@ -204,6 +239,9 @@ export default class AssistManager {
|
|||
}
|
||||
}
|
||||
})
|
||||
socket.on('videofeed', ({ streamId, enabled }) => {
|
||||
videoFeeds[streamId] = enabled
|
||||
})
|
||||
socket.on('SESSION_DISCONNECTED', e => {
|
||||
waitingForMessages = true
|
||||
clearDisconnectTimeout()
|
||||
|
|
@ -366,6 +404,9 @@ export default class AssistManager {
|
|||
|
||||
call.on('stream', stream => {
|
||||
this.callArgs && this.callArgs.onStream(stream)
|
||||
stream.getVideoTracks().forEach(track => {
|
||||
videoFeeds[track.id] = track.enabled
|
||||
})
|
||||
});
|
||||
// call.peerConnection.addEventListener("track", e => console.log('newtrack',e.track))
|
||||
|
||||
|
|
@ -496,6 +537,9 @@ export default class AssistManager {
|
|||
|
||||
call.on('stream', stream => {
|
||||
getState().calling !== CallingState.OnCall && update({ calling: CallingState.OnCall })
|
||||
stream.getVideoTracks().forEach(track => {
|
||||
videoFeeds[track.id] = track.enabled
|
||||
})
|
||||
this.callArgs && this.callArgs.onStream(stream)
|
||||
});
|
||||
// call.peerConnection.addEventListener("track", e => console.log('newtrack',e.track))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue