|
import { writable, type Writable } from 'svelte/store'; |
|
|
|
export enum MediaStreamStatus { |
|
INIT = "init", |
|
CONNECTED = "connected", |
|
DISCONNECTED = "disconnected", |
|
} |
|
export const onFrameChangeStore: Writable<{ now: Number, metadata: VideoFrameCallbackMetadata, blob: Blob }> = writable(); |
|
export const isMediaStreaming = writable(MediaStreamStatus.INIT); |
|
|
|
interface mediaStream { |
|
mediaStream: MediaStream | null; |
|
status: MediaStreamStatus |
|
devices: MediaDeviceInfo[]; |
|
} |
|
|
|
const initialState: mediaStream = { |
|
mediaStream: null, |
|
status: MediaStreamStatus.INIT, |
|
devices: [], |
|
}; |
|
|
|
export const mediaStreamState = writable(initialState); |
|
|
|
export const mediaStreamActions = { |
|
async enumerateDevices() { |
|
console.log("Enumerating devices"); |
|
await navigator.mediaDevices.enumerateDevices() |
|
.then(devices => { |
|
const cameras = devices.filter(device => device.kind === 'videoinput'); |
|
console.log("Cameras: ", cameras); |
|
mediaStreamState.update((state) => ({ |
|
...state, |
|
devices: cameras, |
|
})); |
|
}) |
|
.catch(err => { |
|
console.error(err); |
|
}); |
|
}, |
|
async start(mediaDevicedID?: string) { |
|
const constraints = { |
|
audio: false, |
|
video: { |
|
width: 1024, height: 1024, deviceId: mediaDevicedID |
|
} |
|
}; |
|
|
|
await navigator.mediaDevices |
|
.getUserMedia(constraints) |
|
.then((mediaStream) => { |
|
mediaStreamState.update((state) => ({ |
|
...state, |
|
mediaStream: mediaStream, |
|
status: MediaStreamStatus.CONNECTED, |
|
})); |
|
isMediaStreaming.set(MediaStreamStatus.CONNECTED); |
|
}) |
|
.catch((err) => { |
|
console.error(`${err.name}: ${err.message}`); |
|
isMediaStreaming.set(MediaStreamStatus.DISCONNECTED); |
|
}); |
|
}, |
|
async switchCamera(mediaDevicedID: string) { |
|
const constraints = { |
|
audio: false, |
|
video: { width: 1024, height: 1024, deviceId: mediaDevicedID } |
|
}; |
|
await navigator.mediaDevices |
|
.getUserMedia(constraints) |
|
.then((mediaStream) => { |
|
mediaStreamState.update((state) => ({ |
|
...state, |
|
mediaStream: mediaStream, |
|
status: MediaStreamStatus.CONNECTED, |
|
})); |
|
}) |
|
.catch((err) => { |
|
console.error(`${err.name}: ${err.message}`); |
|
}); |
|
}, |
|
async stop() { |
|
navigator.mediaDevices.getUserMedia({ video: true }).then((mediaStream) => { |
|
mediaStream.getTracks().forEach((track) => track.stop()); |
|
}); |
|
mediaStreamState.update((state) => ({ |
|
...state, |
|
mediaStream: null, |
|
status: MediaStreamStatus.DISCONNECTED, |
|
})); |
|
isMediaStreaming.set(MediaStreamStatus.DISCONNECTED); |
|
}, |
|
}; |