diff --git a/components.d.ts b/components.d.ts index ae1ab037..1a6d0ac9 100644 --- a/components.d.ts +++ b/components.d.ts @@ -166,6 +166,7 @@ declare module '@vue/runtime-core' { MenuIconItem: typeof import('./src/components/MenuIconItem.vue')['default'] MenuLayout: typeof import('./src/components/MenuLayout.vue')['default'] MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default'] + MicTester: typeof import('./src/tools/mic-tester/mic-tester.vue')['default'] MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default'] MultiLinkDownloader: typeof import('./src/tools/multi-link-downloader/multi-link-downloader.vue')['default'] NA: typeof import('naive-ui')['NA'] @@ -173,13 +174,11 @@ declare module '@vue/runtime-core' { NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default'] NButton: typeof import('naive-ui')['NButton'] NCard: typeof import('naive-ui')['NCard'] - NCheckbox: typeof import('naive-ui')['NCheckbox'] NCode: typeof import('naive-ui')['NCode'] NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] NColorPicker: typeof import('naive-ui')['NColorPicker'] NConfigProvider: typeof import('naive-ui')['NConfigProvider'] NDatePicker: typeof import('naive-ui')['NDatePicker'] - NDivider: typeof import('naive-ui')['NDivider'] NDynamicInput: typeof import('naive-ui')['NDynamicInput'] NEllipsis: typeof import('naive-ui')['NEllipsis'] NForm: typeof import('naive-ui')['NForm'] diff --git a/locales/de.yml b/locales/de.yml index e1a7b070..491ba842 100644 --- a/locales/de.yml +++ b/locales/de.yml @@ -275,6 +275,11 @@ tools: mime-types: title: MIME-Typen description: Konvertiere MIME-Typen in Erweiterungen und umgekehrt. + mic-tester: + title: Mikrofonprufung + description: Wiedergabe und Visualisierung des Tons von Ihrem Mikrofon, mit einer Sekunde Verzögerung hinzugefügt + start-button-text: Mikrofon-Wiedergabe Starten + stop-button-text: Mikrofon-Wiedergabe Stoppen toml-to-json: title: TOML zu JSON description: Parse und konvertiere TOML zu JSON. diff --git a/locales/en.yml b/locales/en.yml index a587e0ac..632c3b1d 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -240,6 +240,12 @@ tools: title: MIME types description: Convert MIME types to file extensions and vice-versa. + mic-tester: + title: Microphone Tester + description: Replay and Visualize sound from Your microphone, with added one second of delay + start-button-text: Start replaying microphone + stop-button-text: Stop replaying microphone + toml-to-json: title: TOML to JSON description: Parse and convert TOML to JSON. diff --git a/locales/pl.yml b/locales/pl.yml new file mode 100644 index 00000000..e09128b9 --- /dev/null +++ b/locales/pl.yml @@ -0,0 +1,87 @@ +home: + categories: + newestTools: 'Najnowsze narzędzia' + favoriteTools: 'Twoje ulubione narzędzia' + allTools: 'Wszystkie narzędzia' + subtitle: 'Narzędzia dla programistów' + toggleMenu: 'Menu' + home: Strona główna + uiLib: 'UI Lib' + buyMeACoffee: 'Wesprzyj IT-Tools' + follow: + title: 'Podoba Ci się it-tools?' + p1: 'Wesprzyj nas gwiazdką na' + githubRepository: "repozytorium GitHub IT-Tools" + p2: 'lub śledź nas na' + twitterAccount: "koncie Twitter IT-Tools" + thankYou: 'Dziękujemy!' + nav: + github: 'Repozytorium GitHub' + githubRepository: "Repozytorium GitHub IT-Tools" + twitter: 'Konto Twitter' + twitterAccount: "Konto Twitter IT-Tools" + about: "O IT-Tools" + aboutLabel: 'O nas' + darkMode: 'Tryb ciemny' + lightMode: 'Tryb jasny' + mode: 'Przełącz tryb ciemny/jasny' +about: + content: > + # O IT-Tools + + Ta wspaniała strona, stworzona z ❤ przez [Corentina Thomasseta](https://corentin.tech?utm_source=it-tools&utm_medium=about), zbiera przydatne narzędzia dla programistów i osób pracujących w IT. Jeśli uznasz ją za pomocną, nie zapomnij się nią podzielić i dodać do ulubionych! + + IT Tools jest open-source (na licencji MIT) i darmowe, i takie pozostanie, ale koszty związane z jego hostingiem i odnawianiem domeny spoczywają na mnie. Jeśli chcesz wesprzeć moją pracę i zmotywować mnie do dodania kolejnych narzędzi, zachęcam do [wsparcia](https://www.buymeacoffee.com/cthmsst). + + ## Technologie + + IT Tools zostało stworzone w Vue.js (Vue 3) z wykorzystaniem biblioteki komponentów Naive UI i jest hostowane oraz ciągle wdrażane przez Vercel. Niektóre narzędzia korzystają z zewnętrznych bibliotek open-source, pełną listę znajdziesz w pliku [package.json](https://github.com/CorentinTh/it-tools/blob/main/package.json) repozytorium. + + ## Znalazłeś błąd? Brakuje jakiegoś narzędzia? + + Jeśli potrzebujesz narzędzia, które nie jest jeszcze dostępne, a uważasz, że mogłoby być przydatne, zapraszam do zgłoszenia propozycji funkcji w [sekcji issue](https://github.com/CorentinTh/it-tools/issues/new/choose) repozytorium GitHub. + +404: + notFound: '404 Nie znaleziono' + sorry: "Przepraszamy, ta strona nie istnieje" + maybe: 'Może to problem z cachem, spróbuj wymusić odświeżenie?' + backHome: "Powrót na stronę główną" +toolCard: + new: Nowe +search: + label: Szukaj +tools: + categories: + favorite-tools: 'Twoje ulubione narzędzia' + crypto: Kryptografia + converter: Konwerter + web: Web + images and videos: 'Obrazy i wideo' + development: Programowanie + network: Sieć + math: Matematyka + measurement: Pomiary + text: Tekst + data: Dane + + token-generator: + title: Generator tokenów + description: >- + Generuje losowy ciąg znaków z wybranych przez Ciebie znaków: wielkie + lub małe litery, cyfry i/lub symbole. + uppercase: Wielkie litery (ABC...) + lowercase: Małe litery (abc...) + numbers: Cyfry (123...) + symbols: Symbole (!-;...) + button: + copy: Kopiuj + refresh: Odśwież + copied: Token został skopiowany + length: Długość + tokenPlaceholder: Token... + + mic-tester: + title: Tester mikrofonu + description: Odtwórz i wizualizuj dźwięk z Twojego mikrofonu, z dodaną jedną sekundą opóźnienia + start-button-text: Odtwarzaj mikrofonu + stop-button-text: Zatrzymaj odtwarzanie mikrofonu diff --git a/src/modules/i18n/components/locale-selector.vue b/src/modules/i18n/components/locale-selector.vue index 3fef72ab..c2db1213 100644 --- a/src/modules/i18n/components/locale-selector.vue +++ b/src/modules/i18n/components/locale-selector.vue @@ -7,6 +7,7 @@ const localesLong: Record = { es: 'Español', fr: 'Français', no: 'Norwegian', + pl: 'Polski', pt: 'Português', ru: 'Русский', uk: 'Українська', diff --git a/src/tools/index.ts b/src/tools/index.ts index b4813649..bc22e91d 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -118,6 +118,7 @@ import { tool as dockerComposeConverter } from './docker-compose-converter'; import { tool as imageExifReader } from './image-exif-reader'; import { tool as yamlViewer } from './yaml-viewer'; import { tool as ipRangeToCidr } from './ip-range-to-cidr'; +import { tool as micTester } from './mic-tester'; export const toolsByCategory: ToolCategory[] = [ { @@ -192,6 +193,7 @@ export const toolsByCategory: ToolCategory[] = [ jsUnobfuscator, imageToCss, colorWheel, + micTester, ], }, { diff --git a/src/tools/mic-tester/index.ts b/src/tools/mic-tester/index.ts new file mode 100644 index 00000000..725e9f2c --- /dev/null +++ b/src/tools/mic-tester/index.ts @@ -0,0 +1,12 @@ +import { Microphone } from '@vicons/tabler'; +import { defineTool } from '../tool'; +import { translate } from '@/plugins/i18n.plugin'; + +export const tool = defineTool({ + name: translate('tools.mic-tester.title'), + path: '/mic-tester', + description: translate('tools.mic-tester.description'), + keywords: ['mic', 'microphone', 'test', 'check', 'troubleshoot', 'sound'], + component: () => import('./mic-tester.vue'), + icon: Microphone, +}); diff --git a/src/tools/mic-tester/mic-tester.service.ts b/src/tools/mic-tester/mic-tester.service.ts new file mode 100644 index 00000000..2dd32a09 --- /dev/null +++ b/src/tools/mic-tester/mic-tester.service.ts @@ -0,0 +1,91 @@ +import { onBeforeUnmount, ref } from 'vue'; + +interface IMessageSender { + error: (...messages: any[]) => void +} + +export function useMicrophoneService(messageSender: IMessageSender) { + let audioContext: AudioContext | null = null; + let delayNode: DelayNode | null = null; + let sourceNode: MediaStreamAudioSourceNode | null = null; + let analyserNode: AnalyserNode | null = null; + let stream: MediaStream | null = null; + + const isPlaying = ref(false); + const loudnessLevel = ref(0); // Observable for loudness + + // Measure loudness and update loudness bar + function measureLoudness() { + const dataArray = new Uint8Array(analyserNode!.frequencyBinCount); + + const updateLoudness = () => { + analyserNode!.getByteFrequencyData(dataArray); + + // Calculate average loudness + let sum = 0; + dataArray.forEach(value => sum += value); + const average = sum / dataArray.length; + + // Update the observable loudness level + loudnessLevel.value = average; + + if (isPlaying.value) { + requestAnimationFrame(updateLoudness); + } + }; + updateLoudness(); + }; + + const startMicReplay = async () => { + if (!audioContext) { + audioContext = new (window.AudioContext || (window as any).webkitAudioContext)(); + } + + try { + stream = await navigator.mediaDevices.getUserMedia({ audio: true }); + } + catch (err) { + console.error('Microphone access denied:', err); + messageSender.error('Microphone access denied (the error is also in the console):', err); + return; + } + + sourceNode = audioContext.createMediaStreamSource(stream); + delayNode = audioContext.createDelay(1.0); + delayNode.delayTime.value = 1.0; + + analyserNode = audioContext.createAnalyser(); + analyserNode.fftSize = 256; + + // Connect nodes: mic -> delay -> speakers + sourceNode.connect(delayNode); + delayNode.connect(audioContext.destination); + sourceNode.connect(analyserNode); + + isPlaying.value = true; + measureLoudness(); + }; + + function stopMicReplay() { + if (audioContext && stream) { + const tracks = stream.getTracks(); + tracks.forEach(track => track.stop()); + audioContext.close(); + audioContext = null; + isPlaying.value = false; + loudnessLevel.value = 0; + } + }; + + // Cleanup on service destruction + onBeforeUnmount(() => { + stopMicReplay(); + }); + + return { + startMicReplay, + stopMicReplay, + loudnessLevel, + isPlaying, + }; +} diff --git a/src/tools/mic-tester/mic-tester.vue b/src/tools/mic-tester/mic-tester.vue new file mode 100644 index 00000000..ee5df6cd --- /dev/null +++ b/src/tools/mic-tester/mic-tester.vue @@ -0,0 +1,50 @@ + + + + +