Мой двоюродный брат застрял, пытаясь сделать диктофон с помощью svelte из какого-то примера кода, который он нашел в Интернете. Я был большим сторонником Svelte / SvelteKit и думал, что помогу ему. Это был мой путь к лучшему пониманию того, как работает Svelte/SvelteKit.
Настройка проекта и контекст
Пример, который мой двоюродный брат пытался внедрить в Svelte, взят с этого сайта. Его замешательство возникло из-за того, что он не понял, куда скопировать/вставить код примера в его демо-версию комплекта svelte (Proof of Concept). . Я просмотрел код и тоже решил использовать в качестве референса пример MDN веб-диктофон. Итак, давайте настроим этот PoC и поможем моему двоюродному брату лучше понять Svelte.
- Настройте новый проект SvelteKit (пропустите, если добавляете в существующий проект), введя следующую команду в терминале
npm init svelte@next audio-recorder
- Следуйте инструкциям, пока ваш проект svelte kit не запустится.
- Итак, нам нужно минимум 3 элемента. HTML-элемент аудио и 2 кнопки (начать и остановить запись)
Наш файл index.svelte должен выглядеть так:
<section> <audio controls /> <button>Record</button> <button>Stop</button> </section>
3. Давайте добавим события нажатия на кнопки
<section> <audio controls /> <button on:click={startRecording}>Record</button> <button on:click={stopRecording}>Stop</button> </section>
На следующем этапе мой двоюродный брат запутался в том, как подключить код и заставить его работать, поэтому я сделаю все возможное, чтобы объяснить, почему я написал код так, как я это сделал.
Svelte и DOM
Таким образом, компоненты, написанные с расширением .svelte, не обязательно привязаны к DOM или странице HTML в тот момент, когда мы думаем. Компонент может быть доступен для нашего приложения, но не отображается автоматически в DOM. По той же причине в React есть метод componentDidMount. Это часть жизненного цикла компонента. В Svelte мы используем onMount, чтобы позволить нам писать код, который мы хотели бы выполнить после присоединения нашего компонента к DOM. (Теперь мы можем получить доступ к окну и документу из onMount)
В примере, которому следовал мой двоюродный брат, это «монтирование» запутано, потому что ванильный JS записывается непосредственно на html-страницу, а не «компилируется», как в нашем примере Svelte, и в этом случае нам нужно ждать, пока наш компонент будет смонтирован. на html-страницу перед вызовом объектов DOM или BOM.
На этом я, надеюсь, объяснил эту концепцию наилучшим образом, давайте добавим суть нашего кода в наш тег script.
Теперь мы импортируем метод onMount из Svelte и создадим первую часть нашего диктофона.
<script> import { onMount } from 'svelte' onMount(() => { }) </script> ... html markup
В примере кода используется навигатор с цепочкой промисов, но я предпочитаю использовать методы async/ await
. (Извините, у меня есть опыт работы с C#)
Example code: ------------- navigator.mediaDevices.getUserMedia({ audio: true}).then(function(stream) { var mediaRecorder = new MediaRecorder(stream); var chunks = []; mediaRecorder.addEventListener('dataavailable', function(event){ chunks.push(event.data); }); }); Preferred way: -------------- const stream = await navigator.mediaDevices.getUserMedia({ audio: true}); let mediaRecorder = null; <-- we declare this outside of onMount let media = []; <-- also declared outside of onMount mediaRecorder = new MediaRecorder(stream); mediaRecorder.ondataavailable = e => media.push(e.data);
Я изменил название чанков (мне это не кажется правильным) на носитель, так как это носитель, который мы записали. Я также добавил событие dataavailable
в объект mediaRecorder, чтобы добавить захватываемые данные в массив.
На этом этапе ваш скрипт в файле index.svelte должен выглядеть так.
<script> import { onMount } from 'svelte' let media = []; let mediaRecorder = null; onMount(async () => { const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); mediaRecorder = new MediaRecorder(stream); mediaRecorder.ondataavailable = (e) => media.push(e.data) }) </script>
Последний метод, который нам нужно добавить, — это остановить запись, а затем сохранить звук в нашем аудио-html-элементе и, наконец, сбросить наш медиа-массив, чтобы мы могли быть готовы к записи нового аудиофайла. Затем мы можем подключить наши кнопки к методам щелчка, чтобы начать и остановить запись соответственно.
<script> import { onMount } from 'svelte' let media = []; let mediaRecorder = null; onMount(async () => { const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); mediaRecorder = new MediaRecorder(stream); mediaRecorder.ondataavailable = (e) => media.push(e.data) mediaRecorder.onstop = function(){ const audio = document.querySelector('audio'); const blob = new Blob(media, {'type' : 'audio/ogg; codecs=opus' }); media = []; <-- We reset our media array audio.src = window.URL.createObjectURL(blob); } }) function startRecording(){ mediaRecorder.start() } function stopRecording() { mediaRecorder.stop() } </script>
Теперь вы сможете записывать звук с микрофона вашего устройства.
Я многому научился из этого доказательства концепции и лучше оценил метод onMount
, который является частью Svelte и других фреймворков.
Спасибо!