-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from sunnydanu/feat(new-tool)-microphone-tester
feat(new-tool)-microphone-tester
- Loading branch information
Showing
9 changed files
with
255 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<script setup lang="ts"> | ||
import { useI18n } from 'vue-i18n'; | ||
import { useMessage } from 'naive-ui'; | ||
import { useMicrophoneService } from './mic-tester.service'; | ||
const message = useMessage(); | ||
const { t } = useI18n(); | ||
const { startMicReplay, stopMicReplay, loudnessLevel, isPlaying } = useMicrophoneService(message); | ||
</script> | ||
|
||
<template> | ||
<div> | ||
<c-card> | ||
<div class="control-buttons"> | ||
<c-button :disabled="isPlaying" @click="startMicReplay"> | ||
{{ t('tools.mic-tester.start-button-text') }} | ||
</c-button> | ||
<c-button :disabled="!isPlaying" @click="stopMicReplay"> | ||
{{ t('tools.mic-tester.stop-button-text') }} | ||
</c-button> | ||
</div> | ||
|
||
<!-- Loudness Meter --> | ||
<div id="loudnessMeter"> | ||
<div id="loudnessBar" :style="{ width: `${loudnessLevel}%` }" /> | ||
</div> | ||
</c-card> | ||
</div> | ||
</template> | ||
|
||
<style scoped> | ||
#loudnessMeter { | ||
width: 100%; | ||
height: 30px; | ||
background-color: rgba(46, 51, 56, 0.05); | ||
margin-top: 20px; | ||
position: relative; | ||
} | ||
#loudnessBar { | ||
height: 100%; | ||
background: linear-gradient(48deg, rgba(37, 99, 108, 1) 0%, rgba(59, 149, 111, 1) 60%, rgba(20, 160, 88, 1) 100%); | ||
} | ||
.control-buttons { | ||
display: flex; | ||
gap: 10px; | ||
margin-bottom: 20px; | ||
justify-content: space-between; | ||
} | ||
</style> |