From b3e8a6df800d01dfec2f85d18b864386f6a55477 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Wed, 18 Nov 2020 17:41:54 +0000 Subject: [PATCH 1/2] Tweak video component code style --- src/components/views/messages/MVideoBody.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/views/messages/MVideoBody.tsx b/src/components/views/messages/MVideoBody.tsx index fb987a4f0d..671633be9e 100644 --- a/src/components/views/messages/MVideoBody.tsx +++ b/src/components/views/messages/MVideoBody.tsx @@ -71,7 +71,7 @@ export default class MVideoBody extends React.PureComponent { } } - _getContentUrl(): string|null { + private getContentUrl(): string|null { const content = this.props.mxEvent.getContent(); if (content.file !== undefined) { return this.state.decryptedUrl; @@ -80,7 +80,7 @@ export default class MVideoBody extends React.PureComponent { } } - _getThumbUrl(): string|null { + private getThumbUrl(): string|null { const content = this.props.mxEvent.getContent(); if (content.file !== undefined) { return this.state.decryptedThumbnailUrl; @@ -142,8 +142,8 @@ export default class MVideoBody extends React.PureComponent { } } - async _videoOnPlay() { - if (this._getContentUrl() || this.state.fetchingData || this.state.error) { + private videoOnPlay = async () => { + if (this.getContentUrl() || this.state.fetchingData || this.state.error) { // We have the file, we are fetching the file, or there is an error. return; } @@ -195,8 +195,8 @@ export default class MVideoBody extends React.PureComponent { ); } - const contentUrl = this._getContentUrl(); - const thumbUrl = this._getThumbUrl(); + const contentUrl = this.getContentUrl(); + const thumbUrl = this.getThumbUrl(); let height = null; let width = null; let poster = null; @@ -217,7 +217,7 @@ export default class MVideoBody extends React.PureComponent { From d36618dc86479754459e2cb967d20ce2b4e8d5cb Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 19 Nov 2020 13:26:14 +0000 Subject: [PATCH 2/2] Fix encrypted video playback in Chrome-based browsers For Chrome-based browsers, it seems we need to set some non-empty `src` URI for the video element's play button to be enabled, so this crafts an empty `data` URI and ensures playing is triggered once the real content has been fetched. Fixes https://github.com/vector-im/element-web/issues/15694 Regressed by https://github.com/matrix-org/matrix-react-sdk/pull/5352 --- src/components/views/messages/MVideoBody.tsx | 34 +++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/components/views/messages/MVideoBody.tsx b/src/components/views/messages/MVideoBody.tsx index 671633be9e..9628f11809 100644 --- a/src/components/views/messages/MVideoBody.tsx +++ b/src/components/views/messages/MVideoBody.tsx @@ -39,6 +39,8 @@ interface IState { } export default class MVideoBody extends React.PureComponent { + private videoRef = React.createRef(); + constructor(props) { super(props); this.state = { @@ -80,6 +82,11 @@ export default class MVideoBody extends React.PureComponent { } } + private hasContentUrl(): boolean { + const url = this.getContentUrl(); + return url && !url.startsWith("data:"); + } + private getThumbUrl(): string|null { const content = this.props.mxEvent.getContent(); if (content.file !== undefined) { @@ -118,7 +125,10 @@ export default class MVideoBody extends React.PureComponent { } else { console.log("NOT preloading video"); this.setState({ - decryptedUrl: null, + // For Chrome and Electron, we need to set some non-empty `src` to + // enable the play button. Firefox does not seem to care either + // way, so it's fine to do for all browsers. + decryptedUrl: `data:${content?.info?.mimetype},`, decryptedThumbnailUrl: thumbnailUrl, decryptedBlob: null, }); @@ -143,7 +153,7 @@ export default class MVideoBody extends React.PureComponent { } private videoOnPlay = async () => { - if (this.getContentUrl() || this.state.fetchingData || this.state.error) { + if (this.hasContentUrl() || this.state.fetchingData || this.state.error) { // We have the file, we are fetching the file, or there is an error. return; } @@ -164,6 +174,9 @@ export default class MVideoBody extends React.PureComponent { decryptedUrl: contentUrl, decryptedBlob: decryptedBlob, fetchingData: false, + }, () => { + if (!this.videoRef.current) return; + this.videoRef.current.play(); }); this.props.onHeightChanged(); } @@ -215,9 +228,20 @@ export default class MVideoBody extends React.PureComponent { } return ( -