This commit is contained in:
Hanusiak Piotr 2022-02-08 11:54:18 +01:00
parent 6f7bdf8fe4
commit d6f0c19838
6 changed files with 40 additions and 65 deletions

View File

@ -19,7 +19,6 @@
export let game: Game; export let game: Game;
let selectedCamera: string | undefined = undefined; let selectedCamera: string | undefined = undefined;
let selectedMicrophone: string | undefined = undefined; let selectedMicrophone: string | undefined = undefined;
let volume = 0;
const enableCameraScene = game.scene.getScene(EnableCameraSceneName) as EnableCameraScene; const enableCameraScene = game.scene.getScene(EnableCameraSceneName) as EnableCameraScene;
@ -61,12 +60,7 @@
} }
}); });
const unsubscribeLocalVolumeStore = localVolumeStore.subscribe((value) => {
volume = value ?? 0;
});
onDestroy(() => { onDestroy(() => {
unsubscribeLocalVolumeStore();
unsubscribeLocalStreamStore(); unsubscribeLocalStreamStore();
}); });
@ -95,7 +89,7 @@
<img class="background-img" src={cinemaCloseImg} alt="" /> <img class="background-img" src={cinemaCloseImg} alt="" />
</div> </div>
{/if} {/if}
<HorizontalSoundMeterWidget {volume} /> <HorizontalSoundMeterWidget volume={$localVolumeStore} />
<section class="selectWebcamForm"> <section class="selectWebcamForm">
{#if $cameraListStore.length > 1} {#if $cameraListStore.length > 1}

View File

@ -7,7 +7,6 @@
import LL from "../i18n/i18n-svelte"; import LL from "../i18n/i18n-svelte";
let stream: MediaStream | null; let stream: MediaStream | null;
let volume = 0;
const unsubscribeLocalStreamStore = localStreamStore.subscribe((value) => { const unsubscribeLocalStreamStore = localStreamStore.subscribe((value) => {
if (value.type === "success") { if (value.type === "success") {
@ -17,13 +16,8 @@
} }
}); });
const unsubscribeLocalVolumeStore = localVolumeStore.subscribe((value) => {
volume = value ?? 0;
});
onDestroy(() => { onDestroy(() => {
unsubscribeLocalStreamStore(); unsubscribeLocalStreamStore();
unsubscribeLocalVolumeStore();
}); });
let isSilent: boolean; let isSilent: boolean;
@ -59,7 +53,7 @@
<div class="is-silent">{$LL.camera.my.silentZone()}</div> <div class="is-silent">{$LL.camera.my.silentZone()}</div>
{:else if $localStreamStore.type === "success" && $localStreamStore.stream} {:else if $localStreamStore.type === "success" && $localStreamStore.stream}
<video class="my-cam-video" use:srcObject={stream} autoplay muted playsinline /> <video class="my-cam-video" use:srcObject={stream} autoplay muted playsinline />
<SoundMeterWidget {volume} /> <SoundMeterWidget volume={$localVolumeStore} />
{/if} {/if}
</div> </div>

View File

@ -11,7 +11,7 @@
import type { Streamable } from "../../Stores/StreamableCollectionStore"; import type { Streamable } from "../../Stores/StreamableCollectionStore";
import Woka from "../Woka/Woka.svelte"; import Woka from "../Woka/Woka.svelte";
import { onDestroy, onMount } from "svelte"; import { onMount } from "svelte";
import { isMediaBreakpointOnly } from "../../Utils/BreakpointsUtils"; import { isMediaBreakpointOnly } from "../../Utils/BreakpointsUtils";
export let clickable = false; export let clickable = false;
@ -30,11 +30,6 @@
let embedScreen: EmbedScreen; let embedScreen: EmbedScreen;
let videoContainer: HTMLDivElement; let videoContainer: HTMLDivElement;
let minimized = isMediaBreakpointOnly("md"); let minimized = isMediaBreakpointOnly("md");
let volume = 0;
const unsubscribe = volumeStore.subscribe((value) => {
volume = value ?? 0;
});
if (peer) { if (peer) {
embedScreen = { embedScreen = {
@ -54,10 +49,6 @@
onMount(() => { onMount(() => {
resizeObserver.observe(videoContainer); resizeObserver.observe(videoContainer);
}); });
onDestroy(() => {
unsubscribe();
});
</script> </script>
<div <div
@ -103,7 +94,7 @@
/> />
<img src={blockSignImg} draggable="false" on:dragstart|preventDefault={noDrag} class="block-logo" alt="Block" /> <img src={blockSignImg} draggable="false" on:dragstart|preventDefault={noDrag} class="block-logo" alt="Block" />
{#if $constraintStore && $constraintStore.audio !== false} {#if $constraintStore && $constraintStore.audio !== false}
<SoundMeterWidget {volume} /> <SoundMeterWidget volume={$volumeStore} />
{/if} {/if}
</div> </div>

View File

@ -1,4 +1,4 @@
import type { IAnalyserNode, IAudioContext, IMediaStreamAudioSourceNode } from "standardized-audio-context"; import { AudioContext, IAnalyserNode, IAudioContext, IMediaStreamAudioSourceNode } from "standardized-audio-context";
/** /**
* Class to measure the sound volume of a media stream * Class to measure the sound volume of a media stream
@ -6,41 +6,15 @@ import type { IAnalyserNode, IAudioContext, IMediaStreamAudioSourceNode } from "
export class SoundMeter { export class SoundMeter {
private instant: number; private instant: number;
private clip: number; private clip: number;
//private script: ScriptProcessorNode;
private analyser: IAnalyserNode<IAudioContext> | undefined; private analyser: IAnalyserNode<IAudioContext> | undefined;
private dataArray: Uint8Array | undefined; private dataArray: Uint8Array | undefined;
private context: IAudioContext | undefined; private context: IAudioContext | undefined;
private source: IMediaStreamAudioSourceNode<IAudioContext> | undefined; private source: IMediaStreamAudioSourceNode<IAudioContext> | undefined;
constructor() { constructor(mediaStream: MediaStream) {
this.instant = 0.0; this.instant = 0.0;
this.clip = 0.0; this.clip = 0.0;
//this.script = context.createScriptProcessor(2048, 1, 1); this.connectToSource(mediaStream, new AudioContext());
}
private init(context: IAudioContext) {
this.context = context;
this.analyser = this.context.createAnalyser();
this.analyser.fftSize = 2048;
const bufferLength = this.analyser.fftSize;
this.dataArray = new Uint8Array(bufferLength);
}
public connectToSource(stream: MediaStream, context: IAudioContext): void {
if (this.source !== undefined) {
this.stop();
}
this.init(context);
this.source = this.context?.createMediaStreamSource(stream);
if (this.analyser !== undefined) {
this.source?.connect(this.analyser);
}
//analyser.connect(distortion);
//distortion.connect(this.context.destination);
//this.analyser.connect(this.context.destination);
} }
public getVolume(): number { public getVolume(): number {
@ -78,4 +52,29 @@ export class SoundMeter {
this.dataArray = undefined; this.dataArray = undefined;
this.source = undefined; this.source = undefined;
} }
private init(context: IAudioContext) {
this.context = context;
this.analyser = this.context.createAnalyser();
this.analyser.fftSize = 2048;
const bufferLength = this.analyser.fftSize;
this.dataArray = new Uint8Array(bufferLength);
}
private connectToSource(stream: MediaStream, context: IAudioContext): void {
if (this.source !== undefined) {
this.stop();
}
this.init(context);
this.source = this.context?.createMediaStreamSource(stream);
if (this.analyser !== undefined) {
this.source?.connect(this.analyser);
}
//analyser.connect(distortion);
//distortion.connect(this.context.destination);
//this.analyser.connect(this.context.destination);
}
} }

View File

@ -543,23 +543,21 @@ export const obtainedMediaConstraintStore = derived<Readable<MediaStreamConstrai
} }
); );
export const localVolumeStore = readable<number | null>(null, (set) => { export const localVolumeStore = readable<number | undefined>(undefined, (set) => {
let timeout: ReturnType<typeof setTimeout>; let timeout: ReturnType<typeof setTimeout>;
const unsubscribe = localStreamStore.subscribe((localStreamStoreValue) => { const unsubscribe = localStreamStore.subscribe((localStreamStoreValue) => {
clearInterval(timeout); clearInterval(timeout);
if (localStreamStoreValue.type === "error") { if (localStreamStoreValue.type === "error") {
set(null); set(undefined);
return; return;
} }
const soundMeter = new SoundMeter();
const mediaStream = localStreamStoreValue.stream; const mediaStream = localStreamStoreValue.stream;
if (mediaStream === null || mediaStream.getAudioTracks().length <= 0) { if (mediaStream === null || mediaStream.getAudioTracks().length <= 0) {
set(null); set(undefined);
return; return;
} }
const soundMeter = new SoundMeter(mediaStream);
soundMeter.connectToSource(mediaStream, new AudioContext());
let error = false; let error = false;
timeout = setInterval(() => { timeout = setInterval(() => {

View File

@ -36,7 +36,7 @@ export class VideoPeer extends Peer {
private onBlockSubscribe: Subscription; private onBlockSubscribe: Subscription;
private onUnBlockSubscribe: Subscription; private onUnBlockSubscribe: Subscription;
public readonly streamStore: Readable<MediaStream | null>; public readonly streamStore: Readable<MediaStream | null>;
public readonly volumeStore: Readable<number | null>; public readonly volumeStore: Readable<number | undefined>;
public readonly statusStore: Readable<PeerStatus>; public readonly statusStore: Readable<PeerStatus>;
public readonly constraintsStore: Readable<ObtainedMediaStreamConstraints | null>; public readonly constraintsStore: Readable<ObtainedMediaStreamConstraints | null>;
private newMessageSubscribtion: Subscription | undefined; private newMessageSubscribtion: Subscription | undefined;
@ -73,15 +73,14 @@ export class VideoPeer extends Peer {
}; };
}); });
this.volumeStore = readable<number | null>(null, (set) => { this.volumeStore = readable<number | undefined>(undefined, (set) => {
let timeout: ReturnType<typeof setTimeout>; let timeout: ReturnType<typeof setTimeout>;
const unsubscribe = this.streamStore.subscribe((mediaStream) => { const unsubscribe = this.streamStore.subscribe((mediaStream) => {
if (mediaStream === null || mediaStream.getAudioTracks().length <= 0) { if (mediaStream === null || mediaStream.getAudioTracks().length <= 0) {
set(null); set(undefined);
return; return;
} }
const soundMeter = new SoundMeter(); const soundMeter = new SoundMeter(mediaStream);
soundMeter.connectToSource(mediaStream, new AudioContext());
let error = false; let error = false;
timeout = setInterval(() => { timeout = setInterval(() => {