Now you can select input devices
This commit is contained in:
parent
1fe0b35757
commit
0cc7fcb945
|
@ -35,7 +35,6 @@ class Convulse {
|
|||
|
||||
document.querySelector("canvas").addEventListener("click", e => this.rec(e))
|
||||
document.querySelector("#rec").addEventListener("click", e => this.rec(e))
|
||||
//document.querySelector("#save").addEventListener("click", e => this.save(e))
|
||||
|
||||
document.querySelector("#webcam-size").addEventListener("input", e => this.setWebcamSize(e))
|
||||
document.querySelector("#webcam-size").value = localStorage.webcamSize || 0.3
|
||||
|
@ -51,19 +50,34 @@ class Convulse {
|
|||
|
||||
this.recorder = {state: "unstarted"}
|
||||
|
||||
// this.mediaStream gets audio directly from the device, video from canvas
|
||||
this.mediaStream = new MediaStream()
|
||||
|
||||
navigator.mediaDevices.getUserMedia({video: true, audio: true})
|
||||
.then(media => {
|
||||
document.querySelector("#hello").classList.add("hidden")
|
||||
this.webcamVideo.muted = true
|
||||
this.webcamVideo.srcObject = media
|
||||
this.webcamVideo.play()
|
||||
for (let at of media.getAudioTracks()) {
|
||||
this.mediaStream.addTrack(at)
|
||||
console.log("Adding audio track", at)
|
||||
// Populate select boxes with what media is available
|
||||
navigator.mediaDevices.enumerateDevices()
|
||||
.then(devs => {
|
||||
for (let dev of devs) {
|
||||
let opt = document.createElement("option")
|
||||
opt.value = dev.deviceId
|
||||
if (dev.kind == "audioinput") {
|
||||
opt.text = dev.label || `Microphone ${aud.length+1}`
|
||||
aud.appendChild(opt)
|
||||
} else if (dev.kind == "videoinput") {
|
||||
opt.text = dev.label || `Camera ${vid.length+1}`
|
||||
vid.appendChild(opt)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Pretend the user clicked whatever's in those boxes
|
||||
let aud = document.querySelector("#audio-in")
|
||||
let vid = document.querySelector("#video-in")
|
||||
aud.addEventListener("change", e => this.inputSelect(e))
|
||||
vid.addEventListener("change", e => this.inputSelect(e))
|
||||
this.inputSelect()
|
||||
|
||||
navigator.mediaDevices.getUserMedia({video: true, audio: true})
|
||||
.then(media => this.gotUserMedia(media))
|
||||
.catch(err => {
|
||||
toast("Couldn't open camera!")
|
||||
})
|
||||
|
@ -81,7 +95,6 @@ class Convulse {
|
|||
let canvasStream = this.canvas.captureStream(30)
|
||||
for (let vt of canvasStream.getVideoTracks()) {
|
||||
this.mediaStream.addTrack(vt)
|
||||
console.log("Adding video track", vt)
|
||||
}
|
||||
|
||||
this.frame()
|
||||
|
@ -89,6 +102,52 @@ class Convulse {
|
|||
toast("Click anywhere to start and stop recording")
|
||||
}
|
||||
|
||||
gotUserMedia(media) {
|
||||
document.querySelector("#hello").classList.add("hidden")
|
||||
|
||||
// Set video source
|
||||
// sending this to an HTML element seems janky, is there no direct method for video?
|
||||
if (this.webcamVideo.srcObject) {
|
||||
for (let track of this.webcamVideo.srcObject.getTracks()) {
|
||||
track.stop()
|
||||
}
|
||||
}
|
||||
for (let track of media.getVideoTracks()) {
|
||||
for (let opt of document.querySelector("#video-in")) {
|
||||
if (opt.text == track.label) {
|
||||
opt.selected = true
|
||||
}
|
||||
}
|
||||
}
|
||||
this.webcamVideo.muted = true
|
||||
this.webcamVideo.srcObject = media
|
||||
this.webcamVideo.play()
|
||||
|
||||
// Set audio source
|
||||
for (let track of this.mediaStream.getAudioTracks()) {
|
||||
this.mediaStream.removeTrack(track)
|
||||
track.stop()
|
||||
}
|
||||
for (let track of media.getAudioTracks()) {
|
||||
this.mediaStream.addTrack(track)
|
||||
for (let opt of document.querySelector("#audio-in")) {
|
||||
opt.selected = (opt.value == track.deviceId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inputSelect(event) {
|
||||
let audName = document.querySelector("#audio-in").value || undefined
|
||||
let vidName = document.querySelector("#video-in").value || undefined
|
||||
let constraints = {
|
||||
audio: {deviceId: {exact: audName}},
|
||||
video: {deviceId: {exact: vidName}}
|
||||
}
|
||||
|
||||
navigator.mediaDevices.getUserMedia(constraints)
|
||||
.then(e => this.gotUserMedia(e))
|
||||
}
|
||||
|
||||
setWebcamSize(event) {
|
||||
this.webcamSize = event.target.value
|
||||
localStorage.webcamSize = this.webcamSize
|
||||
|
|
|
@ -38,6 +38,10 @@
|
|||
<button id="rec">⏺️</button>
|
||||
<a id="save">💾</a>
|
||||
</div>
|
||||
<div>
|
||||
<span>🎙️<select id="audio-in"></select></span>
|
||||
<span>🎥<select id="video-in"></select></span>
|
||||
</div>
|
||||
<div id="webcam-controls">
|
||||
UR FACE
|
||||
<input id="webcam-size" type="range" min="0" max="1" step="0.01" value="0.2">
|
||||
|
|
|
@ -1,26 +1,51 @@
|
|||
var cacheName = "convulse-v1";
|
||||
// jshint asi:true
|
||||
|
||||
var cacheName = "v2";
|
||||
var content = [
|
||||
"index.html",
|
||||
"convulse.css",
|
||||
"convulse.js",
|
||||
"convulse.png"
|
||||
];
|
||||
]
|
||||
|
||||
|
||||
self.addEventListener("install", e => {
|
||||
e.waitUntil(caches.Open(cacheName).then(cache => cache.addAll(content)));
|
||||
});
|
||||
self.addEventListener("install", preCache)
|
||||
self.addEventListener("fetch", cachingFetch)
|
||||
self.addEventListener("activate", handleActivate)
|
||||
|
||||
// Have mercy, this is a horror show
|
||||
self.addEventListener("fetch", e => {
|
||||
e.respondWith(
|
||||
caches.match(e.request).then(r => {
|
||||
return r || fetch(e.request).then(response => {
|
||||
return caches.open(cacheName).then(cache => {
|
||||
cache.put(e.request, response.clone());
|
||||
return response;
|
||||
});
|
||||
});
|
||||
function handleActivate(event){
|
||||
event.waitUntil(
|
||||
cleanup()
|
||||
)
|
||||
}
|
||||
|
||||
async function cleanup(event) {
|
||||
let cacheNames = await caches.keys()
|
||||
for (let name of cacheNames) {
|
||||
if (name != cacheName) {
|
||||
console.log("Deleting old cache", name)
|
||||
caches.delete(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function preCache(event) {
|
||||
event.waitUntil(
|
||||
caches.open(cacheName)
|
||||
.then(cache => cache.addAll(content))
|
||||
)
|
||||
}
|
||||
|
||||
// Go try to pull a newer version from the network,
|
||||
// but return what's in the cache for this request
|
||||
function cachingFetch(event) {
|
||||
fetch(event.request)
|
||||
.then(resp => {
|
||||
caches.open(cacheName)
|
||||
.then(cache => {
|
||||
cache.put(event.request, resp.clone())
|
||||
})
|
||||
);
|
||||
});
|
||||
})
|
||||
|
||||
event.respondWith(caches.match(event.request))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue