@@ -265,20 +265,98 @@ $W.getUserMedia = function(options) {
265265 container . appendChild ( video ) ;
266266 video . autoplay = true ;
267267 video . id = 'webcam-video'
268+
269+ var videoElement = document . getElementById ( 'webcam-video' ) ;
270+ var videoSelect = document . querySelector ( 'select#videoSource' ) ;
271+ var selectors = [ videoSelect ] ;
268272
269- const successCallback = stream => {
273+ successCallback = stream => {
270274 $ ( '#heightIndicator' ) . show ( )
271275 $ ( '#webcam-msg' ) . hide ( )
272- attachMediaStream ( video , stream )
276+
277+ window . stream = stream ;
278+ videoElement = attachMediaStream ( videoElement , stream )
273279 if ( $W . flipped == true ) {
274280 $W . flipped = false ; // <= turn it false because f_h() will toggle it. messy.
275281 $W . flip_horizontal ( ) ;
276282 }
283+ return getVidDevices ( ) ;
277284 } ;
278285
279286 const errorCallback = ( ) => console . warn ( error ) ;
280287
281288 getUserMedia ( $W . defaultConstraints , successCallback , errorCallback ) ;
289+
290+ gotVidDevices = ( deviceInfos ) => {
291+ let values = selectors . map ( function ( select ) {
292+ return select . value ;
293+ } ) ;
294+
295+ selectors . forEach ( function ( select ) {
296+ while ( select . firstChild ) {
297+ select . removeChild ( select . firstChild ) ;
298+ }
299+ } ) ;
300+ for ( let i = 0 ; i !== deviceInfos . length ; ++ i ) {
301+ let deviceInfo = deviceInfos [ i ] ;
302+ let option = document . createElement ( 'option' ) ;
303+ option . value = ( deviceInfo . id || deviceInfo . deviceId ) ;
304+ if ( deviceInfo . kind === 'videoinput' || deviceInfo . kind === 'video' ) {
305+ console . log ( deviceInfo . label ) ;
306+ option . text = deviceInfo . label || 'camera ' + ( videoSelect . length + 1 ) ;
307+ videoSelect . appendChild ( option ) ;
308+ }
309+ }
310+
311+ selectors . forEach ( function ( select , selectorIndex ) {
312+ if ( Array . prototype . slice . call ( select . childNodes ) . some ( function ( n ) {
313+ return n . value === values [ selectorIndex ] ;
314+ } ) ) {
315+ select . value = values [ selectorIndex ] ;
316+ }
317+ } ) ;
318+ }
319+
320+ getVidDevices = ( ) => {
321+ if ( typeof Promise === 'undefined' ) {
322+ return MediaStreamTrack . getSources ( gotVidDevices ) ;
323+ } else {
324+ return navigator . mediaDevices . enumerateDevices ( )
325+ . then ( gotVidDevices )
326+ . catch ( ( error ) => {
327+ console . error ( error ) ;
328+ } ) ;
329+ }
330+ }
331+
332+ getVidDevices ( ) ;
333+
334+ start = ( ) => {
335+ if ( window . stream ) {
336+ window . stream . getTracks ( ) . forEach ( function ( track ) {
337+ track . stop ( ) ; //stopping the current video stream
338+ } ) ;
339+ }
340+
341+ var videoSource = videoSelect . value ;
342+ var constraints = {
343+ video : {
344+ deviceId : videoSource ? { exact : videoSource } : undefined //Taking device ids as the video source
345+ }
346+ } ;
347+
348+ if ( typeof Promise === 'undefined' ) {
349+ navigator . getUserMedia ( constraints , successCallback , function ( ) { } ) ;
350+ }
351+ else {
352+ navigator . mediaDevices . getUserMedia ( constraints )
353+ . then ( successCallback ) ;
354+ }
355+ }
356+
357+ videoSelect . onchange = start ; //repeating the process for source change
358+
359+ start ( ) ;
282360 } ) ;
283361} ;
284362
0 commit comments