Upgrade to RingRTC v2.8.2 RC.6

This commit is contained in:
Evan Hahn 2020-11-17 13:49:48 -06:00 committed by Josh Perez
parent 4bf5a24efb
commit b366967ca5
15 changed files with 214 additions and 183 deletions

View file

@ -136,7 +136,7 @@
"redux-ts-utils": "3.2.2", "redux-ts-utils": "3.2.2",
"reselect": "4.0.0", "reselect": "4.0.0",
"rimraf": "2.6.2", "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-filename": "1.6.3",
"sanitize.css": "11.0.0", "sanitize.css": "11.0.0",
"semver": "5.4.1", "semver": "5.4.1",

View file

@ -62,17 +62,10 @@ const createProps = (storyProps: Partial<PropsType> = {}): PropsType => ({
cancelCall: action('cancel-call'), cancelCall: action('cancel-call'),
closeNeedPermissionScreen: action('close-need-permission-screen'), closeNeedPermissionScreen: action('close-need-permission-screen'),
declineCall: action('decline-call'), 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. // can't import.
/* eslint-disable @typescript-eslint/no-explicit-any */ // eslint-disable-next-line @typescript-eslint/no-explicit-any
createCanvasVideoRenderer: () =>
({
setCanvas: noop,
enable: noop,
disable: noop,
} as any),
getGroupCallVideoFrameSource: noop as any, getGroupCallVideoFrameSource: noop as any,
/* eslint-enable @typescript-eslint/no-explicit-any */
hangUp: action('hang-up'), hangUp: action('hang-up'),
i18n, i18n,
me: { me: {

View file

@ -12,7 +12,6 @@ import {
CallEndedReason, CallEndedReason,
CallMode, CallMode,
CallState, CallState,
CanvasVideoRenderer,
GroupCallJoinState, GroupCallJoinState,
GroupCallRemoteParticipantType, GroupCallRemoteParticipantType,
VideoFrameSource, VideoFrameSource,
@ -47,7 +46,6 @@ export interface PropsType {
activeCall?: ActiveCallType; activeCall?: ActiveCallType;
availableCameras: Array<MediaDeviceInfo>; availableCameras: Array<MediaDeviceInfo>;
cancelCall: (_: CancelCallType) => void; cancelCall: (_: CancelCallType) => void;
createCanvasVideoRenderer: () => CanvasVideoRenderer;
closeNeedPermissionScreen: () => void; closeNeedPermissionScreen: () => void;
getGroupCallVideoFrameSource: ( getGroupCallVideoFrameSource: (
conversationId: string, conversationId: string,
@ -89,7 +87,6 @@ const ActiveCallManager: React.FC<ActiveCallManagerPropsType> = ({
availableCameras, availableCameras,
cancelCall, cancelCall,
closeNeedPermissionScreen, closeNeedPermissionScreen,
createCanvasVideoRenderer,
hangUp, hangUp,
i18n, i18n,
getGroupCallVideoFrameSource, getGroupCallVideoFrameSource,
@ -210,7 +207,6 @@ const ActiveCallManager: React.FC<ActiveCallManagerPropsType> = ({
<CallingPip <CallingPip
call={call} call={call}
conversation={conversation} conversation={conversation}
createCanvasVideoRenderer={createCanvasVideoRenderer}
getGroupCallVideoFrameSource={getGroupCallVideoFrameSourceForActiveCall} getGroupCallVideoFrameSource={getGroupCallVideoFrameSourceForActiveCall}
hangUp={hangUp} hangUp={hangUp}
hasLocalVideo={hasLocalVideo} hasLocalVideo={hasLocalVideo}
@ -227,7 +223,6 @@ const ActiveCallManager: React.FC<ActiveCallManagerPropsType> = ({
<CallScreen <CallScreen
call={call} call={call}
conversation={conversation} conversation={conversation}
createCanvasVideoRenderer={createCanvasVideoRenderer}
getGroupCallVideoFrameSource={getGroupCallVideoFrameSourceForActiveCall} getGroupCallVideoFrameSource={getGroupCallVideoFrameSourceForActiveCall}
hangUp={hangUp} hangUp={hangUp}
hasLocalAudio={hasLocalAudio} hasLocalAudio={hasLocalAudio}

View file

@ -78,17 +78,10 @@ const createProps = (
type: 'direct', type: 'direct',
lastUpdated: Date.now(), 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. // can't import.
/* eslint-disable @typescript-eslint/no-explicit-any */ // eslint-disable-next-line @typescript-eslint/no-explicit-any
createCanvasVideoRenderer: () =>
({
setCanvas: noop,
enable: noop,
disable: noop,
} as any),
getGroupCallVideoFrameSource: noop as any, getGroupCallVideoFrameSource: noop as any,
/* eslint-enable @typescript-eslint/no-explicit-any */
hangUp: action('hang-up'), hangUp: action('hang-up'),
hasLocalAudio: boolean('hasLocalAudio', overrideProps.hasLocalAudio || false), hasLocalAudio: boolean('hasLocalAudio', overrideProps.hasLocalAudio || false),
hasLocalVideo: boolean('hasLocalVideo', overrideProps.hasLocalVideo || false), hasLocalVideo: boolean('hasLocalVideo', overrideProps.hasLocalVideo || false),

View file

@ -22,7 +22,6 @@ import {
CallMode, CallMode,
CallState, CallState,
GroupCallConnectionState, GroupCallConnectionState,
CanvasVideoRenderer,
VideoFrameSource, VideoFrameSource,
} from '../types/Calling'; } from '../types/Calling';
import { ColorType } from '../types/Colors'; import { ColorType } from '../types/Colors';
@ -34,7 +33,6 @@ import { GroupCallRemoteParticipants } from './GroupCallRemoteParticipants';
export type PropsType = { export type PropsType = {
call: DirectCallStateType | GroupCallStateType; call: DirectCallStateType | GroupCallStateType;
conversation: ConversationType; conversation: ConversationType;
createCanvasVideoRenderer: () => CanvasVideoRenderer;
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource; getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
hangUp: (_: HangUpType) => void; hangUp: (_: HangUpType) => void;
hasLocalAudio: boolean; hasLocalAudio: boolean;
@ -62,7 +60,6 @@ export type PropsType = {
export const CallScreen: React.FC<PropsType> = ({ export const CallScreen: React.FC<PropsType> = ({
call, call,
conversation, conversation,
createCanvasVideoRenderer,
getGroupCallVideoFrameSource, getGroupCallVideoFrameSource,
hangUp, hangUp,
hasLocalAudio, hasLocalAudio,
@ -174,7 +171,6 @@ export const CallScreen: React.FC<PropsType> = ({
remoteParticipantsElement = ( remoteParticipantsElement = (
<GroupCallRemoteParticipants <GroupCallRemoteParticipants
remoteParticipants={call.remoteParticipants} remoteParticipants={call.remoteParticipants}
createCanvasVideoRenderer={createCanvasVideoRenderer}
getGroupCallVideoFrameSource={getGroupCallVideoFrameSource} getGroupCallVideoFrameSource={getGroupCallVideoFrameSource}
/> />
); );

View file

@ -46,9 +46,7 @@ const defaultCall = {
const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
call: overrideProps.call || defaultCall, call: overrideProps.call || defaultCall,
conversation: overrideProps.conversation || conversation, conversation: overrideProps.conversation || conversation,
/* eslint-disable @typescript-eslint/no-explicit-any */ // eslint-disable-next-line @typescript-eslint/no-explicit-any
createCanvasVideoRenderer: noop as any,
/* eslint-disable @typescript-eslint/no-explicit-any */
getGroupCallVideoFrameSource: noop as any, getGroupCallVideoFrameSource: noop as any,
hangUp: action('hang-up'), hangUp: action('hang-up'),
hasLocalVideo: boolean('hasLocalVideo', overrideProps.hasLocalVideo || false), hasLocalVideo: boolean('hasLocalVideo', overrideProps.hasLocalVideo || false),

View file

@ -6,7 +6,7 @@ import Tooltip from 'react-tooltip-lite';
import { CallingPipRemoteVideo } from './CallingPipRemoteVideo'; import { CallingPipRemoteVideo } from './CallingPipRemoteVideo';
import { LocalizerType } from '../types/Util'; import { LocalizerType } from '../types/Util';
import { ConversationType } from '../state/ducks/conversations'; import { ConversationType } from '../state/ducks/conversations';
import { CanvasVideoRenderer, VideoFrameSource } from '../types/Calling'; import { VideoFrameSource } from '../types/Calling';
import { import {
DirectCallStateType, DirectCallStateType,
GroupCallStateType, GroupCallStateType,
@ -18,7 +18,6 @@ import {
export type PropsType = { export type PropsType = {
call: DirectCallStateType | GroupCallStateType; call: DirectCallStateType | GroupCallStateType;
conversation: ConversationType; conversation: ConversationType;
createCanvasVideoRenderer: () => CanvasVideoRenderer;
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource; getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
hangUp: (_: HangUpType) => void; hangUp: (_: HangUpType) => void;
hasLocalVideo: boolean; hasLocalVideo: boolean;
@ -36,7 +35,6 @@ const PIP_PADDING = 8;
export const CallingPip = ({ export const CallingPip = ({
call, call,
conversation, conversation,
createCanvasVideoRenderer,
getGroupCallVideoFrameSource, getGroupCallVideoFrameSource,
hangUp, hangUp,
hasLocalVideo, hasLocalVideo,
@ -171,7 +169,6 @@ export const CallingPip = ({
<CallingPipRemoteVideo <CallingPipRemoteVideo
call={call} call={call}
conversation={conversation} conversation={conversation}
createCanvasVideoRenderer={createCanvasVideoRenderer}
getGroupCallVideoFrameSource={getGroupCallVideoFrameSource} getGroupCallVideoFrameSource={getGroupCallVideoFrameSource}
i18n={i18n} i18n={i18n}
setRendererCanvas={setRendererCanvas} setRendererCanvas={setRendererCanvas}

View file

@ -8,11 +8,7 @@ import { DirectCallRemoteParticipant } from './DirectCallRemoteParticipant';
import { GroupCallRemoteParticipant } from './GroupCallRemoteParticipant'; import { GroupCallRemoteParticipant } from './GroupCallRemoteParticipant';
import { LocalizerType } from '../types/Util'; import { LocalizerType } from '../types/Util';
import { ConversationType } from '../state/ducks/conversations'; import { ConversationType } from '../state/ducks/conversations';
import { import { CallMode, VideoFrameSource } from '../types/Calling';
CallMode,
CanvasVideoRenderer,
VideoFrameSource,
} from '../types/Calling';
import { import {
DirectCallStateType, DirectCallStateType,
GroupCallStateType, GroupCallStateType,
@ -22,7 +18,6 @@ import {
export interface PropsType { export interface PropsType {
call: DirectCallStateType | GroupCallStateType; call: DirectCallStateType | GroupCallStateType;
conversation: ConversationType; conversation: ConversationType;
createCanvasVideoRenderer: () => CanvasVideoRenderer;
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource; getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
i18n: LocalizerType; i18n: LocalizerType;
setRendererCanvas: (_: SetRendererCanvasType) => void; setRendererCanvas: (_: SetRendererCanvasType) => void;
@ -31,7 +26,6 @@ export interface PropsType {
export const CallingPipRemoteVideo = ({ export const CallingPipRemoteVideo = ({
call, call,
conversation, conversation,
createCanvasVideoRenderer,
getGroupCallVideoFrameSource, getGroupCallVideoFrameSource,
i18n, i18n,
setRendererCanvas, setRendererCanvas,
@ -87,16 +81,12 @@ export const CallingPipRemoteVideo = ({
return ( return (
<div className="module-calling-pip__video--remote"> <div className="module-calling-pip__video--remote">
<GroupCallRemoteParticipant <GroupCallRemoteParticipant
isInPip
key={speaker.demuxId} key={speaker.demuxId}
createCanvasVideoRenderer={createCanvasVideoRenderer}
demuxId={speaker.demuxId} demuxId={speaker.demuxId}
getGroupCallVideoFrameSource={getGroupCallVideoFrameSource} getGroupCallVideoFrameSource={getGroupCallVideoFrameSource}
hasRemoteAudio={speaker.hasRemoteAudio} hasRemoteAudio={speaker.hasRemoteAudio}
hasRemoteVideo={speaker.hasRemoteVideo} hasRemoteVideo={speaker.hasRemoteVideo}
height="100%"
left={0}
top={0}
width="100%"
/> />
</div> </div>
); );

View file

@ -1,64 +1,147 @@
// Copyright 2020 Signal Messenger, LLC // Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // 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 classNames from 'classnames';
import { noop } from 'lodash'; import { noop } from 'lodash';
import { CanvasVideoRenderer, VideoFrameSource } from '../types/Calling'; import { VideoFrameSource } from '../types/Calling';
import { CallBackgroundBlur } from './CallBackgroundBlur'; import { CallBackgroundBlur } from './CallBackgroundBlur';
interface PropsType { // The max size video frame we'll support (in RGBA)
createCanvasVideoRenderer: () => CanvasVideoRenderer; const FRAME_BUFFER_SIZE = 1920 * 1080 * 4;
interface BasePropsType {
demuxId: number; demuxId: number;
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource; getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
hasRemoteAudio: boolean; hasRemoteAudio: boolean;
hasRemoteVideo: boolean; hasRemoteVideo: boolean;
height: number | string;
left: number;
top: number;
width: number | string;
} }
export const GroupCallRemoteParticipant: React.FC<PropsType> = ({ interface InPipPropsType {
createCanvasVideoRenderer, 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, demuxId,
getGroupCallVideoFrameSource, getGroupCallVideoFrameSource,
hasRemoteAudio, hasRemoteAudio,
hasRemoteVideo, hasRemoteVideo,
height, } = props;
left,
top, const [canvasStyles, setCanvasStyles] = useState<CSSProperties>({});
width,
}) => {
const remoteVideoRef = useRef<HTMLCanvasElement | null>(null); 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)
);
useEffect(() => { const videoFrameSource = useMemo(
const canvasVideoRenderer = canvasVideoRendererRef.current; () => getGroupCallVideoFrameSource(demuxId),
[getGroupCallVideoFrameSource, demuxId]
);
if (hasRemoteVideo) { const renderVideoFrame = useCallback(() => {
canvasVideoRenderer.setCanvas(remoteVideoRef); const canvasEl = remoteVideoRef.current;
canvasVideoRenderer.enable(getGroupCallVideoFrameSource(demuxId)); if (!canvasEl) {
return () => { return;
canvasVideoRenderer.disable();
};
} }
canvasVideoRenderer.disable(); const context = canvasEl.getContext('2d');
return noop; if (!context) {
}, [hasRemoteVideo, getGroupCallVideoFrameSource, demuxId]); 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 // 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 // fill the container. This can happen when RingRTC gives us an inaccurate
// `videoAspectRatio`. // `videoAspectRatio`, or if the container is an unexpected size.
const canvasStyles: CSSProperties = {}; if (frameWidth > frameHeight) {
const canvasEl = remoteVideoRef.current; setCanvasStyles({ width: '100%' });
if (hasRemoteVideo && canvasEl) {
if (canvasEl.width > canvasEl.height) {
canvasStyles.width = '100%';
} else { } else {
canvasStyles.height = '100%'; setCanvasStyles({ height: '100%' });
} }
}, [videoFrameSource]);
useEffect(() => {
if (!hasRemoteVideo) {
return noop;
}
const tick = () => {
renderVideoFrame();
rafIdRef.current = requestAnimationFrame(tick);
};
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 ( return (
@ -69,13 +152,7 @@ export const GroupCallRemoteParticipant: React.FC<PropsType> = ({
'module-ongoing-call__group-call-remote-participant--audio-muted': !hasRemoteAudio, 'module-ongoing-call__group-call-remote-participant--audio-muted': !hasRemoteAudio,
} }
)} )}
style={{ style={containerStyles}
position: 'absolute',
width,
height,
top,
left,
}}
> >
{hasRemoteVideo ? ( {hasRemoteVideo ? (
<canvas <canvas

View file

@ -4,7 +4,7 @@
import React, { useState, useMemo } from 'react'; import React, { useState, useMemo } from 'react';
import Measure from 'react-measure'; import Measure from 'react-measure';
import { takeWhile, chunk, maxBy, flatten } from 'lodash'; 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 { GroupCallParticipantInfoType } from '../state/ducks/calling';
import { GroupCallRemoteParticipant } from './GroupCallRemoteParticipant'; import { GroupCallRemoteParticipant } from './GroupCallRemoteParticipant';
@ -22,7 +22,6 @@ interface GridArrangement {
} }
interface PropsType { interface PropsType {
createCanvasVideoRenderer: () => CanvasVideoRenderer;
getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource; getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource;
remoteParticipants: ReadonlyArray<GroupCallParticipantInfoType>; remoteParticipants: ReadonlyArray<GroupCallParticipantInfoType>;
} }
@ -52,7 +51,6 @@ interface PropsType {
// screen? The biggest scalar wins as the "best arrangement". // screen? The biggest scalar wins as the "best arrangement".
// 4. Lay out this arrangement on the screen. // 4. Lay out this arrangement on the screen.
export const GroupCallRemoteParticipants: React.FC<PropsType> = ({ export const GroupCallRemoteParticipants: React.FC<PropsType> = ({
createCanvasVideoRenderer,
getGroupCallVideoFrameSource, getGroupCallVideoFrameSource,
remoteParticipants, remoteParticipants,
}) => { }) => {
@ -196,7 +194,6 @@ export const GroupCallRemoteParticipants: React.FC<PropsType> = ({
return ( return (
<GroupCallRemoteParticipant <GroupCallRemoteParticipant
key={remoteParticipant.demuxId} key={remoteParticipant.demuxId}
createCanvasVideoRenderer={createCanvasVideoRenderer}
demuxId={remoteParticipant.demuxId} demuxId={remoteParticipant.demuxId}
getGroupCallVideoFrameSource={getGroupCallVideoFrameSource} getGroupCallVideoFrameSource={getGroupCallVideoFrameSource}
hasRemoteAudio={remoteParticipant.hasRemoteAudio} hasRemoteAudio={remoteParticipant.hasRemoteAudio}

View file

@ -49,13 +49,16 @@ import { getOwn } from '../util/getOwn';
import { fetchMembershipProof, getMembershipList } from '../groups'; import { fetchMembershipProof, getMembershipList } from '../groups';
import { missingCaseError } from '../util/missingCaseError'; import { missingCaseError } from '../util/missingCaseError';
const RINGRTC_SFU_URL = 'https://sfu.voip.signal.org/';
const RINGRTC_HTTP_METHOD_TO_OUR_HTTP_METHOD: Map< const RINGRTC_HTTP_METHOD_TO_OUR_HTTP_METHOD: Map<
HttpMethod, HttpMethod,
'GET' | 'PUT' | 'POST' 'GET' | 'PUT' | 'POST' | 'DELETE'
> = new Map([ > = new Map([
[HttpMethod.Get, 'GET'], [HttpMethod.Get, 'GET'],
[HttpMethod.Put, 'PUT'], [HttpMethod.Put, 'PUT'],
[HttpMethod.Post, 'POST'], [HttpMethod.Post, 'POST'],
[HttpMethod.Delete, 'DELETE'],
]); ]);
export { export {
@ -323,11 +326,16 @@ export class CallingClass {
let isRequestingMembershipProof = false; let isRequestingMembershipProof = false;
const outerGroupCall = RingRTC.getGroupCall(groupIdBuffer, { const outerGroupCall = RingRTC.getGroupCall(
groupIdBuffer,
RINGRTC_SFU_URL,
{
onLocalDeviceStateChanged: groupCall => { onLocalDeviceStateChanged: groupCall => {
const localDeviceState = groupCall.getLocalDeviceState(); const localDeviceState = groupCall.getLocalDeviceState();
if (localDeviceState.connectionState === ConnectionState.NotConnected) { if (
localDeviceState.connectionState === ConnectionState.NotConnected
) {
if (localDeviceState.videoMuted) { if (localDeviceState.videoMuted) {
this.disableLocalCamera(); this.disableLocalCamera();
} }
@ -339,7 +347,7 @@ export class CallingClass {
if (localDeviceState.videoMuted) { if (localDeviceState.videoMuted) {
this.disableLocalCamera(); this.disableLocalCamera();
} else { } else {
this.enableLocalCamera(); this.videoCapturer.enableCaptureAndSend(groupCall);
} }
} }
@ -348,7 +356,7 @@ export class CallingClass {
onRemoteDeviceStatesChanged: groupCall => { onRemoteDeviceStatesChanged: groupCall => {
this.syncGroupCallToRedux(conversationId, groupCall); this.syncGroupCallToRedux(conversationId, groupCall);
}, },
onJoinedMembersChanged: groupCall => { onPeekChanged: groupCall => {
this.syncGroupCallToRedux(conversationId, groupCall); this.syncGroupCallToRedux(conversationId, groupCall);
}, },
async requestMembershipProof(groupCall) { async requestMembershipProof(groupCall) {
@ -383,7 +391,8 @@ export class CallingClass {
); );
}, },
onEnded: noop, onEnded: noop,
}); }
);
if (!outerGroupCall) { if (!outerGroupCall) {
// This should be very rare, likely due to RingRTC not being able to get a lock // This should be very rare, likely due to RingRTC not being able to get a lock

View file

@ -3,7 +3,6 @@
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { CanvasVideoRenderer } from 'ringrtc';
import { mapDispatchToProps } from '../actions'; import { mapDispatchToProps } from '../actions';
import { CallManager } from '../../components/CallManager'; import { CallManager } from '../../components/CallManager';
import { calling as callingService } from '../../services/calling'; import { calling as callingService } from '../../services/calling';
@ -21,8 +20,6 @@ function renderDeviceSelection(): JSX.Element {
return <SmartCallingDeviceSelection />; return <SmartCallingDeviceSelection />;
} }
const createCanvasVideoRenderer = () => new CanvasVideoRenderer();
const getGroupCallVideoFrameSource = callingService.getGroupCallVideoFrameSource.bind( const getGroupCallVideoFrameSource = callingService.getGroupCallVideoFrameSource.bind(
callingService callingService
); );
@ -108,7 +105,6 @@ const mapStateToIncomingCallProp = (state: StateType) => {
const mapStateToProps = (state: StateType) => ({ const mapStateToProps = (state: StateType) => ({
activeCall: mapStateToActiveCallProp(state), activeCall: mapStateToActiveCallProp(state),
availableCameras: state.calling.availableCameras, availableCameras: state.calling.availableCameras,
createCanvasVideoRenderer,
getGroupCallVideoFrameSource, getGroupCallVideoFrameSource,
i18n: getIntl(state), i18n: getIntl(state),
incomingCall: mapStateToIncomingCallProp(state), incomingCall: mapStateToIncomingCallProp(state),

View file

@ -69,16 +69,6 @@ export interface GroupCallRemoteParticipantType {
title: string; 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 // Should match RingRTC's VideoFrameSource
export interface VideoFrameSource { export interface VideoFrameSource {
receiveVideoFrame(buffer: ArrayBuffer): [number, number] | undefined; receiveVideoFrame(buffer: ArrayBuffer): [number, number] | undefined;

View file

@ -14427,7 +14427,7 @@
"rule": "React-useRef", "rule": "React-useRef",
"path": "ts/components/CallingPip.tsx", "path": "ts/components/CallingPip.tsx",
"line": " const videoContainerRef = React.useRef(null);", "line": " const videoContainerRef = React.useRef(null);",
"lineNumber": 48, "lineNumber": 46,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2020-10-26T19:12:24.410Z", "updated": "2020-10-26T19:12:24.410Z",
"reasonDetail": "Element is measured. Its HTML is not used." "reasonDetail": "Element is measured. Its HTML is not used."
@ -14436,7 +14436,7 @@
"rule": "React-useRef", "rule": "React-useRef",
"path": "ts/components/CallingPip.tsx", "path": "ts/components/CallingPip.tsx",
"line": " const localVideoRef = React.useRef(null);", "line": " const localVideoRef = React.useRef(null);",
"lineNumber": 49, "lineNumber": 47,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2020-10-26T19:12:24.410Z", "updated": "2020-10-26T19:12:24.410Z",
"reasonDetail": "Used to get the local video element for rendering." "reasonDetail": "Used to get the local video element for rendering."
@ -14571,7 +14571,7 @@
"rule": "React-useRef", "rule": "React-useRef",
"path": "ts/components/GroupCallRemoteParticipant.js", "path": "ts/components/GroupCallRemoteParticipant.js",
"line": " const remoteVideoRef = react_1.useRef(null);", "line": " const remoteVideoRef = react_1.useRef(null);",
"lineNumber": 20, "lineNumber": 24,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2020-11-11T21:56:04.179Z", "updated": "2020-11-11T21:56:04.179Z",
"reasonDetail": "Needed to render the remote video element." "reasonDetail": "Needed to render the remote video element."
@ -14579,19 +14579,19 @@
{ {
"rule": "React-useRef", "rule": "React-useRef",
"path": "ts/components/GroupCallRemoteParticipant.js", "path": "ts/components/GroupCallRemoteParticipant.js",
"line": " const canvasVideoRendererRef = react_1.useRef(createCanvasVideoRenderer());", "line": " const rafIdRef = react_1.useRef(null);",
"lineNumber": 21, "lineNumber": 25,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2020-11-11T21:56:04.179Z", "updated": "2020-11-17T16:24:25.480Z",
"reasonDetail": "Doesn't touch the DOM." "reasonDetail": "Doesn't touch the DOM."
}, },
{ {
"rule": "React-useRef", "rule": "React-useRef",
"path": "ts/components/GroupCallRemoteParticipant.tsx", "path": "ts/components/GroupCallRemoteParticipant.js",
"line": " const canvasVideoRendererRef = useRef(createCanvasVideoRenderer());", "line": " const frameBufferRef = react_1.useRef(new ArrayBuffer(FRAME_BUFFER_SIZE));",
"lineNumber": 34, "lineNumber": 26,
"reasonCategory": "usageTrusted", "reasonCategory": "usageTrusted",
"updated": "2020-11-11T21:56:04.179Z", "updated": "2020-11-17T16:24:25.480Z",
"reasonDetail": "Doesn't touch the DOM." "reasonDetail": "Doesn't touch the DOM."
}, },
{ {

View file

@ -14300,9 +14300,9 @@ rimraf@~2.4.0:
dependencies: dependencies:
glob "^6.0.1" 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" 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: ripemd160@^2.0.0, ripemd160@^2.0.1:
version "2.0.1" version "2.0.1"