diff --git a/package-lock.json b/package-lock.json
index d6cf4fd..1dcb498 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,6 +10,7 @@
"dependencies": {
"@types/chromecast-caf-receiver": "^6.0.16",
"@types/chromecast-caf-sender": "^1.0.10",
+ "uuid": "^11.0.3",
"vite-plugin-list-directory-contents": "^1.4.5",
"vue": "^3.4.29"
},
@@ -2526,6 +2527,18 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/uuid": {
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.3.tgz",
+ "integrity": "sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==",
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
+ "bin": {
+ "uuid": "dist/esm/bin/uuid"
+ }
+ },
"node_modules/validator": {
"version": "13.12.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz",
diff --git a/package.json b/package.json
index 8b253d0..c9bfc5c 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,7 @@
"dependencies": {
"@types/chromecast-caf-receiver": "^6.0.16",
"@types/chromecast-caf-sender": "^1.0.10",
+ "uuid": "^11.0.3",
"vite-plugin-list-directory-contents": "^1.4.5",
"vue": "^3.4.29"
},
diff --git a/src/chromecast.ts b/src/chromecast.ts
index 1bf7683..e860b63 100644
--- a/src/chromecast.ts
+++ b/src/chromecast.ts
@@ -8,13 +8,9 @@ const chromecast = new ChromecastChannelCaster(searchParams.get('ws') ?? undefin
const postMessage = new PostMessageChannel(window);
chromecast.initialize();
chromecast.on((msg) => {
- console.log('CHROMECAST MESSAGE', msg);
- console.log(msg);
postMessage.send(msg);
})
postMessage.on((msg) => {
- console.log('POST MESSAGE', msg);
- console.log(msg);
chromecast.send(msg);
});
diff --git a/src/components/Audio/AudioCard.vue b/src/components/Audio/AudioCard.vue
index ee7f544..6c59e80 100644
--- a/src/components/Audio/AudioCard.vue
+++ b/src/components/Audio/AudioCard.vue
@@ -6,7 +6,7 @@
@dragover.prevent="onDragover"
>
@@ -32,6 +37,9 @@
Sfx
+
+ Parallel
+
Tab Source
@@ -50,6 +58,8 @@ import TabSource from './TabSource.vue';
import DeviceVolume from './DeviceVolume.vue';
import {AudioNodeManager} from '../../model/Audio/AudioNodesManager';
import {debounce} from '../../utils/debounce';
+import {ParallelGroupNode} from '../../model/Audio/ParallelGroupNode';
+import Parallel from './Parallel.vue';
const fs = inject(MountedFsSymbol)!;
const audioContext = inject(AudioContextSymbol) as AudioContext;
@@ -61,29 +71,43 @@ const nodes = reactive(audioNodesManager.restore({fs, audioContext}));
function addNode(name: string) {
if (name === 'playlist') {
nodes.push(reactive(new PlaylistGroupNode({
- currentTrack: 0,
- currentTrackTime: 0,
- volume: 100,
- isMuted: false,
- sounds: [],
+ label: 'Playlist',
+ currentTrack: 0,
+ currentTrackTime: 0,
+ volume: 100,
+ isMuted: false,
+ sounds: [],
}, {
fs,
audioContext,
})))
} else if (name === 'sfx') {
nodes.push(reactive(new SfxGroupNode({
- isMuted: false,
- volume: 100,
- sounds: [],
+ label: 'SFX',
+ isMuted: false,
+ volume: 100,
+ sounds: [],
}, {
fs,
audioContext,
})))
} else if (name === 'tab') {
nodes.push(reactive(new TabSourceNode({
- isMuted: false,
- volume: 100,
- sounds: [],
+ label: 'Tab Source',
+ isMuted: false,
+ volume: 100,
+ sounds: [],
+ }, {
+ fs,
+ audioContext,
+ })))
+ } else if (name === 'parallel') {
+ nodes.push(reactive(new ParallelGroupNode({
+ label: 'Parallel',
+ isMuted: false,
+ volume: 100,
+ enabledTracks: [],
+ sounds: [],
}, {
fs,
audioContext,
@@ -115,10 +139,8 @@ const dest = audioContext.createGain();
watch(() => deviceManager.audioDevices.length, () => {
- console.log('DEVICE_MANAGER', deviceManager)
for(const device of deviceManager.audioDevices) {
dest.connect(device.audioSink);
- console.log('DEVICES', device, device.audioSink);
}
}, {immediate: true})
diff --git a/src/components/Audio/modal.vue b/src/components/Audio/modal.vue
index 1fff3c7..8b2814c 100644
--- a/src/components/Audio/modal.vue
+++ b/src/components/Audio/modal.vue
@@ -35,7 +35,6 @@ function onClose() {
watch(() => props.open, (open) => {
if (open) {
- console.log(dialog.value);
dialog.value?.showModal();
popover.value?.showPopover();
} else {
diff --git a/src/components/FileManager/FileManager.vue b/src/components/FileManager/FileManager.vue
index 0fdc95a..38991d1 100644
--- a/src/components/FileManager/FileManager.vue
+++ b/src/components/FileManager/FileManager.vue
@@ -69,7 +69,6 @@ function onFilePreview(file: VirtualFile) {
watch(search, async (value) => {
searchResults.value = [];
- console.log('search', value, value.length);
if (value.length < 3) {
return;
}
@@ -117,16 +116,6 @@ async function buildIndex() {
grid-gap: 4px;
}
-.file-manager__preview {
- max-height: 25vh;
- transition: max-height 200ms;
- transition-behavior: allow-discrete;
-}
-
-.file-manager__preview:hover {
- max-height: initial;
-}
-
.file-manager-dir {
list-style-type: none;
padding-left: 1rem;
diff --git a/src/components/FileManager/FileManagerDir.vue b/src/components/FileManager/FileManagerDir.vue
index 2a9a7ba..6c08135 100644
--- a/src/components/FileManager/FileManagerDir.vue
+++ b/src/components/FileManager/FileManagerDir.vue
@@ -59,8 +59,12 @@ async function toggleCollapse() {
async function fetchDirectoryContent() {
try {
isLoading.value = true;
- // preload from cache
- content.value = await fs.listDir(props.dir, {cache: 'only-cache'});
+ try {
+ // preload from cache
+ content.value = await fs.listDir(props.dir, {cache: 'only-cache'});
+ } catch (err) {
+ // ignore missing cache
+ }
// replace with network
content.value = await fs.listDir(props.dir, {cache: 'use-network'});
} finally {
diff --git a/src/components/FileManager/FilePreview.vue b/src/components/FileManager/FilePreview.vue
index 4421402..a73a325 100644
--- a/src/components/FileManager/FilePreview.vue
+++ b/src/components/FileManager/FilePreview.vue
@@ -1,27 +1,37 @@
-
-
![]()
+
+
+
-
+ autoplay
+ muted
+ loop
+ playsinline
+ class="file-preview__video"
+ >
+
+
\ No newline at end of file
diff --git a/src/components/Map/MapControl.vue b/src/components/Map/MapControl.vue
index c914635..4f16199 100644
--- a/src/components/Map/MapControl.vue
+++ b/src/components/Map/MapControl.vue
@@ -58,7 +58,6 @@ let canvasDisplay: undefined | CanvasDisplay;
function selectScreen (screen: any) {
if (screen.imageSink?.display) {
selectedScreen.value = screen;
- console.log('selectScreen!!!', screen.imageSink?.display);
canvasDisplay?.disconnectTarget(canvas.value!);
canvasDisplay = screen.imageSink?.display;
canvasDisplay?.connectTarget(canvas.value!);
@@ -66,7 +65,6 @@ function selectScreen (screen: any) {
}
async function onDrop(file: VirtualFile) {
- console.log('onDrop!!', file);
onLoad(file);
}
@@ -77,7 +75,6 @@ const dragging = ref(false);
function onScroll(event: WheelEvent) {
event.preventDefault();
- // console.log('scroll', event.deltaY, event.offsetX, event.offsetY);
const delta = -1 * event.deltaY / 2000;
if (!canvasDisplay) {
return;
diff --git a/src/components/Map/MapRenderer.vue b/src/components/Map/MapRenderer.vue
index e4ff70d..41819c9 100644
--- a/src/components/Map/MapRenderer.vue
+++ b/src/components/Map/MapRenderer.vue
@@ -41,7 +41,6 @@ function redraw() {
ctx: map.value!.getContext('2d')!,
...mapContext.value,
};
- console.log('redraw', ctx.scale);
ctx.ctx.fillStyle = 'black';
ctx.ctx.fillRect(0, 0, ctx.virtualWidth, ctx.virtualHeight);
for (const layer of props.layers) {
diff --git a/src/components/Map/helpers.ts b/src/components/Map/helpers.ts
index de95de9..6b5db12 100644
--- a/src/components/Map/helpers.ts
+++ b/src/components/Map/helpers.ts
@@ -1,6 +1,5 @@
export async function loadImage(src: string | File): Promise
{
if (src instanceof File) {
- console.log('Creating object URL');
src = URL.createObjectURL(src);
}
try {
diff --git a/src/components/Map/object.ts b/src/components/Map/object.ts
index adf2d60..5b4268b 100644
--- a/src/components/Map/object.ts
+++ b/src/components/Map/object.ts
@@ -43,7 +43,6 @@ export class DistanceMeasurement implements CanvasDisplayDrawable {
ctx.scale(1/display.scale, 1/display.scale);
ctx.translate(display.offsetX - display.width/2, display.offsetY - display.height / 2 );
if (this.pointer) {
- console.log('Drawing pointer', );
ctx.fillStyle = 'rgba(255,0,0,0.5)';
ctx.beginPath();
@@ -65,7 +64,9 @@ export class DistanceMeasurement implements CanvasDisplayDrawable {
return;
}
const lengthPx = Math.sqrt(Math.pow(this.start!.x - this.end!.x, 2) + Math.pow(this.start!.y - this.end!.y, 2));
+ const chebychevPx = Math.max(Math.abs(this.start!.x - this.end!.x), Math.abs(this.start!.y - this.end!.y));
const lengthFeet = ((lengthPx / display.dpi) * 5) / display.scale;
+ const chebychevFeet = Math.round(((chebychevPx / display.dpi) / display.scale)) * 5;
const roundedFeets = Math.floor(lengthFeet/5) * 5;
const roundedPx = ((roundedFeets) / 5) * display.dpi * display.scale;
const halfInchInPx = 0.5 * display.dpi * display.scale;
@@ -93,7 +94,7 @@ export class DistanceMeasurement implements CanvasDisplayDrawable {
ctx.fillRect(this.end!.x, this.end!.y - 30, 200, 40);
ctx.font = "30px Arial";
ctx.fillStyle = 'red';
- ctx.fillText(`${roundedFeets} / ${lengthFeet.toFixed(2)} ft`, this.end!.x + 5, this.end!.y);
+ ctx.fillText(`${chebychevFeet} / ${lengthFeet.toFixed(2)} ft`, this.end!.x + 5, this.end!.y);
}
}
@@ -131,7 +132,9 @@ export class MapLayerDrawable implements CanvasDisplayDrawable {
}
if (this.file.type.startsWith('image/')) {
this.img = await loadImage(this.file);
- this.mapWidthInInches = this.mapWidth ?? 10;
+ if (this.mapWidth) {
+ this.mapWidthInInches = this.mapWidth;
+ }
if (this.img.naturalWidth < this.img.naturalHeight) {
this.rotation = 1;
}
@@ -146,6 +149,9 @@ export class MapLayerDrawable implements CanvasDisplayDrawable {
video.loop = true;
video.play();
await videoMeta;
+ if (this.mapWidth) {
+ this.mapWidthInInches = this.mapWidth;
+ }
if (video.videoWidth < video.videoHeight) {
this.rotation = 1;
}
@@ -169,6 +175,7 @@ export class MapLayerDrawable implements CanvasDisplayDrawable {
private setDefaultDPI(display: CanvasDisplay, width: number, height: number) {
if (this.dpi === undefined) {
this.dpi = Math.min((width / display.width), height / display.height) * display.dpi;
+ this.mapWidth = Math.floor(width / this.dpi);
}
}
@@ -280,7 +287,6 @@ export class CanvasDisplay {
this.width = width;
this.height = height;
if (diameter) {
- console.log('Setting diameter', diameter);
this.setDiameter(diameter);
}
this.offsetX = 0;
@@ -364,7 +370,6 @@ export class CanvasDisplay {
this.targets.add(target);
if (this.targets.size > 0) {
this.start();
- console.log('Canvas', this.canvas);
}
}
@@ -374,7 +379,6 @@ export class CanvasDisplay {
async getStream() {
this.redrawBuffer();
- console.log('Streamed Canvas', this.canvas.width, this.canvas.height);
await new Promise((resolve) => requestAnimationFrame(resolve));
return this.canvas.captureStream(25);
}
diff --git a/src/components/RemoteDevices/RemoteDevices.vue b/src/components/RemoteDevices/RemoteDevices.vue
index fceef8c..4cf9363 100644
--- a/src/components/RemoteDevices/RemoteDevices.vue
+++ b/src/components/RemoteDevices/RemoteDevices.vue
@@ -53,7 +53,6 @@ import {DeviceConfig} from '../../model/Remote/RemoteDeviceManager';
const name = ref('');
const manager = inject(RemoteDeviceManagerSymbol)!;
-console.log(manager);
const localWindowDialog = ref();
const availableDevices = ref([]);
diff --git a/src/components/ScreenManager/RemoteScreen.vue b/src/components/ScreenManager/RemoteScreen.vue
index 3cc93c7..dea6a2e 100644
--- a/src/components/ScreenManager/RemoteScreen.vue
+++ b/src/components/ScreenManager/RemoteScreen.vue
@@ -55,7 +55,6 @@ const {onMouseDown} = useMouseDragging()
function onWheel(event: WheelEvent) {
scale.value = Math.max(10, Math.min(1000, scale.value + event.deltaY / 100));
- console.log('scroll', event.deltaY, scale.value);
}
@@ -71,7 +70,6 @@ async function loadFile(meta: VirtualFile, file: File) {
const map = new MapLayerDrawable(file, meta?.map?.width);
await map.preloadFile();
imageSink.value.display.mapLayer = map
- console.log(imageSink.value?.display);
}
}
@@ -95,8 +93,6 @@ async function onDrop(event: DragEvent) {
await loadFile(meta, file);
}
}
- console.log('files', event.dataTransfer?.files);
- console.log('drop', event.dataTransfer?.getData('application/json'));
}
diff --git a/src/components/Soundboard.vue b/src/components/Soundboard.vue
index 2ec3c43..f9e8d36 100644
--- a/src/components/Soundboard.vue
+++ b/src/components/Soundboard.vue
@@ -8,6 +8,5 @@ import {reactive} from 'vue';
import {SoundPlayer} from '../model/SoundPlayer';
const soundPlayer = reactive(new SoundPlayer());
-console.log(soundPlayer);
\ No newline at end of file
diff --git a/src/components/Tabs.vue b/src/components/Tabs.vue
index 21f472a..9914c7b 100644
--- a/src/components/Tabs.vue
+++ b/src/components/Tabs.vue
@@ -26,8 +26,6 @@ const slots = defineSlots<{
Id: string,
}>()
-console.log(slots)
-
const selectedTab = ref(props.tabs?.[0]?.key);
diff --git a/src/main.ts b/src/main.ts
index 0f8ea0b..12ed506 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -12,7 +12,6 @@ const app = createApp(ControlApp);
const chromecastChannelCaster = new ChromecastChannelCaster();
chromecastChannelCaster.initialize();
-console.log('chromecastChannelCaster', chromecastChannelCaster);
const audioContext = new AudioContext();
@@ -44,6 +43,13 @@ app
key: '426pBJgSyfmgJAaUmNjk',
share: 'nCKcVyl',
},
+ {
+ name: 'Scenes',
+ type: 'filestash',
+ domain: 'https://files.fisoft.eu',
+ key: '426pBJgSyfmgJAaUmNjk',
+ share: 'ONiRCBi',
+ },
{
name: 'Audio',
type: 'filestash',
diff --git a/src/model/Audio/AudioNodesManager.ts b/src/model/Audio/AudioNodesManager.ts
index 7227956..fed04ad 100644
--- a/src/model/Audio/AudioNodesManager.ts
+++ b/src/model/Audio/AudioNodesManager.ts
@@ -1,3 +1,4 @@
+import { ParallelGroupNode } from "./ParallelGroupNode";
import { PlaylistGroupNode } from "./PlaylistGroupNode";
import { SfxGroupNode } from "./SfxGroupNode";
import { SoundGroupNode } from "./SoundGroupNode";
@@ -6,7 +7,7 @@ import { SoundboardContext } from "./types";
type SerializedNode> = ReturnType
-export type SupportedDefinitions = SerializedNode | SerializedNode | SerializedNode
+export type SupportedDefinitions = SerializedNode | SerializedNode | SerializedNode | SerializedNode;
export class AudioNodeManager {
@@ -23,6 +24,8 @@ export class AudioNodeManager {
return new SfxGroupNode(definition, ctx);
} else if (definition.type === 'tabSource') {
return new TabSourceNode(definition, ctx);
+ } else if (definition.type === 'parallel') {
+ return new ParallelGroupNode(definition, ctx);
} else {
throw new Error('Invalid node type');
}
diff --git a/src/model/Audio/ParallelGroupNode.ts b/src/model/Audio/ParallelGroupNode.ts
new file mode 100644
index 0000000..946ccf7
--- /dev/null
+++ b/src/model/Audio/ParallelGroupNode.ts
@@ -0,0 +1,75 @@
+import { VirtualFile } from "../FileSystem/types";
+import { SoundGroupNode, SoundGroupNodeOptions } from "./SoundGroupNode";
+import { MediaElementSoundNode } from "./SoundNode";
+
+export interface ParallelGroupNodeOptions extends SoundGroupNodeOptions {
+ enabledTracks: string[];
+}
+
+export class ParallelGroupNode extends SoundGroupNode {
+
+ public readonly type = 'parallel';
+ private enabledTracks: Set = new Set();
+
+ get isPlaying() {
+ return this.soundNodes.some(sound => sound.isPlaying);
+ }
+
+ play() {
+ this.soundNodes.forEach((sound, i) => {
+ if (this.enabledTracks.has(sound.id)) {
+ sound.play();
+ }
+ });
+ }
+
+ removeSoundNode(node: MediaElementSoundNode) {
+ this.enabledTracks.delete(node.id);
+ super.removeSoundNode(node);
+ }
+
+ stop() {
+ this.soundNodes.forEach(sound => sound.stop());
+ }
+
+ togglePlay() {
+ if (this.isPlaying) {
+ this.stop();
+ } else {
+ this.play();
+ }
+ }
+
+ deserializeOptions(options: ParallelGroupNodeOptions) {
+ this.enabledTracks = new Set(options.enabledTracks);
+ super.deserializeOptions(options);
+ }
+
+ toggleTrack(track: MediaElementSoundNode) {
+ if (this.enabledTracks.has(track.id)) {
+ track.pause();
+ this.enabledTracks.delete(track.id);
+ } else {
+ this.enabledTracks.add(track.id);
+ track.play();
+ }
+ }
+
+ serializeOptions() {
+ return {
+ ...super.serializeOptions(),
+ volume: this.volume,
+ isMuted: this.options.isMuted,
+ enabledTracks: [...this.options.enabledTracks.values()] as string[],
+ type: this.type,
+ } as const;
+ }
+
+ addSound(vFile: VirtualFile) {
+ this.addSoundNode({
+ type: 'mediaElement',
+ vFile,
+ volume: 100,
+ });
+ }
+}
\ No newline at end of file
diff --git a/src/model/Audio/SoundGroupNode.ts b/src/model/Audio/SoundGroupNode.ts
index 18ae65a..ef8631f 100644
--- a/src/model/Audio/SoundGroupNode.ts
+++ b/src/model/Audio/SoundGroupNode.ts
@@ -4,6 +4,7 @@ import { BufferedSoundNode, MediaElementSoundNode, PartiaSoundNodeOptions, Sound
import { SoundboardContext } from "./types";
export interface SoundGroupNodeOptions {
+ label: string,
volume: number,
isMuted: boolean,
sounds: PartiaSoundNodeOptions[]
@@ -29,25 +30,35 @@ export class DeviceSource {
}
}
-export abstract class SoundGroupNode {
+export abstract class SoundGroupNode {
public abstract readonly type: string;
public deviceSources: Map = new Map();
+ // @ts-ignore it's in deserializeOptions
protected options: Omit
protected gainNode: GainNode;
- protected soundNodes: SoundNode[] = [];
+ protected soundNodes: TNode[] = [];
constructor(
options: T,
protected ctx: SoundboardContext
) {
- this.options = options;
+ this.deserializeOptions(options);
this.gainNode = this.ctx.audioContext.createGain();
this.gainNode.gain.value = (options.volume / 100);
for (const sound of options.sounds) {
this.addSoundNode(sound);
}
}
+
+ get label() {
+ return this.options.label;
+ }
+
+ set label(val: string) {
+ this.options.label = val;
+ }
+
// @ts-ignore
addSound(vFile: VirtualFile) {
// implement in subclass
@@ -56,16 +67,18 @@ export abstract class SoundGroupNode {
addSoundNode(options: PartiaSoundNodeOptions) {
if (options.type === 'buffered') {
const sound = new BufferedSoundNode(options, this.ctx);
+ // @ts-ignore
this.soundNodes.push(sound);
sound.connect(this.gainNode);
} else if (options.type === 'mediaElement') {
const sound = new MediaElementSoundNode(options, this.ctx);
+ // @ts-ignore
this.soundNodes.push(sound);
sound.connect(this.gainNode);
}
}
- removeSoundNode(node: SoundNode) {
+ removeSoundNode(node: TNode) {
node?.stop();
const index = this.soundNodes.indexOf(node);
if (index > -1) {
@@ -86,7 +99,6 @@ export abstract class SoundGroupNode {
connect(destination: AudioNode) {
- console.log('connecting', this, destination);
this.gainNode.connect(destination);
}
@@ -140,6 +152,10 @@ export abstract class SoundGroupNode {
return this.deviceSources.get(remoteDevice)!;
}
+ deserializeOptions(options: T) {
+ this.options = options;
+ }
+
serializeOptions() {
return {
...this.options,
diff --git a/src/model/Audio/SoundNode.ts b/src/model/Audio/SoundNode.ts
index ac71ba9..9940c89 100644
--- a/src/model/Audio/SoundNode.ts
+++ b/src/model/Audio/SoundNode.ts
@@ -1,23 +1,27 @@
import { MountedFs } from "../FileSystem/MountedFs";
import { VirtualFile } from "../FileSystem/types";
import { SoundboardContext } from "./types";
+import { v4 as uuidv4 } from 'uuid';
export interface PartiaSoundNodeOptions {
+ id?: string;
vFile: VirtualFile;
volume?: number;
type: 'buffered' | 'mediaElement';
}
export interface SoundNodeOptions extends PartiaSoundNodeOptions {
+ id: string;
volume: number;
}
-export abstract class SoundNode {
+export abstract class SoundNode {
+ public readonly id: string;
protected gainNode: GainNode;
protected file?: File;
- public options: SoundNodeOptions;
+ public options: T;
public readonly numberOfInputs = 0;
public readonly numberOfOutputs = 1;
protected activeSources: AudioBufferSourceNode[] = [];
@@ -29,10 +33,14 @@ export abstract class SoundNode {
options: PartiaSoundNodeOptions,
ctx: SoundboardContext,
) {
+
+ // @ts-ignore
this.options = {
+ id: uuidv4(),
...options,
volume: options.volume ?? 100
}
+ this.id = options.id!;
this.audioContext = ctx.audioContext;
this.fs = ctx.fs;
this.gainNode = this.audioContext.createGain();
@@ -58,7 +66,6 @@ export abstract class SoundNode {
}
connect(destination: AudioNode) {
- console.log('connecting', this, destination);
this.gainNode.connect(destination);
}
@@ -72,6 +79,7 @@ export abstract class SoundNode {
setVolume(volume: number) {
this.gainNode.gain.value = volume / 100;
+ this.options.volume = volume;
}
getVolume() {
@@ -115,7 +123,11 @@ export class BufferedSoundNode extends SoundNode {
}
}
-export class MediaElementSoundNode extends SoundNode {
+export interface MediaElementSoundNodeOptions extends SoundNodeOptions {
+ loop: boolean;
+}
+
+export class MediaElementSoundNode extends SoundNode {
private mediaElement?: HTMLMediaElement;
private source?: MediaElementAudioSourceNode;
private _isPlaying = false;
@@ -124,6 +136,9 @@ export class MediaElementSoundNode extends SoundNode {
await super.preload();
if (!this.mediaElement) {
this.mediaElement = document.createElement('audio');
+ if (this.options.loop) {
+ this.mediaElement.loop = true;
+ }
this.mediaElement.src = URL.createObjectURL(this.file!);
this.source = this.audioContext.createMediaElementSource(this.mediaElement);
this.source.connect(this.gainNode);
@@ -132,7 +147,6 @@ export class MediaElementSoundNode extends SoundNode {
this._isPlaying = false;
});
this.mediaElement.addEventListener('playing', (event) => {
- console.log(event);
this._isPlaying = true;
});
this.mediaElement.addEventListener('pause', () => {
diff --git a/src/model/Audio/TabSourceNode.ts b/src/model/Audio/TabSourceNode.ts
index 4b2d08c..e45e33a 100644
--- a/src/model/Audio/TabSourceNode.ts
+++ b/src/model/Audio/TabSourceNode.ts
@@ -38,7 +38,6 @@ export class TabSourceNode extends SoundGroupNode {
surfaceSwitching: "include",
monitorTypeSurfaces: "include",
});
- console.log(this.stream);
this.source = this.ctx.audioContext.createMediaStreamSource(this.stream);
this.source.connect(this.gainNode);
} catch (err) {
diff --git a/src/model/Remote/Channels/WebRTCChannel.ts b/src/model/Remote/Channels/WebRTCChannel.ts
index 19786aa..69eb5f1 100644
--- a/src/model/Remote/Channels/WebRTCChannel.ts
+++ b/src/model/Remote/Channels/WebRTCChannel.ts
@@ -128,12 +128,10 @@ export class WebRtcChannelSummon extends MessageEmitter implements JsonChannelSu
event.streams.forEach((stream) => {
stream.getTracks().forEach((track) => {
if (event.track.kind === 'audio') {
- console.log('audio track', track);
const audioElement = document.createElement('audio');
audioElement.srcObject = stream; // Attach the received stream
audioElement.play();
} else if (event.track.kind === 'video') {
- console.log('video track', track);
const videoEl = document.getElementById('mainVideo') as HTMLVideoElement;
if (videoEl) {
videoEl.srcObject = stream;
diff --git a/src/model/Remote/RemoteDeviceManager.ts b/src/model/Remote/RemoteDeviceManager.ts
index 7013e20..3ef6343 100644
--- a/src/model/Remote/RemoteDeviceManager.ts
+++ b/src/model/Remote/RemoteDeviceManager.ts
@@ -47,7 +47,6 @@ export class RemoteDeviceManager {
}
async add(device: DeviceConfig, connect: boolean = false): Promise {
- console.log('add', device);
const instance = await this.createInstance(device);
if (!instance) {
return;
diff --git a/src/model/SoundPlayer.ts b/src/model/SoundPlayer.ts
index 040f986..e55b0f9 100644
--- a/src/model/SoundPlayer.ts
+++ b/src/model/SoundPlayer.ts
@@ -16,10 +16,7 @@ export class SoundPlayer {
const randomOption = options[Math.floor(Math.random() * options.length)];
const soundBuffer = await this.fetchSound(sound, randomOption);
this.playBuffer(soundBuffer);
- console.log(`Playing sound: ${sound}`);
- } else {
- console.log(`Sound not found: ${sound}`);
- }
+ }
}
async fetchSoundOptions(sound: string) {
@@ -40,7 +37,6 @@ export class SoundPlayer {
if (this.cache.has(url)) {
return this.cache.get(url)!;
}
- console.log(`Fetching sound: ${sound}/${options}`);
const arrayBuffer = await (await fetch(url)).arrayBuffer();
const audioBuffer = await this.ctx.decodeAudioData(arrayBuffer);
this.cache.set(url, audioBuffer);
diff --git a/src/modules/map/MapScene.vue b/src/modules/map/MapScene.vue
index 56a16db..4482b48 100644
--- a/src/modules/map/MapScene.vue
+++ b/src/modules/map/MapScene.vue
@@ -108,7 +108,6 @@ const dynamicStyle = computed(() => {
function onVideoLoaded(event: Event) {
- console.log('video loaded', event.target);
mediaDimensions.value = {
width: video.value!.videoWidth,
height: video.value!.videoHeight,
diff --git a/src/modules/summon/Debug.vue b/src/modules/summon/Debug.vue
index 931db4d..35a0055 100644
--- a/src/modules/summon/Debug.vue
+++ b/src/modules/summon/Debug.vue
@@ -13,7 +13,6 @@ import { JsonChannelSymbol, WebRtcChannelSymbol } from '../../model/injectionSym
const jsonMessages = ref<{source: 'json' | 'webrtc', message: Message}[]>([]);
const lastMessages = computed(() => [...jsonMessages.value].reverse().slice(0, 10));
-console.log(jsonMessages, lastMessages);
const channel = inject(JsonChannelSymbol)!;
const webRTC = inject(WebRtcChannelSymbol)!;
channel.on((message) => {