UNPKG

videocontext

Version:

A WebGL & HTML5 graph based video composition library

261 lines (220 loc) 9.08 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: SourceNodes/videonode.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: SourceNodes/videonode.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>//Matthew Shotton, R&amp;D User Experience,© BBC 2015 import SourceNode, { SOURCENODESTATE } from "./sourcenode"; class VideoNode extends SourceNode { /** * Initialise an instance of a VideoNode. * This should not be called directly, but created through a call to videoContext.createVideoNode(); */ constructor(src, gl, renderGraph, currentTime, globalPlaybackRate=1.0, sourceOffset=0, preloadTime = 4, videoElementCache=undefined, attributes = {}){ super(src, gl, renderGraph, currentTime); this._preloadTime = preloadTime; this._sourceOffset = sourceOffset; this._globalPlaybackRate = globalPlaybackRate; this._videoElementCache = videoElementCache; this._playbackRate = 1.0; this._playbackRateUpdated = true; this._attributes = attributes; this._loopElement = false; this._isElementPlaying = false; if (this._attributes.loop){ this._loopElement = this._attributes.loop; } this._displayName = "VideoNode"; } set playbackRate(playbackRate){ this._playbackRate = playbackRate; this._playbackRateUpdated = true; } set stretchPaused(stretchPaused){ super.stretchPaused = stretchPaused; if(this._element){ if (this._stretchPaused){ this._element.pause(); } else{ if(this._state === SOURCENODESTATE.playing){ this._element.play(); } } } } get stretchPaused(){ return this._stretchPaused; } get playbackRate(){ return this._playbackRate; } get elementURL(){ return this._elementURL; } _load(){ super._load(); if (this._element !== undefined){ for (var key in this._attributes) { this._element[key] = this._attributes[key]; } if (this._element.readyState > 3 &amp;&amp; !this._element.seeking){ if(this._loopElement === false){ if (this._stopTime === Infinity || this._stopTime == undefined){ this._stopTime = this._startTime + this._element.duration; this._triggerCallbacks("durationchange", this.duration); } } if(this._ready !== true){ this._triggerCallbacks("loaded"); this._playbackRateUpdated = true; } this._ready = true; } else{ if(this._state !== SOURCENODESTATE.error){ this._ready = false; } } return; } if (this._isResponsibleForElementLifeCycle){ if (this._videoElementCache){ this._element = this._videoElementCache.get(); }else{ this._element = document.createElement("video"); this._element.setAttribute("crossorigin", "anonymous"); this._element.setAttribute("webkit-playsinline", ""); this._playbackRateUpdated = true; } if (this._elementURL instanceof MediaStream){ this._element.srcObject = this._elementURL; }else{ this._element.src = this._elementURL; } for (let key in this._attributes) { this._element[key] = this._attributes[key]; } } if (this._element){ this._element.currentTime = this._sourceOffset; this._element.onerror = () => { if (this._element === undefined) return; console.debug("Error with element", this._element); this._state = SOURCENODESTATE.error; //Event though there's an error ready should be set to true so the node can output transparenn this._ready = true; this._triggerCallbacks("error"); }; }else{ //If the element doesn't exist for whatever reason enter the error state. this._state = SOURCENODESTATE.error; this._ready = true; this._triggerCallbacks("error"); } } _destroy(){ super._destroy(); if (this._isResponsibleForElementLifeCycle &amp;&amp; this._element !== undefined){ this._element.src = ""; for (let key in this._attributes){ this._element.removeAttribute(key); } this._element = undefined; if(!this._videoElementCache) delete this._element; } this._ready = false; this._isElementPlaying = false; } _seek(time){ super._seek(time); if (this.state === SOURCENODESTATE.playing || this.state === SOURCENODESTATE.paused){ if (this._element === undefined) this._load(); let relativeTime = this._currentTime - this._startTime + this._sourceOffset; this._element.currentTime = relativeTime; this._ready = false; } if((this._state === SOURCENODESTATE.sequenced || this._state === SOURCENODESTATE.ended) &amp;&amp; this._element !== undefined){ this._destroy(); } } _update(currentTime){ //if (!super._update(currentTime)) return false; super._update(currentTime); //check if the video has ended if(this._element !== undefined){ if (this._element.ended){ this._state = SOURCENODESTATE.ended; this._triggerCallbacks("ended"); } } if (this._startTime - this._currentTime &lt; this._preloadTime &amp;&amp; this._state !== SOURCENODESTATE.waiting &amp;&amp; this._state !== SOURCENODESTATE.ended)this._load(); if (this._state === SOURCENODESTATE.playing){ if (this._playbackRateUpdated) { this._element.playbackRate = this._globalPlaybackRate * this._playbackRate; this._playbackRateUpdated = false; } if (!this._isElementPlaying){ this._element.play(); if (this._stretchPaused){ this._element.pause(); } this._isElementPlaying = true; } return true; } else if (this._state === SOURCENODESTATE.paused){ this._element.pause(); this._isElementPlaying = false; return true; } else if (this._state === SOURCENODESTATE.ended &amp;&amp; this._element !== undefined){ this._element.pause(); if (this._isElementPlaying){ this._destroy(); } return false; } } clearTimelineState(){ super.clearTimelineState(); if (this._element !== undefined) { this._element.pause(); this._isElementPlaying = false; } this._destroy(); } destroy(){ if (this._element) this._element.pause(); this._isElementPlaying = false; super.destroy(); this._destroy(); } } export default VideoNode; </code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-VideoContext.html">VideoContext</a></li></ul><h3>Classes</h3><ul><li><a href="CanvasNode.html">CanvasNode</a></li><li><a href="CompositingNode.html">CompositingNode</a></li><li><a href="DestinationNode.html">DestinationNode</a></li><li><a href="EffectNode.html">EffectNode</a></li><li><a href="GraphNode.html">GraphNode</a></li><li><a href="ImageNode.html">ImageNode</a></li><li><a href="module-VideoContext.html">VideoContext</a></li><li><a href="ProcessingNode.html">ProcessingNode</a></li><li><a href="RenderGraph.html">RenderGraph</a></li><li><a href="SourceNode.html">SourceNode</a></li><li><a href="TransitionNode.html">TransitionNode</a></li><li><a href="VideoNode.html">VideoNode</a></li></ul> </nav> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>