diff options
| author | Gubolin <gubolin@fantasymail.de> | 2014-08-10 20:04:52 +0200 |
|---|---|---|
| committer | Gubolin <gubolin@fantasymail.de> | 2014-08-10 20:04:52 +0200 |
| commit | 4b71fef0c1e29c89f06389b6db81cd578d028f12 (patch) | |
| tree | 210e8a83543e39e6846812a24095e4f9768bf862 | |
| parent | 0333925e916acc47c25cdcfec0c3be3d695a825f (diff) | |
| download | snap-4b71fef0c1e29c89f06389b6db81cd578d028f12.tar.gz snap-4b71fef0c1e29c89f06389b6db81cd578d028f12.zip | |
add camera streaming blocks (fix #460)
| -rw-r--r-- | objects.js | 13 | ||||
| -rw-r--r-- | threads.js | 71 |
2 files changed, 83 insertions, 1 deletions
@@ -569,6 +569,16 @@ SpriteMorph.prototype.initBlocks = function () { category: 'pen', spec: 'stamp' }, + doStreamCamera: { + type: 'command', + category: 'pen', + spec: 'start streaming from the camera' + }, + doStopCamera: { + type: 'command', + category: 'pen', + spec: 'stop streaming from the camera' + }, // Control receiveGo: { @@ -4911,6 +4921,9 @@ StageMorph.prototype.blockTemplates = function (category) { } else if (cat === 'pen') { blocks.push(block('clear')); + blocks.push('-'); + blocks.push(block('doStreamCamera')); + blocks.push(block('doStopCamera')); } else if (cat === 'control') { @@ -1,5 +1,5 @@ /* - + threads.js a tail call optimized blocks-based programming language interpreter @@ -2732,6 +2732,73 @@ Process.prototype.doPlayNoteForSecs = function (pitch, secs) { this.pushContext(); }; +// Process camera streaming primitives + +Process.prototype.doStreamCamera = function () { + var myself = this; + var video = this.context.activeStream || null; + + var stage = this.homeContext.receiver.parentThatIsA(StageMorph); + if (!stage.trailsCanvas) { + stage.trailsCanvas = newCanvas(stage.dimensions); + } + + if (video === null) { + video = document.createElement('video'); + video.width = stage.dimensions.x; + video.height = stage.dimensions.y; + + this.context.activeStream = video; + + var videoObject = {'video': true, 'audio': false}; + + if (navigator.getUserMedia) { + navigator.getUserMedia(videoObject, function (stream) { + video.src = stream; + video.play(); + }, this.handleError); // TODO: improve error handling + } else if (navigator.webkitGetUserMedia) { + navigator.webkitGetUserMedia(videoObject, function (stream) { + video.src = window.webkitURL.createObjectURL(stream); + video.play(); + }, this.handleError); + } else if (navigator.mozGetUserMedia) { + navigator.mozGetUserMedia(videoObject, function (stream) { + video.src = window.URL.createObjectURL(stream); + video.play(); + }, this.handleError); + } + } else { + var canvas = stage.trailsCanvas; + var context = canvas.getContext('2d'); + + if (video.readyState !== 0) { + try { + context.drawImage(video, 0, 0, video.width, video.height); + stage.changed(); + } catch (e) { + if (e.name !== 'NS_ERROR_NOT_AVAILABLE') { + // https://bugzilla.mozilla.org/show_bug.cgi?id=879717 + throw e; + } + } + } + } + this.pushContext('doYield'); + this.pushContext(); +}; + +Process.prototype.doStopCamera = function () { + var stage = this.homeContext.receiver.parentThatIsA(StageMorph); + if (stage) { + stage.threads.processes.forEach(function (thread) { + if (thread.context.activeStream) { + thread.popContext(); + } + }); + } +}; + // Process constant input options Process.prototype.inputOption = function (dta) { @@ -2808,6 +2875,7 @@ Process.prototype.reportFrameCount = function () { startValue initial value for interpolated operations activeAudio audio buffer for interpolated operations, don't persist activeNote audio oscillator for interpolated ops, don't persist + activeStream video element for camera streaming, don't persist isLambda marker for return ops isImplicitLambda marker for return ops isCustomBlock marker for return ops @@ -2835,6 +2903,7 @@ function Context( this.startTime = null; this.activeAudio = null; this.activeNote = null; + this.activeStream = null; this.isLambda = false; // marks the end of a lambda this.isImplicitLambda = false; // marks the end of a C-shaped slot this.isCustomBlock = false; // marks the end of a custom block's stack |
