@@ -2135,7 +2135,11 @@ if (navigator.mediaDevices.getUserMedia === undefined) {
21352135 * W3C documentation</a> for possible properties. Different browsers support different
21362136 * properties.
21372137 *
2138- * The second parameter, `callback`, is optional. It's a function to call once
2138+ * The 'flipped' property is an optional property which can be set to `{flipped:true}`
2139+ * to mirror the video output.If it is true then it means that video will be mirrored
2140+ * or flipped and if nothing is mentioned then by default it will be `false`.
2141+ *
2142+ * The second parameter,`callback`, is optional. It's a function to call once
21392143 * the capture is ready for use. The callback function should have one
21402144 * parameter, `stream`, that's a
21412145 * <a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaStream" target="_blank">MediaStream</a> object.
@@ -2148,6 +2152,8 @@ if (navigator.mediaDevices.getUserMedia === undefined) {
21482152 * @param {String|Constant|Object } [type] type of capture, either AUDIO or VIDEO,
21492153 * or a constraints object. Both video and audio
21502154 * audio streams are captured by default.
2155+ * @param {Object } [flipped] flip the capturing video and mirror the output with `{flipped:true}`. By
2156+ * default it is false.
21512157 * @param {Function } [callback] function to call once the stream
21522158 * has loaded.
21532159 * @return {p5.Element } new <a href="#/p5.Element">p5.Element</a> object.
@@ -2183,6 +2189,19 @@ if (navigator.mediaDevices.getUserMedia === undefined) {
21832189 * }
21842190 * </code>
21852191 * </div>
2192+ * <div class='notest'>
2193+ * <code>
2194+ * let capture;
2195+ *
2196+ * function setup() {
2197+ * // Create the video capture with mirrored output.
2198+ * capture = createCapture(VIDEO,{ flipped:true });
2199+ * capture.size(100,100);
2200+ * describe('A video stream from the webcam with flipped or mirrored output.');
2201+ * }
2202+ *
2203+ * </code>
2204+ * </div>
21862205 *
21872206 * <div class='notest norender'>
21882207 * <code>
@@ -2212,7 +2231,7 @@ if (navigator.mediaDevices.getUserMedia === undefined) {
22122231p5 . prototype . createCapture = function ( ...args ) {
22132232 p5 . _validateParameters ( 'createCapture' , args ) ;
22142233
2215- // return if getUserMedia is not supported by browser
2234+ // return if getUserMedia is not supported by the browser
22162235 if ( ! ( navigator . mediaDevices && navigator . mediaDevices . getUserMedia ) ) {
22172236 throw new DOMException ( 'getUserMedia not supported in this browser' ) ;
22182237 }
@@ -2221,29 +2240,40 @@ p5.prototype.createCapture = function(...args) {
22212240 let useAudio = true ;
22222241 let constraints ;
22232242 let callback ;
2243+ let flipped = false ;
2244+
22242245 for ( const arg of args ) {
22252246 if ( arg === p5 . prototype . VIDEO ) useAudio = false ;
22262247 else if ( arg === p5 . prototype . AUDIO ) useVideo = false ;
2227- else if ( typeof arg === 'object' ) constraints = arg ;
2228- else if ( typeof arg === 'function' ) callback = arg ;
2248+ else if ( typeof arg === 'object' ) {
2249+ if ( arg . flipped !== undefined ) {
2250+ flipped = arg . flipped ;
2251+ delete arg . flipped ;
2252+ }
2253+ constraints = Object . assign ( { } , constraints , arg ) ;
2254+ }
2255+ else if ( typeof arg === 'function' ) {
2256+ callback = arg ;
2257+ }
22292258 }
2230- if ( ! constraints ) constraints = { video : useVideo , audio : useAudio } ;
22312259
2260+ const videoConstraints = { video : useVideo , audio : useAudio } ;
2261+ constraints = Object . assign ( { } , videoConstraints , constraints ) ;
22322262 const domElement = document . createElement ( 'video' ) ;
22332263 // required to work in iOS 11 & up:
22342264 domElement . setAttribute ( 'playsinline' , '' ) ;
2235-
22362265 navigator . mediaDevices . getUserMedia ( constraints ) . then ( function ( stream ) {
22372266 try {
22382267 if ( 'srcObject' in domElement ) {
22392268 domElement . srcObject = stream ;
22402269 } else {
22412270 domElement . src = window . URL . createObjectURL ( stream ) ;
22422271 }
2243- } catch ( err ) {
2272+ }
2273+ catch ( err ) {
22442274 domElement . src = stream ;
22452275 }
2246- } , console . log ) ;
2276+ } , console . error ) ;
22472277
22482278 const videoEl = addElement ( domElement , this , true ) ;
22492279 videoEl . loadedmetadata = false ;
@@ -2253,6 +2283,9 @@ p5.prototype.createCapture = function(...args) {
22532283 if ( domElement . width ) {
22542284 videoEl . width = domElement . width ;
22552285 videoEl . height = domElement . height ;
2286+ if ( flipped ) {
2287+ videoEl . elt . style . transform = 'scaleX(-1)' ;
2288+ }
22562289 } else {
22572290 videoEl . width = videoEl . elt . width = domElement . videoWidth ;
22582291 videoEl . height = videoEl . elt . height = domElement . videoHeight ;
@@ -2261,9 +2294,11 @@ p5.prototype.createCapture = function(...args) {
22612294
22622295 if ( callback ) callback ( domElement . srcObject ) ;
22632296 } ) ;
2297+ videoEl . flipped = flipped ;
22642298 return videoEl ;
22652299} ;
22662300
2301+
22672302/**
22682303 * Creates a new <a href="#/p5.Element">p5.Element</a> object.
22692304 *
@@ -4377,7 +4412,6 @@ class MediaElement extends p5.Element {
43774412 duration ( ) {
43784413 return this . elt . duration ;
43794414 }
4380-
43814415 _ensureCanvas ( ) {
43824416 if ( ! this . canvas ) {
43834417 this . canvas = document . createElement ( 'canvas' ) ;
@@ -4398,18 +4432,26 @@ class MediaElement extends p5.Element {
43984432 }
43994433
44004434 this . drawingContext . clearRect (
4401- 0 ,
4402- 0 ,
4403- this . canvas . width ,
4404- this . canvas . height
4405- ) ;
4435+ 0 , 0 , this . canvas . width , this . canvas . height ) ;
4436+
4437+ if ( this . flipped === true ) {
4438+ this . drawingContext . save ( ) ;
4439+ this . drawingContext . scale ( - 1 , 1 ) ;
4440+ this . drawingContext . translate ( - this . canvas . width , 0 ) ;
4441+ }
4442+
44064443 this . drawingContext . drawImage (
44074444 this . elt ,
44084445 0 ,
44094446 0 ,
44104447 this . canvas . width ,
44114448 this . canvas . height
44124449 ) ;
4450+
4451+ if ( this . flipped === true ) {
4452+ this . drawingContext . restore ( ) ;
4453+ }
4454+
44134455 this . setModified ( true ) ;
44144456 this . _frameOnCanvas = this . _pInst . frameCount ;
44154457 }
0 commit comments