From 6f72a041d8f90c1bc2b958d735bf1d085a6b5e23 Mon Sep 17 00:00:00 2001 From: Nikolai Giman Date: Tue, 15 Jul 2025 17:14:33 +0200 Subject: [PATCH] feat: add volume control and output device selection --- .gitignore | 5 +- README.md | 26 +++ packages/dev-app/.gitignore | 1 + .../dev-app/src/components/VolumeChanger.vue | 23 +++ packages/dev-app/src/router/index.ts | 12 ++ packages/dev-app/src/views/HomeView.vue | 15 ++ .../src/views/examples/AdvancedTranslator.vue | 7 +- .../examples/ChangeAudioOutputDevice.vue | 195 ++++++++++++++++++ .../src/views/examples/FromAudioFile.vue | 164 +++++++++++++++ packages/lib/README.md | 26 +++ packages/lib/package.json | 2 +- packages/lib/src/PalabraClient.model.ts | 8 - packages/lib/src/PalabraClient.ts | 125 ++++++----- .../lib/src/__tests__/PalabraClient.test.ts | 73 ++++++- .../__tests__/PalabraWebRtcTransport.test.ts | 1 + packages/lib/src/api/api.model.ts | 29 ++- packages/lib/src/api/api.ts | 60 +++--- packages/lib/src/lib.ts | 7 +- .../transport/PalabraWebRtcTransport.model.ts | 4 +- .../src/transport/PalabraWebRtcTransport.ts | 33 ++- packages/lib/src/utils/browser-devices.ts | 18 +- packages/lib/src/utils/index.ts | 7 + packages/lib/src/utils/track-from-file.ts | 43 ++++ packages/lib/src/utils/utils.ts | 3 + pnpm-lock.yaml | 121 +++++++++++ 25 files changed, 883 insertions(+), 125 deletions(-) create mode 100644 packages/dev-app/src/components/VolumeChanger.vue create mode 100644 packages/dev-app/src/views/examples/ChangeAudioOutputDevice.vue create mode 100644 packages/dev-app/src/views/examples/FromAudioFile.vue create mode 100644 packages/lib/src/utils/index.ts create mode 100644 packages/lib/src/utils/track-from-file.ts create mode 100644 packages/lib/src/utils/utils.ts diff --git a/.gitignore b/.gitignore index 059ba01..c59eb46 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ .env .vscode node_modules -dist \ No newline at end of file +dist +coverage +.DS_Store +tmp \ No newline at end of file diff --git a/README.md b/README.md index b1f51b4..45eee74 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,24 @@ await client.stopPlayback(); await client.stopTranslation(); ``` +### 6. Output device changing + +> [!NOTE] +> Audio output device switching is supported only in browsers that implement setSinkId(). In unsupported browsers like Safari, this method will have no effect. +> +```ts +await client.changeAudioOutputDevice('deviceId') +``` + +### 7. Volume changing for audio track by language + +> [!NOTE] +> Volume should be a value between 0.0 and 1.0, where 0.0 is muted and 1.0 is maximum volume. +> +```ts +client.setVolume('es', .7) +``` + > [!NOTE] > Browsers may restrict audio playback initiated without user interaction. > Each browser may also define user interaction differently. @@ -145,6 +163,14 @@ new PalabraClient(options: PalabraClientData) - `unmuteOriginalTrack(): void` Unmutes the original audio track (microphone). +- `setVolume(language: string, volume: number): void` +Set volume for audio track by given language. Volume should be between 0.0 (muted) and 1.0 (maximum) + +- `changeAudioOutputDevice(deviceId: string): Promise` + Change output device + > Note: Audio output device switching is supported only in browsers that implement setSinkId(). In unsupported browsers like Safari, this method will have no effect. + > + - `cleanup(): Promise` Stops translation and playback, releases resources, and resets the client to its initial state. diff --git a/packages/dev-app/.gitignore b/packages/dev-app/.gitignore index aef72d0..015a8db 100644 --- a/packages/dev-app/.gitignore +++ b/packages/dev-app/.gitignore @@ -31,3 +31,4 @@ coverage test-results/ playwright-report/ +*.test.mp3 diff --git a/packages/dev-app/src/components/VolumeChanger.vue b/packages/dev-app/src/components/VolumeChanger.vue new file mode 100644 index 0000000..5b7e572 --- /dev/null +++ b/packages/dev-app/src/components/VolumeChanger.vue @@ -0,0 +1,23 @@ + + + \ No newline at end of file diff --git a/packages/dev-app/src/router/index.ts b/packages/dev-app/src/router/index.ts index bcc0ba9..0bad924 100644 --- a/packages/dev-app/src/router/index.ts +++ b/packages/dev-app/src/router/index.ts @@ -3,6 +3,8 @@ import HomeView from '../views/HomeView.vue' import BasicTranslator from '../views/examples/BasicTranslator.vue' import AdvancedTranslator from '../views/examples/AdvancedTranslator.vue' import AudioElement from '../views/examples/AudioElement.vue' +import FromAudioFile from '../views/examples/FromAudioFile.vue' +import ChangeAudioOutputDevice from '@/views/examples/ChangeAudioOutputDevice.vue' const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), @@ -26,6 +28,16 @@ const router = createRouter({ path: '/audio-element', name: 'audio-element', component: AudioElement + }, + { + path: '/from-audio-file', + name: 'from-audio-file', + component: FromAudioFile + }, + { + path: '/change-audio-output-device', + name: 'change-audio-output-device', + component: ChangeAudioOutputDevice } ] }, diff --git a/packages/dev-app/src/views/HomeView.vue b/packages/dev-app/src/views/HomeView.vue index 1e60cd8..132a994 100644 --- a/packages/dev-app/src/views/HomeView.vue +++ b/packages/dev-app/src/views/HomeView.vue @@ -17,6 +17,7 @@ const route = useRoute();
diff --git a/packages/dev-app/src/views/examples/AdvancedTranslator.vue b/packages/dev-app/src/views/examples/AdvancedTranslator.vue index 96529ad..bf1b479 100644 --- a/packages/dev-app/src/views/examples/AdvancedTranslator.vue +++ b/packages/dev-app/src/views/examples/AdvancedTranslator.vue @@ -7,9 +7,9 @@ import { type PalabraClientData, } from '@palabra-ai/translator'; import { onMounted, ref } from 'vue'; +import VolumeChanger from '@/components/VolumeChanger.vue'; let palabraClient: PalabraClient | null = null; -const currentMicTrack: MediaStreamTrack | null = null; const isTranslationStarted = ref(false); const isMicrophoneMuted = ref(false); @@ -58,7 +58,6 @@ const stopTranslation = async () => { }; const toggleMicrophone = () => { - if (!currentMicTrack) return; if (isMicrophoneMuted.value) { palabraClient?.unmuteOriginalTrack(); isMicrophoneMuted.value = false; @@ -110,6 +109,10 @@ const setTranslateTo = async (code: PalabraClientData['translateTo']) => {