mirror of
https://github.com/element-hq/element-web
synced 2024-11-27 19:56:47 +03:00
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
This commit is contained in:
parent
f7e2d70ddf
commit
3e85b6d085
1 changed files with 29 additions and 5 deletions
|
@ -39,6 +39,8 @@ interface IState {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class MVideoBody extends React.PureComponent<IProps, IState> {
|
export default class MVideoBody extends React.PureComponent<IProps, IState> {
|
||||||
|
private videoRef = React.createRef<HTMLVideoElement>();
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
|
@ -80,6 +82,11 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private hasContentUrl(): boolean {
|
||||||
|
const url = this.getContentUrl();
|
||||||
|
return url && !url.startsWith("data:");
|
||||||
|
}
|
||||||
|
|
||||||
private getThumbUrl(): string|null {
|
private getThumbUrl(): string|null {
|
||||||
const content = this.props.mxEvent.getContent();
|
const content = this.props.mxEvent.getContent();
|
||||||
if (content.file !== undefined) {
|
if (content.file !== undefined) {
|
||||||
|
@ -118,7 +125,10 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
|
||||||
} else {
|
} else {
|
||||||
console.log("NOT preloading video");
|
console.log("NOT preloading video");
|
||||||
this.setState({
|
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,
|
decryptedThumbnailUrl: thumbnailUrl,
|
||||||
decryptedBlob: null,
|
decryptedBlob: null,
|
||||||
});
|
});
|
||||||
|
@ -143,7 +153,7 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private videoOnPlay = async () => {
|
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.
|
// We have the file, we are fetching the file, or there is an error.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -164,6 +174,9 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
|
||||||
decryptedUrl: contentUrl,
|
decryptedUrl: contentUrl,
|
||||||
decryptedBlob: decryptedBlob,
|
decryptedBlob: decryptedBlob,
|
||||||
fetchingData: false,
|
fetchingData: false,
|
||||||
|
}, () => {
|
||||||
|
if (!this.videoRef.current) return;
|
||||||
|
this.videoRef.current.play();
|
||||||
});
|
});
|
||||||
this.props.onHeightChanged();
|
this.props.onHeightChanged();
|
||||||
}
|
}
|
||||||
|
@ -215,9 +228,20 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<span className="mx_MVideoBody">
|
<span className="mx_MVideoBody">
|
||||||
<video className="mx_MVideoBody" src={contentUrl} title={content.body}
|
<video
|
||||||
controls preload={preload} muted={autoplay} autoPlay={autoplay}
|
className="mx_MVideoBody"
|
||||||
height={height} width={width} poster={poster} onPlay={this.videoOnPlay}>
|
ref={this.videoRef}
|
||||||
|
src={contentUrl}
|
||||||
|
title={content.body}
|
||||||
|
controls
|
||||||
|
preload={preload}
|
||||||
|
muted={autoplay}
|
||||||
|
autoPlay={autoplay}
|
||||||
|
height={height}
|
||||||
|
width={width}
|
||||||
|
poster={poster}
|
||||||
|
onPlay={this.videoOnPlay}
|
||||||
|
>
|
||||||
</video>
|
</video>
|
||||||
<MFileBody {...this.props} decryptedBlob={this.state.decryptedBlob} />
|
<MFileBody {...this.props} decryptedBlob={this.state.decryptedBlob} />
|
||||||
</span>
|
</span>
|
||||||
|
|
Loading…
Reference in a new issue