mirror of https://github.com/vector-im/riot-web
Remove audio element from VideoFeed
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>pull/21833/head
parent
b612b252e1
commit
f3a7ffca60
|
@ -21,7 +21,6 @@ import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import { CallFeed, CallFeedEvent } from 'matrix-js-sdk/src/webrtc/callFeed';
|
import { CallFeed, CallFeedEvent } from 'matrix-js-sdk/src/webrtc/callFeed';
|
||||||
import { logger } from 'matrix-js-sdk/src/logger';
|
import { logger } from 'matrix-js-sdk/src/logger';
|
||||||
import MemberAvatar from "../avatars/MemberAvatar"
|
import MemberAvatar from "../avatars/MemberAvatar"
|
||||||
import CallMediaHandler from "../../../CallMediaHandler";
|
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
|
@ -45,11 +44,9 @@ interface IState {
|
||||||
videoMuted: boolean;
|
videoMuted: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@replaceableComponent("views.voip.VideoFeed")
|
@replaceableComponent("views.voip.VideoFeed")
|
||||||
export default class VideoFeed extends React.Component<IProps, IState> {
|
export default class VideoFeed extends React.Component<IProps, IState> {
|
||||||
private video = createRef<HTMLVideoElement>();
|
private element = createRef<HTMLVideoElement>();
|
||||||
private audio = createRef<HTMLAudioElement>();
|
|
||||||
|
|
||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -62,38 +59,20 @@ export default class VideoFeed extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.feed.addListener(CallFeedEvent.NewStream, this.onNewStream);
|
this.props.feed.addListener(CallFeedEvent.NewStream, this.onNewStream);
|
||||||
this.playAllMedia();
|
this.playMedia();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.props.feed.removeListener(CallFeedEvent.NewStream, this.onNewStream);
|
this.props.feed.removeListener(CallFeedEvent.NewStream, this.onNewStream);
|
||||||
this.video.current?.removeEventListener('resize', this.onResize);
|
this.element.current?.removeEventListener('resize', this.onResize);
|
||||||
this.stopAllMedia();
|
this.stopMedia();
|
||||||
}
|
}
|
||||||
|
|
||||||
private playMediaElement(element: HTMLVideoElement | HTMLAudioElement) {
|
private playMedia() {
|
||||||
if (element instanceof HTMLAudioElement) {
|
const element = this.element.current;
|
||||||
const audioOutput = CallMediaHandler.getAudioOutput();
|
if (!element) return;
|
||||||
|
// We play audio in AudioFeed, not here
|
||||||
// Don't play audio if the feed is local
|
element.muted = true;
|
||||||
element.muted = this.props.feed.isLocal();
|
|
||||||
|
|
||||||
if (audioOutput && !element.muted) {
|
|
||||||
try {
|
|
||||||
// This seems quite unreliable in Chrome, although I haven't yet managed to make a jsfiddle where
|
|
||||||
// it fails.
|
|
||||||
// It seems reliable if you set the sink ID after setting the srcObject and then set the sink ID
|
|
||||||
// back to the default after the call is over - Dave
|
|
||||||
element.setSinkId(audioOutput);
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Couldn't set requested audio output device: using default", e);
|
|
||||||
logger.warn("Couldn't set requested audio output device: using default", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
element.muted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
element.srcObject = this.props.feed.stream;
|
element.srcObject = this.props.feed.stream;
|
||||||
element.autoplay = true;
|
element.autoplay = true;
|
||||||
try {
|
try {
|
||||||
|
@ -112,7 +91,10 @@ export default class VideoFeed extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private stopMediaElement(element: HTMLAudioElement | HTMLVideoElement) {
|
private stopMedia() {
|
||||||
|
const element = this.element.current;
|
||||||
|
if (!element) return;
|
||||||
|
|
||||||
element.pause();
|
element.pause();
|
||||||
element.src = null;
|
element.src = null;
|
||||||
|
|
||||||
|
@ -122,22 +104,12 @@ export default class VideoFeed extends React.Component<IProps, IState> {
|
||||||
// seem to be necessary - Šimon
|
// seem to be necessary - Šimon
|
||||||
}
|
}
|
||||||
|
|
||||||
private playAllMedia() {
|
|
||||||
this.playMediaElement(this.audio.current);
|
|
||||||
if (this.video.current) this.playMediaElement(this.video.current);
|
|
||||||
}
|
|
||||||
|
|
||||||
private stopAllMedia() {
|
|
||||||
this.stopMediaElement(this.audio.current)
|
|
||||||
if (this.video.current) this.stopMediaElement(this.video.current);
|
|
||||||
}
|
|
||||||
|
|
||||||
private onNewStream = () => {
|
private onNewStream = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
audioMuted: this.props.feed.isAudioMuted(),
|
audioMuted: this.props.feed.isAudioMuted(),
|
||||||
videoMuted: this.props.feed.isVideoMuted(),
|
videoMuted: this.props.feed.isVideoMuted(),
|
||||||
});
|
});
|
||||||
this.playAllMedia();
|
this.playMedia();
|
||||||
};
|
};
|
||||||
|
|
||||||
private onResize = (e) => {
|
private onResize = (e) => {
|
||||||
|
@ -152,16 +124,13 @@ export default class VideoFeed extends React.Component<IProps, IState> {
|
||||||
mx_VideoFeed_local: this.props.feed.isLocal(),
|
mx_VideoFeed_local: this.props.feed.isLocal(),
|
||||||
mx_VideoFeed_remote: !this.props.feed.isLocal(),
|
mx_VideoFeed_remote: !this.props.feed.isLocal(),
|
||||||
mx_VideoFeed_voice: this.state.videoMuted,
|
mx_VideoFeed_voice: this.state.videoMuted,
|
||||||
|
mx_VideoFeed_video: !this.state.videoMuted,
|
||||||
mx_VideoFeed_mirror: (
|
mx_VideoFeed_mirror: (
|
||||||
this.props.feed.isLocal() &&
|
this.props.feed.isLocal() &&
|
||||||
SettingsStore.getValue('VideoView.flipVideoHorizontally')
|
SettingsStore.getValue('VideoView.flipVideoHorizontally')
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
const audio = (
|
|
||||||
<audio ref={this.audio} />
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this.state.videoMuted) {
|
if (this.state.videoMuted) {
|
||||||
const member = this.props.feed.getMember();
|
const member = this.props.feed.getMember();
|
||||||
const avatarSize = this.props.pipMode ? 76 : 160;
|
const avatarSize = this.props.pipMode ? 76 : 160;
|
||||||
|
@ -173,15 +142,11 @@ export default class VideoFeed extends React.Component<IProps, IState> {
|
||||||
height={avatarSize}
|
height={avatarSize}
|
||||||
width={avatarSize}
|
width={avatarSize}
|
||||||
/>
|
/>
|
||||||
{audio}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<div className={classnames(videoClasses)}>
|
<video className={classnames(videoClasses)} ref={this.element} />
|
||||||
<video className="mx_VideoFeed_video" ref={this.video} />
|
|
||||||
{audio}
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue