rendered paste body /**************************************************\| || VideoStream Class || --------------------- || This class creates and controls a video stream || object, once started, it is self sustaining and || has members for changing its resolution, mapping || the image object and the stream name to the dom || tree, and controling the feed (start, stop, pause,|| rewind, fastforward, seek, ect (most arent done, || but will be comming soon)). || | \**************************************************/ /**** Singleton Array of all Streams ****/ VideoStream.prototype.allStreams = new Array(0); /******************************************\ | VideoStream constructor | | ----------------------- | | Parameters: | | name: String name of the video | | locator: IP address or Domain Name of | | the video provider | | hash: Identifier hash passed to the | | provider for authentication | | videoSize: String name of the resolution | | to use, (e.g. high, low) | | | \******************************************/ function VideoStream(name, locator, hash, frameSize) { this.origName = name; this.streamName = document.createElement('p').appendChild(document.createTextNode(name)); this.streamState = 'stopped'; this.streamVideo = document.createElement('img'); this.serverLocator = locator; this.serverHash = hash; this.frameDelay = 200; this.frameSize = frameSize; this.frameDelayTimeout = -1; this.frameLoadDelay = 1000; this.frameLoadTimeout = -1; this.frameLagCount = 0; this.streamMode = false; if (window.netscape) this.streamMode = true; this.startFrameURL = this.buildURL(); this.streamVideo.src = this.startFrameURL; this.streamID = (VideoStream.prototype.allStreams.push(-1)-1); VideoStream.prototype.allStreams[this.streamID] = this;// this.streamVideo.setAttribute('onLoad', 'delayFrame("'+this.streamID+'")');//this.delayFrame(this.streamID); } /************************************\| **** Video Controller Functions **** | \************************************/ VideoStream.prototype.start = function() { if (this.streamState == 'playing') return true; this.streamState = 'playing'; this.streamVideo.onload = createMethodReference(this, "delayFrame"); this.streamVideo.src = this.buildURL(); } VideoStream.prototype.stop = function() { if (this.streamState == 'stopped') return true; this.streamState = 'stopped'; this.resetTimeouts(); this.streamVideo.src = this.startFrameURL; this.reloadStartFrame(); return true; } VideoStream.prototype.pause = VideoStream.prototype.stop; VideoStream.prototype.reloadStartFrame = function() { if (this.streamState != 'stopped') return false; this.startFrameURL = this.buildURL(); this.streamVideo.src = this.startFrameURL; } /**********************************\| ******* Mapping Functions ******** | \**********************************/ /*************************************\ | mapUnder: Maps one object as a | | child to to another | | --------------------------------- | | Parameters: | | parent_obj: object to map to | | source_obj: object being mapped | | class_name: class of source | | | \*************************************/ VideoStream.prototype.mapUnder = function(parent_obj, source_obj, class_name) {// source_obj.setAttribute('class', class_name); parent_obj.appendChild(source_obj); } /*************************************\ | mapBefore: Maps one object after | | another object in DOM | | --------------------------------- | | Parameters: | | sibling_obj: object to map after | | source_obj: object being mapped | | class_name: class of source | | | \*************************************/ VideoStream.prototype.mapBefore = function(sibling_obj, source_obj, class_name) {// source_obj.setAttribute('class', class_name); sibling_obj.offsetParent.insertBefore(source_obj, sibling_obj); } /*************************************\ | mapVideoUnder/ Wrappers to mapUnder | | mapVideoBefore: and mapAfter passing | | the Video object | | ----------------------------------- | | Parameters: | | parent_id/ ID of parent or | | sibling_id: sibling | | class_name: class of source | | | \*************************************/ VideoStream.prototype.mapVideoUnder = function(parent_id, class_name) { var our_parent = document.getElementById(parent_id); if (undefined == our_parent) return false; this.mapUnder(our_parent, this.streamVideo, class_name); return true; } VideoStream.prototype.mapVideoBefore = function(sibling_id, class_name) { var our_sib = document.getElementById(sibling_id); if (undefined == our_sib) return false; this.mapBefore(our_sib, this.streamVideo, class_name); return true; } VideoStream.prototype.replaceVideoUnder = function(parent_id) { var our_parent = document.getElementById(parent_id); our_parent.replaceChild(this.streamVideo, our_parent.firstChild); } /*************************************\ | mapNameUnder/ Wrappers to mapUnder | | mapNameBefore: and mapAfter passing | | the streamName object | | ------------------------------------ | | Parameters: | | parent_id/ ID of parent or | | sibling_id: sibling | | class_name: class of source | | | \*************************************/ VideoStream.prototype.mapNameUnder = function(parent_id, class_name) { var our_parent = document.getElementById(parent_id); if (undefined == our_parent) return false; this.mapUnder(our_parent, this.streamName, class_name); return true; } VideoStream.prototype.mapNameBefore = function(sibling_id, class_name) { var our_sib = document.getElementById(sibling_id); if (undefined == our_sib) return false; this.mapBefore(our_sib, this.streamName, class_name); return true; } VideoStream.prototype.replaceNameUnder = function(parent_id) { var our_parent = document.getElementById(parent_id); our_parent.replaceChild(this.streamName, our_parent.firstChild); } /****************************************\| ****** Video Continuity Functions ****** || ** You shouldn't have to modify these ** | \****************************************/ /*************************************\ | delayFrame: Called after a frame | | is loaded to create a | | delay between frames | | ---------------------------------- | | Parameters: | | id: The array slice ID for this | | Video object. | | | \*************************************/ VideoStream.prototype.delayFrame = function() { if (undefined == this) return true; this.resetTimeouts(); if (this.streamMode && !this.streamVideo.complete) return; switch (this.streamState) { case 'stopped':// alert('stopped'); this.resetTimeouts(); break; case 'stopping': this.resetTimeouts();/* this.streamState = 'stopped'; alert('stopping'); if (this.streamMode) { this.streamMode = false; this.streamVideo.src = this.buildURL(); this.streamMode = true; }*/ break; case 'playing': if (this.frameLagCount > 0) this.frameLagCount--; clearTimeout(this.frameDelayTimeout); this.frameDelayTimeout = setTimeout( createMethodReference(this, "reloadFrame"), this.frameDelay ); break; default: alert('state unknown: '+this.streamState); break; } } VideoStream.prototype.resetTimeouts = function() { clearTimeout(this.frameDelayTimeout); clearTimeout(this.frameLoadTimeout); } /**************************************\ | reloadFrame: Called after delayFrame, | | buildURL returns new src | | ------------------------------------ | | Parameters: | | id: The array slice ID for this | | Video object. | | | \**************************************/ VideoStream.prototype.reloadFrame = function() { this.streamVideo.src = this.buildURL(); this.resetTimeouts(); if (this.streamState == 'playing') { this.frameLoadTimeout = setTimeout( createMethodReference(this, "timeoutFrame"), this.frameLoadDelay ); } } VideoStream.prototype.timeoutFrame = function() { if (this.streamState != 'playing') return true; this.resetTimeouts(); this.frameLagCount++; if (this.frameLagCount > 5 && this.frameSize != '160x120') { this.frameSize = '160x120'; } this.reloadFrame(); } /*************************************\ | buildURL: Called to build the URL | | of the video provider. | | ---------------------------------- | | Parameters: None | | | \*************************************/ VideoStream.prototype.buildURL = function() { var path = this.serverLocator + '?'; if (!this.streamMode || this.streamState != 'playing') path += '&single=true'; path += '&size=' + this.frameSize; path += '&t=' + (new Date()).getTime(); return path; } /*******************************************/ function createMethodReference(object, methodName) { return function () { object[methodName](); }; };