Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 3e85b6d

Browse files
committed
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 element-hq/element-web#15694 Regressed by #5352
1 parent f7e2d70 commit 3e85b6d

File tree

1 file changed

+29
-5
lines changed

1 file changed

+29
-5
lines changed

src/components/views/messages/MVideoBody.tsx

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ interface IState {
3939
}
4040

4141
export default class MVideoBody extends React.PureComponent<IProps, IState> {
42+
private videoRef = React.createRef<HTMLVideoElement>();
43+
4244
constructor(props) {
4345
super(props);
4446
this.state = {
@@ -80,6 +82,11 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
8082
}
8183
}
8284

85+
private hasContentUrl(): boolean {
86+
const url = this.getContentUrl();
87+
return url && !url.startsWith("data:");
88+
}
89+
8390
private getThumbUrl(): string|null {
8491
const content = this.props.mxEvent.getContent();
8592
if (content.file !== undefined) {
@@ -118,7 +125,10 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
118125
} else {
119126
console.log("NOT preloading video");
120127
this.setState({
121-
decryptedUrl: null,
128+
// For Chrome and Electron, we need to set some non-empty `src` to
129+
// enable the play button. Firefox does not seem to care either
130+
// way, so it's fine to do for all browsers.
131+
decryptedUrl: `data:${content?.info?.mimetype},`,
122132
decryptedThumbnailUrl: thumbnailUrl,
123133
decryptedBlob: null,
124134
});
@@ -143,7 +153,7 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
143153
}
144154

145155
private videoOnPlay = async () => {
146-
if (this.getContentUrl() || this.state.fetchingData || this.state.error) {
156+
if (this.hasContentUrl() || this.state.fetchingData || this.state.error) {
147157
// We have the file, we are fetching the file, or there is an error.
148158
return;
149159
}
@@ -164,6 +174,9 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
164174
decryptedUrl: contentUrl,
165175
decryptedBlob: decryptedBlob,
166176
fetchingData: false,
177+
}, () => {
178+
if (!this.videoRef.current) return;
179+
this.videoRef.current.play();
167180
});
168181
this.props.onHeightChanged();
169182
}
@@ -215,9 +228,20 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
215228
}
216229
return (
217230
<span className="mx_MVideoBody">
218-
<video className="mx_MVideoBody" src={contentUrl} title={content.body}
219-
controls preload={preload} muted={autoplay} autoPlay={autoplay}
220-
height={height} width={width} poster={poster} onPlay={this.videoOnPlay}>
231+
<video
232+
className="mx_MVideoBody"
233+
ref={this.videoRef}
234+
src={contentUrl}
235+
title={content.body}
236+
controls
237+
preload={preload}
238+
muted={autoplay}
239+
autoPlay={autoplay}
240+
height={height}
241+
width={width}
242+
poster={poster}
243+
onPlay={this.videoOnPlay}
244+
>
221245
</video>
222246
<MFileBody {...this.props} decryptedBlob={this.state.decryptedBlob} />
223247
</span>

0 commit comments

Comments
 (0)