mirror of
https://github.com/element-hq/element-web
synced 2024-11-27 19:56:47 +03:00
Merge pull request #5430 from matrix-org/jryans/fix-encrypted-videos
Fix encrypted video playback in Chrome-based browsers
This commit is contained in:
commit
dea4fd661a
1 changed files with 34 additions and 10 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 = {
|
||||||
|
@ -71,7 +73,7 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_getContentUrl(): string|null {
|
private getContentUrl(): string|null {
|
||||||
const content = this.props.mxEvent.getContent();
|
const content = this.props.mxEvent.getContent();
|
||||||
if (content.file !== undefined) {
|
if (content.file !== undefined) {
|
||||||
return this.state.decryptedUrl;
|
return this.state.decryptedUrl;
|
||||||
|
@ -80,7 +82,12 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_getThumbUrl(): string|null {
|
private hasContentUrl(): boolean {
|
||||||
|
const url = this.getContentUrl();
|
||||||
|
return url && !url.startsWith("data:");
|
||||||
|
}
|
||||||
|
|
||||||
|
private getThumbUrl(): string|null {
|
||||||
const content = this.props.mxEvent.getContent();
|
const content = this.props.mxEvent.getContent();
|
||||||
if (content.file !== undefined) {
|
if (content.file !== undefined) {
|
||||||
return this.state.decryptedThumbnailUrl;
|
return this.state.decryptedThumbnailUrl;
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
|
@ -142,8 +152,8 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _videoOnPlay() {
|
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();
|
||||||
}
|
}
|
||||||
|
@ -195,8 +208,8 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const contentUrl = this._getContentUrl();
|
const contentUrl = this.getContentUrl();
|
||||||
const thumbUrl = this._getThumbUrl();
|
const thumbUrl = this.getThumbUrl();
|
||||||
let height = null;
|
let height = null;
|
||||||
let width = null;
|
let width = null;
|
||||||
let poster = null;
|
let poster = null;
|
||||||
|
@ -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.bind(this)}>
|
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