Upgrade to RingRTC v2.8.2 RC.6
This commit is contained in:
parent
4bf5a24efb
commit
b366967ca5
15 changed files with 214 additions and 183 deletions
|
@ -136,7 +136,7 @@
|
|||
"redux-ts-utils": "3.2.2",
|
||||
"reselect": "4.0.0",
|
||||
"rimraf": "2.6.2",
|
||||
"ringrtc": "https://github.com/signalapp/signal-ringrtc-node.git#7de95cffa71019e94c74fc43313c28eaf23c66e1",
|
||||
"ringrtc": "https://github.com/signalapp/signal-ringrtc-node.git#65fbea67295005fe1a9db2cbe85fce0d5297848d",
|
||||
"sanitize-filename": "1.6.3",
|
||||
"sanitize.css": "11.0.0",
|
||||
"semver": "5.4.1",
|
||||
|
|
|
@ -62,17 +62,10 @@ const createProps = (storyProps: Partial<PropsType> = {}): PropsType => ({
|
|||
cancelCall: action('cancel-call'),
|
||||
closeNeedPermissionScreen: action('close-need-permission-screen'),
|
||||
declineCall: action('decline-call'),
|
||||
// We allow `any` here because these are fake and actually come from RingRTC, which we
|
||||
// We allow `any` here because this is fake and actually comes from RingRTC, which we
|
||||
// can't import.
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
createCanvasVideoRenderer: () =>
|
||||
({
|
||||
setCanvas: noop,
|
||||
enable: noop,
|
||||
disable: noop,
|
||||
} as any),
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
getGroupCallVideoFrameSource: noop as any,
|
||||
/* eslint-enable @typescript-eslint/no-explicit-any */
|
||||
hangUp: action('hang-up'),
|
||||
i18n,
|
||||
me: {
|
||||
|
|
|
@ -12,7 +12,6 @@ import {
|
|||
CallEndedReason,
|
||||
CallMode,
|
||||
CallState,
|
||||
CanvasVideoRenderer,
|
||||
GroupCallJoinState,
|
||||
GroupCallRemoteParticipantType,
|
||||
VideoFrameSource,
|
||||
|
@ -47,7 +46,6 @@ export interface PropsType {
|
|||
activeCall?: ActiveCallType;
|
||||
availableCameras: Array<MediaDeviceInfo>;
|
||||
cancelCall: (_: CancelCallType) => void;
|
||||
createCanvasVideoRenderer: () => CanvasVideoRenderer;
|
||||
closeNeedPermissionScreen: () => void;
|
||||
getGroupCallVideoFrameSource: (
|
||||
conversationId: string,
|
||||
|
@ -89,7 +87,6 @@ const ActiveCallManager: React.FC<ActiveCallManagerPropsType> = ({
|
|||
availableCameras,
|
||||
cancelCall,
|
||||
closeNeedPermissionScreen,
|
||||
createCanvasVideoRenderer,
|
||||
hangUp,
|
||||
i18n,
|
||||
getGroupCallVideoFrameSource,
|
||||
|
@ -210,7 +207,6 @@ const ActiveCallManager: React.FC<ActiveCallManagerPropsType> = ({
|
|||
<CallingPip
|
||||
call={call}
|
||||
conversation={conversation}
|
||||
createCanvasVideoRenderer={createCanvasVideoRenderer}
|
||||
getGroupCallVideoFrameSource={getGroupCallVideoFrameSourceForActiveCall}
|
||||
hangUp={hangUp}
|
||||
hasLocalVideo={hasLocalVideo}
|
||||
|
@ -227,7 +223,6 @@ const ActiveCallManager: React.FC<ActiveCallManagerPropsType> = ({
|
|||
<CallScreen
|
||||
call={call}
|
||||
conversation={conversation}
|
||||
createCanvasVideoRenderer={createCanvasVideoRenderer}
|
||||
getGroupCallVideoFrameSource={getGroupCallVideoFrameSourceForActiveCall}
|
||||
hangUp={hangUp}
|
||||
hasLocalAudio={hasLocalAudio}
|
||||
|
|
|
@ -78,17 +78,10 @@ const createProps = (
|
|||
type: 'direct',
|
||||
lastUpdated: Date.now(),
|
||||
},
|
||||
// We allow `any` here because these are fake and actually come from RingRTC, which we
|
||||
// We allow `any` here because this is fake and actually comes from RingRTC, which we
|
||||
// can't import.
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
createCanvasVideoRenderer: () =>
|
||||
({
|
||||
setCanvas: noop,
|
||||
enable: noop,
|
||||
disable: noop,
|
||||
} as any),
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
getGroupCallVideoFrameSource: noop as any,
|
||||
/* eslint-enable @typescript-eslint/no-explicit-any */
|
||||
hangUp: action('hang-up'),
|
||||
hasLocalAudio: boolean('hasLocalAudio', overrideProps.hasLocalAudio || false),
|
||||
hasLocalVideo: boolean('hasLocalVideo', overrideProps.hasLocalVideo || false),
|
||||
|
|
|
@ -22,7 +22,6 @@ import {
|
|||
CallMode,
|
||||
CallState,
|
||||
GroupCallConnectionState,
|
||||
CanvasVideoRenderer,
|
||||
VideoFrameSource,
|
||||
} from '../types/Calling';
|
||||
import { ColorType } from '../types/Colors';
|
||||
|
@ -34,7 +33,6 @@ import { GroupCallRemoteParticipants } from './GroupCallRemoteParticipants';
|
|||
export type PropsType = {
|
||||
call: DirectCallStateType | GroupCallStateType;
|
||||
conversation: ConversationType;
|
||||
createCanvasVideoRenderer: () => CanvasVideoRenderer;
|
||||
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
|
||||
hangUp: (_: HangUpType) => void;
|
||||
hasLocalAudio: boolean;
|
||||
|
@ -62,7 +60,6 @@ export type PropsType = {
|
|||
export const CallScreen: React.FC<PropsType> = ({
|
||||
call,
|
||||
conversation,
|
||||
createCanvasVideoRenderer,
|
||||
getGroupCallVideoFrameSource,
|
||||
hangUp,
|
||||
hasLocalAudio,
|
||||
|
@ -174,7 +171,6 @@ export const CallScreen: React.FC<PropsType> = ({
|
|||
remoteParticipantsElement = (
|
||||
<GroupCallRemoteParticipants
|
||||
remoteParticipants={call.remoteParticipants}
|
||||
createCanvasVideoRenderer={createCanvasVideoRenderer}
|
||||
getGroupCallVideoFrameSource={getGroupCallVideoFrameSource}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -46,9 +46,7 @@ const defaultCall = {
|
|||
const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
|
||||
call: overrideProps.call || defaultCall,
|
||||
conversation: overrideProps.conversation || conversation,
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
createCanvasVideoRenderer: noop as any,
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
getGroupCallVideoFrameSource: noop as any,
|
||||
hangUp: action('hang-up'),
|
||||
hasLocalVideo: boolean('hasLocalVideo', overrideProps.hasLocalVideo || false),
|
||||
|
|
|
@ -6,7 +6,7 @@ import Tooltip from 'react-tooltip-lite';
|
|||
import { CallingPipRemoteVideo } from './CallingPipRemoteVideo';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { ConversationType } from '../state/ducks/conversations';
|
||||
import { CanvasVideoRenderer, VideoFrameSource } from '../types/Calling';
|
||||
import { VideoFrameSource } from '../types/Calling';
|
||||
import {
|
||||
DirectCallStateType,
|
||||
GroupCallStateType,
|
||||
|
@ -18,7 +18,6 @@ import {
|
|||
export type PropsType = {
|
||||
call: DirectCallStateType | GroupCallStateType;
|
||||
conversation: ConversationType;
|
||||
createCanvasVideoRenderer: () => CanvasVideoRenderer;
|
||||
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
|
||||
hangUp: (_: HangUpType) => void;
|
||||
hasLocalVideo: boolean;
|
||||
|
@ -36,7 +35,6 @@ const PIP_PADDING = 8;
|
|||
export const CallingPip = ({
|
||||
call,
|
||||
conversation,
|
||||
createCanvasVideoRenderer,
|
||||
getGroupCallVideoFrameSource,
|
||||
hangUp,
|
||||
hasLocalVideo,
|
||||
|
@ -171,7 +169,6 @@ export const CallingPip = ({
|
|||
<CallingPipRemoteVideo
|
||||
call={call}
|
||||
conversation={conversation}
|
||||
createCanvasVideoRenderer={createCanvasVideoRenderer}
|
||||
getGroupCallVideoFrameSource={getGroupCallVideoFrameSource}
|
||||
i18n={i18n}
|
||||
setRendererCanvas={setRendererCanvas}
|
||||
|
|
|
@ -8,11 +8,7 @@ import { DirectCallRemoteParticipant } from './DirectCallRemoteParticipant';
|
|||
import { GroupCallRemoteParticipant } from './GroupCallRemoteParticipant';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { ConversationType } from '../state/ducks/conversations';
|
||||
import {
|
||||
CallMode,
|
||||
CanvasVideoRenderer,
|
||||
VideoFrameSource,
|
||||
} from '../types/Calling';
|
||||
import { CallMode, VideoFrameSource } from '../types/Calling';
|
||||
import {
|
||||
DirectCallStateType,
|
||||
GroupCallStateType,
|
||||
|
@ -22,7 +18,6 @@ import {
|
|||
export interface PropsType {
|
||||
call: DirectCallStateType | GroupCallStateType;
|
||||
conversation: ConversationType;
|
||||
createCanvasVideoRenderer: () => CanvasVideoRenderer;
|
||||
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
|
||||
i18n: LocalizerType;
|
||||
setRendererCanvas: (_: SetRendererCanvasType) => void;
|
||||
|
@ -31,7 +26,6 @@ export interface PropsType {
|
|||
export const CallingPipRemoteVideo = ({
|
||||
call,
|
||||
conversation,
|
||||
createCanvasVideoRenderer,
|
||||
getGroupCallVideoFrameSource,
|
||||
i18n,
|
||||
setRendererCanvas,
|
||||
|
@ -87,16 +81,12 @@ export const CallingPipRemoteVideo = ({
|
|||
return (
|
||||
<div className="module-calling-pip__video--remote">
|
||||
<GroupCallRemoteParticipant
|
||||
isInPip
|
||||
key={speaker.demuxId}
|
||||
createCanvasVideoRenderer={createCanvasVideoRenderer}
|
||||
demuxId={speaker.demuxId}
|
||||
getGroupCallVideoFrameSource={getGroupCallVideoFrameSource}
|
||||
hasRemoteAudio={speaker.hasRemoteAudio}
|
||||
hasRemoteVideo={speaker.hasRemoteVideo}
|
||||
height="100%"
|
||||
left={0}
|
||||
top={0}
|
||||
width="100%"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,64 +1,147 @@
|
|||
// Copyright 2020 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { useRef, useEffect, CSSProperties } from 'react';
|
||||
import React, {
|
||||
useState,
|
||||
useRef,
|
||||
useMemo,
|
||||
useCallback,
|
||||
useEffect,
|
||||
CSSProperties,
|
||||
} from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { noop } from 'lodash';
|
||||
import { CanvasVideoRenderer, VideoFrameSource } from '../types/Calling';
|
||||
import { VideoFrameSource } from '../types/Calling';
|
||||
import { CallBackgroundBlur } from './CallBackgroundBlur';
|
||||
|
||||
interface PropsType {
|
||||
createCanvasVideoRenderer: () => CanvasVideoRenderer;
|
||||
// The max size video frame we'll support (in RGBA)
|
||||
const FRAME_BUFFER_SIZE = 1920 * 1080 * 4;
|
||||
|
||||
interface BasePropsType {
|
||||
demuxId: number;
|
||||
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
|
||||
hasRemoteAudio: boolean;
|
||||
hasRemoteVideo: boolean;
|
||||
height: number | string;
|
||||
left: number;
|
||||
top: number;
|
||||
width: number | string;
|
||||
}
|
||||
|
||||
export const GroupCallRemoteParticipant: React.FC<PropsType> = ({
|
||||
createCanvasVideoRenderer,
|
||||
demuxId,
|
||||
getGroupCallVideoFrameSource,
|
||||
hasRemoteAudio,
|
||||
hasRemoteVideo,
|
||||
height,
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
}) => {
|
||||
interface InPipPropsType {
|
||||
isInPip: true;
|
||||
}
|
||||
|
||||
interface NotInPipPropsType {
|
||||
isInPip?: false;
|
||||
width: number;
|
||||
height: number;
|
||||
left: number;
|
||||
top: number;
|
||||
}
|
||||
|
||||
type PropsType = BasePropsType & (InPipPropsType | NotInPipPropsType);
|
||||
|
||||
export const GroupCallRemoteParticipant: React.FC<PropsType> = props => {
|
||||
const {
|
||||
demuxId,
|
||||
getGroupCallVideoFrameSource,
|
||||
hasRemoteAudio,
|
||||
hasRemoteVideo,
|
||||
} = props;
|
||||
|
||||
const [canvasStyles, setCanvasStyles] = useState<CSSProperties>({});
|
||||
|
||||
const remoteVideoRef = useRef<HTMLCanvasElement | null>(null);
|
||||
const canvasVideoRendererRef = useRef(createCanvasVideoRenderer());
|
||||
const rafIdRef = useRef<number | null>(null);
|
||||
const frameBufferRef = useRef<ArrayBuffer>(
|
||||
new ArrayBuffer(FRAME_BUFFER_SIZE)
|
||||
);
|
||||
|
||||
const videoFrameSource = useMemo(
|
||||
() => getGroupCallVideoFrameSource(demuxId),
|
||||
[getGroupCallVideoFrameSource, demuxId]
|
||||
);
|
||||
|
||||
const renderVideoFrame = useCallback(() => {
|
||||
const canvasEl = remoteVideoRef.current;
|
||||
if (!canvasEl) {
|
||||
return;
|
||||
}
|
||||
|
||||
const context = canvasEl.getContext('2d');
|
||||
if (!context) {
|
||||
return;
|
||||
}
|
||||
|
||||
const frameDimensions = videoFrameSource.receiveVideoFrame(
|
||||
frameBufferRef.current
|
||||
);
|
||||
if (!frameDimensions) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [frameWidth, frameHeight] = frameDimensions;
|
||||
canvasEl.width = frameWidth;
|
||||
canvasEl.height = frameHeight;
|
||||
|
||||
context.putImageData(
|
||||
new ImageData(
|
||||
new Uint8ClampedArray(
|
||||
frameBufferRef.current,
|
||||
0,
|
||||
frameWidth * frameHeight * 4
|
||||
),
|
||||
frameWidth,
|
||||
frameHeight
|
||||
),
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
// If our `width` and `height` props don't match the canvas's aspect ratio, we want to
|
||||
// fill the container. This can happen when RingRTC gives us an inaccurate
|
||||
// `videoAspectRatio`, or if the container is an unexpected size.
|
||||
if (frameWidth > frameHeight) {
|
||||
setCanvasStyles({ width: '100%' });
|
||||
} else {
|
||||
setCanvasStyles({ height: '100%' });
|
||||
}
|
||||
}, [videoFrameSource]);
|
||||
|
||||
useEffect(() => {
|
||||
const canvasVideoRenderer = canvasVideoRendererRef.current;
|
||||
|
||||
if (hasRemoteVideo) {
|
||||
canvasVideoRenderer.setCanvas(remoteVideoRef);
|
||||
canvasVideoRenderer.enable(getGroupCallVideoFrameSource(demuxId));
|
||||
return () => {
|
||||
canvasVideoRenderer.disable();
|
||||
};
|
||||
if (!hasRemoteVideo) {
|
||||
return noop;
|
||||
}
|
||||
|
||||
canvasVideoRenderer.disable();
|
||||
return noop;
|
||||
}, [hasRemoteVideo, getGroupCallVideoFrameSource, demuxId]);
|
||||
const tick = () => {
|
||||
renderVideoFrame();
|
||||
rafIdRef.current = requestAnimationFrame(tick);
|
||||
};
|
||||
|
||||
// If our `width` and `height` props don't match the canvas's aspect ratio, we want to
|
||||
// fill the container. This can happen when RingRTC gives us an inaccurate
|
||||
// `videoAspectRatio`.
|
||||
const canvasStyles: CSSProperties = {};
|
||||
const canvasEl = remoteVideoRef.current;
|
||||
if (hasRemoteVideo && canvasEl) {
|
||||
if (canvasEl.width > canvasEl.height) {
|
||||
canvasStyles.width = '100%';
|
||||
} else {
|
||||
canvasStyles.height = '100%';
|
||||
}
|
||||
rafIdRef.current = requestAnimationFrame(tick);
|
||||
|
||||
return () => {
|
||||
if (rafIdRef.current) {
|
||||
cancelAnimationFrame(rafIdRef.current);
|
||||
rafIdRef.current = null;
|
||||
}
|
||||
};
|
||||
}, [hasRemoteVideo, renderVideoFrame, videoFrameSource]);
|
||||
|
||||
let containerStyles: CSSProperties;
|
||||
|
||||
// TypeScript isn't smart enough to know that `isInPip` by itself disambiguates the
|
||||
// types, so we have to use `props.isInPip` instead.
|
||||
// eslint-disable-next-line react/destructuring-assignment
|
||||
if (props.isInPip) {
|
||||
containerStyles = canvasStyles;
|
||||
} else {
|
||||
const { top, left, width, height } = props;
|
||||
|
||||
containerStyles = {
|
||||
height,
|
||||
left,
|
||||
position: 'absolute',
|
||||
top,
|
||||
width,
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -69,13 +152,7 @@ export const GroupCallRemoteParticipant: React.FC<PropsType> = ({
|
|||
'module-ongoing-call__group-call-remote-participant--audio-muted': !hasRemoteAudio,
|
||||
}
|
||||
)}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
width,
|
||||
height,
|
||||
top,
|
||||
left,
|
||||
}}
|
||||
style={containerStyles}
|
||||
>
|
||||
{hasRemoteVideo ? (
|
||||
<canvas
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import React, { useState, useMemo } from 'react';
|
||||
import Measure from 'react-measure';
|
||||
import { takeWhile, chunk, maxBy, flatten } from 'lodash';
|
||||
import { CanvasVideoRenderer, VideoFrameSource } from '../types/Calling';
|
||||
import { VideoFrameSource } from '../types/Calling';
|
||||
import { GroupCallParticipantInfoType } from '../state/ducks/calling';
|
||||
import { GroupCallRemoteParticipant } from './GroupCallRemoteParticipant';
|
||||
|
||||
|
@ -22,7 +22,6 @@ interface GridArrangement {
|
|||
}
|
||||
|
||||
interface PropsType {
|
||||
createCanvasVideoRenderer: () => CanvasVideoRenderer;
|
||||
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
|
||||
remoteParticipants: ReadonlyArray<GroupCallParticipantInfoType>;
|
||||
}
|
||||
|
@ -52,7 +51,6 @@ interface PropsType {
|
|||
// screen? The biggest scalar wins as the "best arrangement".
|
||||
// 4. Lay out this arrangement on the screen.
|
||||
export const GroupCallRemoteParticipants: React.FC<PropsType> = ({
|
||||
createCanvasVideoRenderer,
|
||||
getGroupCallVideoFrameSource,
|
||||
remoteParticipants,
|
||||
}) => {
|
||||
|
@ -196,7 +194,6 @@ export const GroupCallRemoteParticipants: React.FC<PropsType> = ({
|
|||
return (
|
||||
<GroupCallRemoteParticipant
|
||||
key={remoteParticipant.demuxId}
|
||||
createCanvasVideoRenderer={createCanvasVideoRenderer}
|
||||
demuxId={remoteParticipant.demuxId}
|
||||
getGroupCallVideoFrameSource={getGroupCallVideoFrameSource}
|
||||
hasRemoteAudio={remoteParticipant.hasRemoteAudio}
|
||||
|
|
|
@ -49,13 +49,16 @@ import { getOwn } from '../util/getOwn';
|
|||
import { fetchMembershipProof, getMembershipList } from '../groups';
|
||||
import { missingCaseError } from '../util/missingCaseError';
|
||||
|
||||
const RINGRTC_SFU_URL = 'https://sfu.voip.signal.org/';
|
||||
|
||||
const RINGRTC_HTTP_METHOD_TO_OUR_HTTP_METHOD: Map<
|
||||
HttpMethod,
|
||||
'GET' | 'PUT' | 'POST'
|
||||
'GET' | 'PUT' | 'POST' | 'DELETE'
|
||||
> = new Map([
|
||||
[HttpMethod.Get, 'GET'],
|
||||
[HttpMethod.Put, 'PUT'],
|
||||
[HttpMethod.Post, 'POST'],
|
||||
[HttpMethod.Delete, 'DELETE'],
|
||||
]);
|
||||
|
||||
export {
|
||||
|
@ -323,67 +326,73 @@ export class CallingClass {
|
|||
|
||||
let isRequestingMembershipProof = false;
|
||||
|
||||
const outerGroupCall = RingRTC.getGroupCall(groupIdBuffer, {
|
||||
onLocalDeviceStateChanged: groupCall => {
|
||||
const localDeviceState = groupCall.getLocalDeviceState();
|
||||
const outerGroupCall = RingRTC.getGroupCall(
|
||||
groupIdBuffer,
|
||||
RINGRTC_SFU_URL,
|
||||
{
|
||||
onLocalDeviceStateChanged: groupCall => {
|
||||
const localDeviceState = groupCall.getLocalDeviceState();
|
||||
|
||||
if (localDeviceState.connectionState === ConnectionState.NotConnected) {
|
||||
if (localDeviceState.videoMuted) {
|
||||
this.disableLocalCamera();
|
||||
}
|
||||
if (
|
||||
localDeviceState.connectionState === ConnectionState.NotConnected
|
||||
) {
|
||||
if (localDeviceState.videoMuted) {
|
||||
this.disableLocalCamera();
|
||||
}
|
||||
|
||||
delete this.callsByConversation[conversationId];
|
||||
} else {
|
||||
this.callsByConversation[conversationId] = groupCall;
|
||||
|
||||
if (localDeviceState.videoMuted) {
|
||||
this.disableLocalCamera();
|
||||
delete this.callsByConversation[conversationId];
|
||||
} else {
|
||||
this.enableLocalCamera();
|
||||
}
|
||||
}
|
||||
this.callsByConversation[conversationId] = groupCall;
|
||||
|
||||
this.syncGroupCallToRedux(conversationId, groupCall);
|
||||
},
|
||||
onRemoteDeviceStatesChanged: groupCall => {
|
||||
this.syncGroupCallToRedux(conversationId, groupCall);
|
||||
},
|
||||
onJoinedMembersChanged: groupCall => {
|
||||
this.syncGroupCallToRedux(conversationId, groupCall);
|
||||
},
|
||||
async requestMembershipProof(groupCall) {
|
||||
if (isRequestingMembershipProof) {
|
||||
return;
|
||||
}
|
||||
isRequestingMembershipProof = true;
|
||||
try {
|
||||
const proof = await fetchMembershipProof({
|
||||
publicParams,
|
||||
secretParams,
|
||||
});
|
||||
if (proof) {
|
||||
const proofArray = new TextEncoder().encode(proof);
|
||||
groupCall.setMembershipProof(proofArray.buffer);
|
||||
if (localDeviceState.videoMuted) {
|
||||
this.disableLocalCamera();
|
||||
} else {
|
||||
this.videoCapturer.enableCaptureAndSend(groupCall);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
window.log.error('Failed to fetch membership proof', err);
|
||||
} finally {
|
||||
isRequestingMembershipProof = false;
|
||||
}
|
||||
},
|
||||
requestGroupMembers(groupCall) {
|
||||
groupCall.setGroupMembers(
|
||||
getMembershipList(conversationId).map(
|
||||
member =>
|
||||
new GroupMemberInfo(
|
||||
uuidToArrayBuffer(member.uuid),
|
||||
member.uuidCiphertext
|
||||
)
|
||||
)
|
||||
);
|
||||
},
|
||||
onEnded: noop,
|
||||
});
|
||||
|
||||
this.syncGroupCallToRedux(conversationId, groupCall);
|
||||
},
|
||||
onRemoteDeviceStatesChanged: groupCall => {
|
||||
this.syncGroupCallToRedux(conversationId, groupCall);
|
||||
},
|
||||
onPeekChanged: groupCall => {
|
||||
this.syncGroupCallToRedux(conversationId, groupCall);
|
||||
},
|
||||
async requestMembershipProof(groupCall) {
|
||||
if (isRequestingMembershipProof) {
|
||||
return;
|
||||
}
|
||||
isRequestingMembershipProof = true;
|
||||
try {
|
||||
const proof = await fetchMembershipProof({
|
||||
publicParams,
|
||||
secretParams,
|
||||
});
|
||||
if (proof) {
|
||||
const proofArray = new TextEncoder().encode(proof);
|
||||
groupCall.setMembershipProof(proofArray.buffer);
|
||||
}
|
||||
} catch (err) {
|
||||
window.log.error('Failed to fetch membership proof', err);
|
||||
} finally {
|
||||
isRequestingMembershipProof = false;
|
||||
}
|
||||
},
|
||||
requestGroupMembers(groupCall) {
|
||||
groupCall.setGroupMembers(
|
||||
getMembershipList(conversationId).map(
|
||||
member =>
|
||||
new GroupMemberInfo(
|
||||
uuidToArrayBuffer(member.uuid),
|
||||
member.uuidCiphertext
|
||||
)
|
||||
)
|
||||
);
|
||||
},
|
||||
onEnded: noop,
|
||||
}
|
||||
);
|
||||
|
||||
if (!outerGroupCall) {
|
||||
// This should be very rare, likely due to RingRTC not being able to get a lock
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { CanvasVideoRenderer } from 'ringrtc';
|
||||
import { mapDispatchToProps } from '../actions';
|
||||
import { CallManager } from '../../components/CallManager';
|
||||
import { calling as callingService } from '../../services/calling';
|
||||
|
@ -21,8 +20,6 @@ function renderDeviceSelection(): JSX.Element {
|
|||
return <SmartCallingDeviceSelection />;
|
||||
}
|
||||
|
||||
const createCanvasVideoRenderer = () => new CanvasVideoRenderer();
|
||||
|
||||
const getGroupCallVideoFrameSource = callingService.getGroupCallVideoFrameSource.bind(
|
||||
callingService
|
||||
);
|
||||
|
@ -108,7 +105,6 @@ const mapStateToIncomingCallProp = (state: StateType) => {
|
|||
const mapStateToProps = (state: StateType) => ({
|
||||
activeCall: mapStateToActiveCallProp(state),
|
||||
availableCameras: state.calling.availableCameras,
|
||||
createCanvasVideoRenderer,
|
||||
getGroupCallVideoFrameSource,
|
||||
i18n: getIntl(state),
|
||||
incomingCall: mapStateToIncomingCallProp(state),
|
||||
|
|
|
@ -69,16 +69,6 @@ export interface GroupCallRemoteParticipantType {
|
|||
title: string;
|
||||
}
|
||||
|
||||
// Should match RingRTC's CanvasVideoRenderer
|
||||
interface Ref<T> {
|
||||
readonly current: T | null;
|
||||
}
|
||||
export interface CanvasVideoRenderer {
|
||||
setCanvas(canvas: Ref<HTMLCanvasElement> | undefined): void;
|
||||
enable(source: VideoFrameSource): void;
|
||||
disable(): void;
|
||||
}
|
||||
|
||||
// Should match RingRTC's VideoFrameSource
|
||||
export interface VideoFrameSource {
|
||||
receiveVideoFrame(buffer: ArrayBuffer): [number, number] | undefined;
|
||||
|
|
|
@ -14427,7 +14427,7 @@
|
|||
"rule": "React-useRef",
|
||||
"path": "ts/components/CallingPip.tsx",
|
||||
"line": " const videoContainerRef = React.useRef(null);",
|
||||
"lineNumber": 48,
|
||||
"lineNumber": 46,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-10-26T19:12:24.410Z",
|
||||
"reasonDetail": "Element is measured. Its HTML is not used."
|
||||
|
@ -14436,7 +14436,7 @@
|
|||
"rule": "React-useRef",
|
||||
"path": "ts/components/CallingPip.tsx",
|
||||
"line": " const localVideoRef = React.useRef(null);",
|
||||
"lineNumber": 49,
|
||||
"lineNumber": 47,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-10-26T19:12:24.410Z",
|
||||
"reasonDetail": "Used to get the local video element for rendering."
|
||||
|
@ -14571,7 +14571,7 @@
|
|||
"rule": "React-useRef",
|
||||
"path": "ts/components/GroupCallRemoteParticipant.js",
|
||||
"line": " const remoteVideoRef = react_1.useRef(null);",
|
||||
"lineNumber": 20,
|
||||
"lineNumber": 24,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-11-11T21:56:04.179Z",
|
||||
"reasonDetail": "Needed to render the remote video element."
|
||||
|
@ -14579,19 +14579,19 @@
|
|||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/GroupCallRemoteParticipant.js",
|
||||
"line": " const canvasVideoRendererRef = react_1.useRef(createCanvasVideoRenderer());",
|
||||
"lineNumber": 21,
|
||||
"line": " const rafIdRef = react_1.useRef(null);",
|
||||
"lineNumber": 25,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-11-11T21:56:04.179Z",
|
||||
"updated": "2020-11-17T16:24:25.480Z",
|
||||
"reasonDetail": "Doesn't touch the DOM."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/GroupCallRemoteParticipant.tsx",
|
||||
"line": " const canvasVideoRendererRef = useRef(createCanvasVideoRenderer());",
|
||||
"lineNumber": 34,
|
||||
"path": "ts/components/GroupCallRemoteParticipant.js",
|
||||
"line": " const frameBufferRef = react_1.useRef(new ArrayBuffer(FRAME_BUFFER_SIZE));",
|
||||
"lineNumber": 26,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-11-11T21:56:04.179Z",
|
||||
"updated": "2020-11-17T16:24:25.480Z",
|
||||
"reasonDetail": "Doesn't touch the DOM."
|
||||
},
|
||||
{
|
||||
|
|
|
@ -14300,9 +14300,9 @@ rimraf@~2.4.0:
|
|||
dependencies:
|
||||
glob "^6.0.1"
|
||||
|
||||
"ringrtc@https://github.com/signalapp/signal-ringrtc-node.git#7de95cffa71019e94c74fc43313c28eaf23c66e1":
|
||||
"ringrtc@https://github.com/signalapp/signal-ringrtc-node.git#65fbea67295005fe1a9db2cbe85fce0d5297848d":
|
||||
version "2.8.1"
|
||||
resolved "https://github.com/signalapp/signal-ringrtc-node.git#7de95cffa71019e94c74fc43313c28eaf23c66e1"
|
||||
resolved "https://github.com/signalapp/signal-ringrtc-node.git#65fbea67295005fe1a9db2cbe85fce0d5297848d"
|
||||
|
||||
ripemd160@^2.0.0, ripemd160@^2.0.1:
|
||||
version "2.0.1"
|
||||
|
|
Loading…
Add table
Reference in a new issue