-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathinit-webrtc.js
113 lines (99 loc) · 2.82 KB
/
init-webrtc.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
102
103
104
105
106
107
108
109
110
111
112
113
function polyfillGetUserMedia() {
if (!navigator.mediaDevices) {
navigator.mediaDevices = {}
}
if (!navigator.mediaDevices.getUserMedia) {
let oldGetUserMedia =
navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia
if (oldGetUserMedia) {
oldGetUserMedia = oldGetUserMedia.bind(navigator)
} else {
navigator.mediaDevices.getUserMedia = Promise.reject(
new Error("Browser doesn't support getUserMedia"),
)
return
}
navigator.mediaDevices.getUserMedia = function (constraints) {
return new Promise((resolve, reject) => oldGetUserMedia(constraints, resolve, reject))
}
}
}
class StreamResult {
constructor(video, stream, url, hasFrontAndRear, facing) {
this.video = video
this.stream = stream
this.url = url
this.hasFrontAndRear = hasFrontAndRear
this.facing = facing
this.stopped = false
}
stop() {
if (this.stopped) return
if (this.url && this.video.src === this.url) {
this.video.pause()
this.video.removeAttribute('src')
window.URL.revokeObjectURL(this.url)
this.url = null
} else if (
(this.video.srcObject && this.video.srcObject === this.stream) ||
(this.video.mozSrcObject && this.video.mozSrcObject === this.stream)
) {
this.video.pause()
this.video.removeAttribute('src')
}
for (const track of this.stream.getTracks()) {
track.stop()
}
this.video = null
this.stream = null
this.stopped = true
}
}
async function initWebrtc(video, facing, cancelToken = { canceled: false }) {
polyfillGetUserMedia()
const constraints = {
facingMode: facing,
width: {
ideal: 1280,
},
height: {
ideal: 720,
},
}
const stream = await navigator.mediaDevices.getUserMedia({
audio: false,
video: constraints,
})
let url
video.autoplay = true
video.muted = true
video.playsInline = true
if ('srcObject' in video) {
video.srcObject = stream
} else if ('mozSrcObject' in video) {
video.mozSrcObject = stream
} else {
url = window.URL.createObjectURL(stream)
video.src = url
}
await new Promise(resolve => {
const listener = () => {
video.removeEventListener('loadeddata', listener)
resolve()
}
video.addEventListener('loadeddata', listener)
})
const result = new StreamResult(video, stream, url, true /* hasFrontAndRear */, facing)
if (cancelToken.canceled) {
// NOTE: we wait to stop things here because it makes the code simpler, technically we could
// probably stop things after the getUserMedia call most of the time
result.stop()
}
return result
}
// TODO(tec27): only set this if there are multiple cameras?
initWebrtc.supportsSourceSelection = true
export default initWebrtc