blob: 90fb8973a22ca0750fbb9f89f4f517a650252236 [file] [edit]
/*
* Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree.
*/
'use strict';
/**
* Decodes and plays a video.
* @implements {MediaStreamSource} in pipeline.js
*/
class VideoSource { // eslint-disable-line no-unused-vars
constructor() {
/** @private {boolean} */
this.visibility_ = false;
/** @private {?HTMLVideoElement} video element providing the MediaStream */
this.video_ = null;
/**
* @private {?Promise<!MediaStream>} a Promise that resolves to the
* MediaStream from captureStream. Set iff video_ is set.
*/
this.stream_ = null;
/** @private {string} */
this.debugPath_ = '<unknown>';
}
/** @override */
setDebugPath(path) {
this.debugPath_ = path;
}
/** @override */
setVisibility(visible) {
this.visibility_ = visible;
if (this.video_) {
this.updateVideoVisibility();
}
}
/** @private */
updateVideoVisibility() {
if (this.video_.parentNode && !this.visibility_) {
if (!this.video_.paused) {
// Video playback is automatically paused when the element is removed
// from the DOM. That is not the behavior we want.
this.video_.onpause = async () => {
this.video_.onpause = null;
await this.video_.play();
};
}
this.video_.parentNode.removeChild(this.video_);
} else if (!this.video_.parentNode && this.visibility_) {
console.log(
'[VideoSource] Adding source video element to page.',
`${this.debugPath_}.video_ =`, this.video_);
const outputVideo = document.getElementById('outputVideo');
outputVideo.parentNode.insertBefore(this.video_, outputVideo);
}
}
/** @override */
async getMediaStream() {
if (this.stream_) return this.stream_;
console.log('[VideoSource] Loading video');
this.video_ =
/** @type {!HTMLVideoElement} */ (document.createElement('video'));
this.video_.classList.add('video', 'sourceVideo');
this.video_.controls = true;
this.video_.loop = true;
this.video_.muted = true;
// All browsers that support insertable streams also support WebM/VP8.
this.video_.src = '../../../video/chrome.webm';
this.video_.load();
this.video_.play();
this.updateVideoVisibility();
this.stream_ = new Promise((resolve, reject) => {
this.video_.oncanplay = () => {
if (!resolve || !reject) return;
console.log('[VideoSource] Obtaining video capture stream');
if (this.video_.captureStream) {
resolve(this.video_.captureStream());
} else if (this.video_.mozCaptureStream) {
resolve(this.video_.mozCaptureStream());
} else {
const e = new Error('Stream capture is not supported');
console.error(e);
reject(e);
}
resolve = null;
reject = null;
};
});
await this.stream_;
console.log(
'[VideoSource] Received source video stream.',
`${this.debugPath_}.stream_ =`, this.stream_);
return this.stream_;
}
/** @override */
destroy() {
if (this.video_) {
console.log('[VideoSource] Stopping source video');
this.video_.pause();
if (this.video_.parentNode) {
this.video_.parentNode.removeChild(this.video_);
}
}
}
}