forked from react-native-webrtc/react-native-webrtc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
getUserMedia.js
101 lines (94 loc) · 3.56 KB
/
getUserMedia.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
'use strict';
import {NativeModules} from 'react-native';
import MediaStream from './MediaStream';
import MediaStreamError from './MediaStreamError';
import MediaStreamTrack from './MediaStreamTrack';
const {WebRTCModule} = NativeModules;
export default function getUserMedia(
constraints,
successCallback,
errorCallback) {
if (typeof successCallback !== 'function') {
throw new TypeError('successCallback is non-nullable and required');
}
if (typeof errorCallback !== 'function') {
throw new TypeError('errorCallback is non-nullable and required');
}
// According to
// https://www.w3.org/TR/mediacapture-streams/#dom-mediadevices-getusermedia,
// the constraints argument is a dictionary of type MediaStreamConstraints.
if (typeof constraints === 'object') {
// According to step 2 of the getUserMedia() algorithm, requestedMediaTypes
// is the set of media types in constraints with either a dictionary value
// or a value of "true".
let requestedMediaTypes = 0;
for (const mediaType of [ 'audio', 'video' ]) {
// According to the spec, the types of the audio and video members of
// MediaStreamConstraints are either boolean or MediaTrackConstraints
// (i.e. dictionary).
const mediaTypeConstraints = constraints[mediaType];
const typeofMediaTypeConstraints = typeof mediaTypeConstraints;
if (typeofMediaTypeConstraints !== 'undefined') {
if (typeofMediaTypeConstraints === 'boolean') {
mediaTypeConstraints && ++requestedMediaTypes;
} else if (typeofMediaTypeConstraints == 'object') {
++requestedMediaTypes;
} else {
errorCallback(
new TypeError(
'constraints.' + mediaType
+ ' is neither a boolean nor a dictionary'));
return;
}
}
}
// According to step 3 of the getUserMedia() algorithm, if
// requestedMediaTypes is the empty set, the method invocation fails with
// a TypeError.
if (requestedMediaTypes === 0) {
errorCallback(new TypeError('constraints requests no media types'));
return;
}
} else {
errorCallback(new TypeError('constraints is not a dictionary'));
return;
}
WebRTCModule.getUserMedia(
constraints,
/* successCallback */ (id, tracks) => {
const stream = new MediaStream(id);
for (const track of tracks) {
stream.addTrack(new MediaStreamTrack(track));
}
successCallback(stream);
},
/* errorCallback */ (type, message) => {
let error;
switch (type) {
case 'DOMException':
// According to
// https://www.w3.org/TR/mediacapture-streams/#idl-def-MediaStreamError,
// MediaStreamError is either a DOMException object or an
// OverconstrainedError object. We are very likely to not have a
// definition of DOMException on React Native (unless the client has
// provided such a definition). If necessary, we will fall back to our
// definition of MediaStreamError.
if (typeof DOMException === 'function') {
error = new DOMException(/* message */ undefined, /* name */ message);
}
break;
case 'OverconstrainedError':
if (typeof OverconstrainedError === 'function') {
error = new OverconstrainedError(/* constraint */ undefined, message);
}
break;
case 'TypeError':
error = new TypeError(message);
break;
}
if (!error) {
error = new MediaStreamError({ message, name: type });
}
errorCallback(error);
});
}