#исследуем
🎞 Запись видео на JS используя WebRTC + сохранение видео на сервер на примере PHP
Иногда, чтобы развеять свою "CRUD рутину", можно пощупать какие-то технологии, которые не так часто встречаются во время разработки стандартных веб-приложений или реализовать функционал, который редко встречается на сайтах. Хочу сделать это постоянной рубрикой, будем разбирать на реальных кейсах (если концепт интересен, то ставь огонёк 🔥).
Первая статья про WebRTC
Технология реализована для потоковой передачи видео/аудио. Пример сервиса, завязанного на WebRTC: Google Meet. Мы разберём более простой кейс использования этой технологии из реальной практики:
📋 Была поставлена задача реализовать запись видео-отзыва после заполнения формы, после чего сохранять его на сервер.
Рассмотрим два варианта решения этой задачи:
1. Давать пользователям самим загружать файлы
Думаю не стоит объяснять что пользователи вряд-ли будут усложнять себе жизнь записывая видео отдельно. На мобильных устройствах с этим попроще. Можно использовать
2. Использовать WebRTC
Казалось бы, как WebRTC может тут помочь? Для этого он имеет специальный MediaRecorder, который позволяет хранить транслируемое медиа как Blob). Удобный для пользователей вариант, который позволяет: выводить; пересмотреть и без проблем перезаписать видео.
Выбираем второй вариант
Для большего удобства использовал специальную библиотеку: RecordRTC.
На наглядный пример работы RecordRTC можете посмотреть по ссылке. Там ещё есть 30 других демо + код.
По примеру можно понять что есть много настраиваемых опций: формат; кодек; битрейт; фреймрейт и т.д..
Единственное что, перед выставлением этих опций нужно проверить совместимость (например, Safari запись видео в
Из-за вопросов совместимости принял решение записывать видео в формате
Важно убрать сериализацию. Передавать именно некодированные данные (multipart/form-data), запретить кеширование запроса. Сформировать данные для отправки:
Загрузка видео
Чтобы сжимать получаемое видео для экономии пространства на сервере можно использовать ffmpeg. После получения видео на сервер нужно обязательно проверить:
- Тип файла:
- Размер файла:
Получив количество байт (
- Другие сопутствующие проверки.
Если другие проверки отработали хорошо, то файл можно поместить куда-то в директорию, а потом проверить длительность видео запустив
Если длительность будет выше приемлемой - можно просто удалить файл.
Это в принципе всё что нужно для реализации такого функционала. Смотрите примеры, пробуйте их использовать и если есть вопросы - задавайте в комментариях 🕺.
#фронтенд #бэкенд #технологии
🎞 Запись видео на JS используя WebRTC + сохранение видео на сервер на примере PHP
Иногда, чтобы развеять свою "CRUD рутину", можно пощупать какие-то технологии, которые не так часто встречаются во время разработки стандартных веб-приложений или реализовать функционал, который редко встречается на сайтах. Хочу сделать это постоянной рубрикой, будем разбирать на реальных кейсах (если концепт интересен, то ставь огонёк 🔥).
Первая статья про WebRTC
Технология реализована для потоковой передачи видео/аудио. Пример сервиса, завязанного на WebRTC: Google Meet. Мы разберём более простой кейс использования этой технологии из реальной практики:
📋 Была поставлена задача реализовать запись видео-отзыва после заполнения формы, после чего сохранять его на сервер.
Рассмотрим два варианта решения этой задачи:
1. Давать пользователям самим загружать файлы
Думаю не стоит объяснять что пользователи вряд-ли будут усложнять себе жизнь записывая видео отдельно. На мобильных устройствах с этим попроще. Можно использовать
input
с атрибутом capture
, который указывает какую камеру включить (если значение user
- открывается фронтальная камера, а если environment
- задняя):<input type="file" accept="video/*" capture="user">Слишком большой размер входного файла + отсутствие предпросмотра/возможности записи на ПК отбрасывает этот метод (можно его использовать как вспомогательный, если WebRTC не поддерживается).
2. Использовать WebRTC
Казалось бы, как WebRTC может тут помочь? Для этого он имеет специальный MediaRecorder, который позволяет хранить транслируемое медиа как Blob). Удобный для пользователей вариант, который позволяет: выводить; пересмотреть и без проблем перезаписать видео.
Выбираем второй вариант
Для большего удобства использовал специальную библиотеку: RecordRTC.
На наглядный пример работы RecordRTC можете посмотреть по ссылке. Там ещё есть 30 других демо + код.
По примеру можно понять что есть много настраиваемых опций: формат; кодек; битрейт; фреймрейт и т.д..
Единственное что, перед выставлением этих опций нужно проверить совместимость (например, Safari запись видео в
H264
кодеке не поддерживает). Кстати наличие SSL сертификата для работы #webrtc обязательно.Из-за вопросов совместимости принял решение записывать видео в формате
webm
используя видео-кодек VP8
и аудио-кодек OPUS
. После того, как на основе примера выше была реализована запись - отправляем её на сервер.Важно убрать сериализацию. Передавать именно некодированные данные (multipart/form-data), запретить кеширование запроса. Сформировать данные для отправки:
// recorder = RecordRTC(stream, recorderConfig);Ну и реализовать саму отправку.
let currentBlob = recorder.getBlob();
let blob = new File([currentBlob], fileName, {
type: mimeType
});
let videoData = new FormData();
videoData.append('video', blob);
Загрузка видео
Чтобы сжимать получаемое видео для экономии пространства на сервере можно использовать ffmpeg. После получения видео на сервер нужно обязательно проверить:
- Тип файла:
mime_content_type($_FILES['video']['tmp_name']);
- Размер файла:
Получив количество байт (
$_FILES['video']['size']
) можно сделать ограничение (например в 200 мб.).- Другие сопутствующие проверки.
Если другие проверки отработали хорошо, то файл можно поместить куда-то в директорию, а потом проверить длительность видео запустив
ffmpeg
таким образом:shell_exec('ffmpeg -i ' . $videoPath . ' -vstats 2>&1')
или же использовать специальные библиотеки для более удобной работы с ffmpeg. Команда отдаст информацию про разрешение видео, кодек, длительность и т.д..Если длительность будет выше приемлемой - можно просто удалить файл.
Это в принципе всё что нужно для реализации такого функционала. Смотрите примеры, пробуйте их использовать и если есть вопросы - задавайте в комментариях 🕺.
#фронтенд #бэкенд #технологии
#исследуем
🎙 Делаем озвучивание текста на сайте в 3 шага (JS)
Синтезатор речи на данный момент является экспериментальной технологией, но как показывает таблица совместимости - её можно вполне массово использовать. При том она довольно простая 😳.
Как синтезировать речь?
1. Получаем точку входа:
3. Воспроизводим звук:
Бонус ⭐️. Голос озвучивания тоже можно выбирать:
🎙 Делаем озвучивание текста на сайте в 3 шага (JS)
Синтезатор речи на данный момент является экспериментальной технологией, но как показывает таблица совместимости - её можно вполне массово использовать. При том она довольно простая 😳.
Как синтезировать речь?
1. Получаем точку входа:
const synth = window.speechSynthesis;2. Делаем речевой запрос:
const message = new SpeechSynthesisUtterance("Озвучь мне это");Можем настроить под себя (необязательно) указав:
message.lang = "ru-RU"; // язык
message.pitch = "1"; // тональность звука от 0 до 2
message.rate = "1"; // скорость от 0.1 до 10
3. Воспроизводим звук:
synth.speak(message);Технология завязана на Web Speech API. Для теста можете использовать онлайн редакторы.
Бонус ⭐️. Голос озвучивания тоже можно выбирать:
let voices = synth.getVoices();#фронтенд
console.log(voices);
message.voice = voices[0];
Можно ли новичку выдавать более качественное программное решение, при этом экономя время?
Однозначно да! Казалось бы: "за двумя зайцами погонишься, ни одного не поймаешь", но не тут то было. Просто программисты (особенно начинающие), иногда изобретают велосипед, даже не подозревая про существование паттерна под их задачу.
Шаблоны (паттерны) проектирования - проверенные решения большинства проблем, которые возникают при проектировании архитектуры. Необязательно изучать их досконально. Достаточно знать то, какую проблему решает каждый шаблон. Идеально было бы попробовать реализовать каждый, основываясь на конкретных примерах (так можно ещё: подтянуть знания #ооп; улучшить стиль кода).
📖 Подробное объяснение паттернов с примерами можете почитать тут. Есть псевдокод + реализации на: #php, #typescript, #python, java, c#, c++, ruby, swift, #go.
Другие примеры:
- Паттерны на PHP;
- Паттерны на JS.
#статьи #бэкенд #фронтенд
Однозначно да! Казалось бы: "за двумя зайцами погонишься, ни одного не поймаешь", но не тут то было. Просто программисты (особенно начинающие), иногда изобретают велосипед, даже не подозревая про существование паттерна под их задачу.
Шаблоны (паттерны) проектирования - проверенные решения большинства проблем, которые возникают при проектировании архитектуры. Необязательно изучать их досконально. Достаточно знать то, какую проблему решает каждый шаблон. Идеально было бы попробовать реализовать каждый, основываясь на конкретных примерах (так можно ещё: подтянуть знания #ооп; улучшить стиль кода).
📖 Подробное объяснение паттернов с примерами можете почитать тут. Есть псевдокод + реализации на: #php, #typescript, #python, java, c#, c++, ruby, swift, #go.
Другие примеры:
- Паттерны на PHP;
- Паттерны на JS.
#статьи #бэкенд #фронтенд
#исследуем
Делаем генератор кастомного QR кода на JS (часть 1)
Для этого возьмём гибкую библиотеку qr-code-styling
1. Копируем весь пример
Тут важно заменить подключаемую версию с
2. Делаем стартовый дизайн
Чуть ниже примера описано как конфигурировать
3. Настраиваем #qr
Многие приложения поддерживают свои URL-схемы. Для телеграма, например, мы можем использовать
Обратите внимание на опцию
4. Скачиваем получившийся код
#фронтенд #статья
Делаем генератор кастомного QR кода на JS (часть 1)
Для этого возьмём гибкую библиотеку qr-code-styling
1. Копируем весь пример
Тут важно заменить подключаемую версию с
1.5.0
на 1.6.0-rc.1
, потому-что там появился функционал расширений2. Делаем стартовый дизайн
Чуть ниже примера описано как конфигурировать
QRCodeStyling
. Благо разработчик библиотеки всё упростил. Достаточно зайти на сайт, быстро настроить всё под свои нужды, после чего выкачать конфигурацию3. Настраиваем #qr
Многие приложения поддерживают свои URL-схемы. Для телеграма, например, мы можем использовать
tg://resolve?domain=deovenk
вместо https://tttttt.me/deovenk внутри data
для быстрого открытия каналаОбратите внимание на опцию
errorCorrectionLevel
. Существует 4 уровня исправления ошибок на случай если кьюар код немного сотрётся, загрязнится4. Скачиваем получившийся код
qrCode.download({name: 'qr', extension: 'png'})Готово! Детальнее внутри комментариев 💬. Если есть вопросы, задавайте 😳
// jpeg; webp; svg
#фронтенд #статья
#исследуем
Делаем настраиваемую вибрацию на JS
👉🏻 Полная реализация внутри моего codepen проекта. Будет приятно если накините лайков за наглядность 😳
1. Запустим одну вибрацию
2. Запускаем несколько вибраций
Давайте, например, сделаем сигнал SOS:
3. Отменяем вибрацию
Допустим Вы решили отменить вибрацию по нажатию на кнопку. Для этого запускаем:
Решается это
#фронтенд
Делаем настраиваемую вибрацию на JS
👉🏻 Полная реализация внутри моего codepen проекта. Будет приятно если накините лайков за наглядность 😳
1. Запустим одну вибрацию
let launched = window.navigator.vibrate(200)Если передать слишком большое количество миллисекунд, то устройство может не выполнить операцию (зависит от конкретной модели). Если действие недопустимо, то метод вернёт
false
2. Запускаем несколько вибраций
Давайте, например, сделаем сигнал SOS:
let pattern = [100, 30, 100, 30, 100, 30, 200, 30, 200, 30, 200, 30, 100, 30, 100, 30, 100]Как видите, тут передаётся массив, который помимо длительности содержит интервалы паузы
navigator.vibrate(pattern)
3. Отменяем вибрацию
Допустим Вы решили отменить вибрацию по нажатию на кнопку. Для этого запускаем:
navigator.vibrate(0)
или navigator.vibrate([])
4. Бесконечная вибрацияРешается это
setInterval
-ом. Нужно только посчитать количество секунд, через которые повторно запускать цикл:pattern.reduce((a, b) => a + b)
✍️ Код на JS тут#фронтенд
#исследуем
Делаем всплывающее окно на сайте по стандартам (часть 1)
Вот давайте честно, кого не достали эти насквозь пронизанные div-ами диалоги, которые выглядят как один сплошной костыль 😳? Создатели браузеров подсуетились, поэтому мы наконец-то получили очень простое, нативное решение задачи
Встречайте #html элемент <dialog>
👉🏻 Полный пример внутри моего codepen проекта. На вложенных фото упрощённые вырезки
Этот тег существует уже несколько лет, но глобальную поддержку получил только сейчас
Если внутри диалога мы вставим тег <form>, то в атрибут
Псевдо-элемент ::backdrop позволяет стилизовать фон, а для создания анимации можно нацелиться на атрибут
#фронтенд
Делаем всплывающее окно на сайте по стандартам (часть 1)
Вот давайте честно, кого не достали эти насквозь пронизанные div-ами диалоги, которые выглядят как один сплошной костыль 😳? Создатели браузеров подсуетились, поэтому мы наконец-то получили очень простое, нативное решение задачи
Встречайте #html элемент <dialog>
👉🏻 Полный пример внутри моего codepen проекта. На вложенных фото упрощённые вырезки
Этот тег существует уже несколько лет, но глобальную поддержку получил только сейчас
Если внутри диалога мы вставим тег <form>, то в атрибут
method
мы можем передать значение dialog
, при котором событие submit
вызовется без отправки данных. При этом форма автоматически закроется и вызовет событие close
, которое вернёт dialog.returnValue
При открытии диалогового окна (dialog.showModal()
) важно обнулять прошлое значение, потому-что оно не стираетсяПсевдо-элемент ::backdrop позволяет стилизовать фон, а для создания анимации можно нацелиться на атрибут
open
💬 Пишите вопросы в комментариях#фронтенд
#совет дня
Если поле находится за пределами формы, то вы можете установить input-у атрибут form (или кнопке), указав id формы. Так-же вместо указания label-у поля через атрибут for желательно завернуть input внутрь label.
☕️ Поддержать канал чашкой кофе
#фронтенд #html
Если поле находится за пределами формы, то вы можете установить input-у атрибут form (или кнопке), указав id формы. Так-же вместо указания label-у поля через атрибут for желательно завернуть input внутрь label.
☕️ Поддержать канал чашкой кофе
#фронтенд #html
#совет дня
Очистить массив от дубликатов можно всего одной строкой используя Set. Set - особый вид коллекции, который по своей сути содержит множество уникальных значений. Чтобы сделать из Set объекта массив - мы используем оператор spread (...).
☕️ Поддержать чашечкой кофе
#фронтенд #js
Очистить массив от дубликатов можно всего одной строкой используя Set. Set - особый вид коллекции, который по своей сути содержит множество уникальных значений. Чтобы сделать из Set объекта массив - мы используем оператор spread (...).
☕️ Поддержать чашечкой кофе
#фронтенд #js
#совет дня по #css
Сделать на всю высоту и ширину элемент с фиксированным/абсолютным позиционированием - можно без top, left, right, bottom 🤔. Достаточно один раз указать
☕️ Поддержать чашечкой кофе
#фронтенд
Сделать на всю высоту и ширину элемент с фиксированным/абсолютным позиционированием - можно без top, left, right, bottom 🤔. Достаточно один раз указать
inset: 0
.☕️ Поддержать чашечкой кофе
#фронтенд
#создаём
Редактор файлов внутри браузера (часть 1)
Мы будем сохранять изменения файлов/папок сразу на устройстве пользователя. Другими словами - редактировать файловую систему прямиком из браузера 🤯!
Это новая рубрика, где мы будем пошагово создавать интересные #проект(-ы). Можете поддержать мой формат чашечкой кофе ☕️.
Для управления файлами используется File System Access API.
Пошаговый процесс создания редактора с пояснениями показан на скринах. При выборе файлов поставил ограничения на: txt; md форматы. Если хотите открыть другой файл (например, html), то явно укажите это внутри проводника, как показано на втором шаге.
На третьем этапе, при получение хэндлера, возвращается массив, но из-за того что файл один - используется деструктуризация [].
👨💻 Посмотреть код: https://stackblitz.com/edit/fs
(Важно: проверить редактор можно используя Chrome, Edge или Opera нажав на кнопку Open In New Window из-за того что доступ к файлам не выдаётся iframe-у, подробнее в комментариях)
#исследуем #фронтенд #js
Редактор файлов внутри браузера (часть 1)
Мы будем сохранять изменения файлов/папок сразу на устройстве пользователя. Другими словами - редактировать файловую систему прямиком из браузера 🤯!
Это новая рубрика, где мы будем пошагово создавать интересные #проект(-ы). Можете поддержать мой формат чашечкой кофе ☕️.
Для управления файлами используется File System Access API.
Пошаговый процесс создания редактора с пояснениями показан на скринах. При выборе файлов поставил ограничения на: txt; md форматы. Если хотите открыть другой файл (например, html), то явно укажите это внутри проводника, как показано на втором шаге.
На третьем этапе, при получение хэндлера, возвращается массив, но из-за того что файл один - используется деструктуризация [].
👨💻 Посмотреть код: https://stackblitz.com/edit/fs
(Важно: проверить редактор можно используя Chrome, Edge или Opera нажав на кнопку Open In New Window из-за того что доступ к файлам не выдаётся iframe-у, подробнее в комментариях)
#исследуем #фронтенд #js
#блог
Наткнулся сегодня на пикчу про CSS Grid-ы (скрин 1), которая зафорсилась за считаные часы. Со стороны она может показаться полезной, но не всё так однозначно. Меня удивило обилие комментариев, где люди пишут что гуглят это каждый раз 🤔. Удивило потому-что вместо использования этого рисунка можно ввести display: grid внутри DevTools-ов, после чего появится иконка где можно визуально выбрать всё что душа пожелает (вложение 2).
Сейчас готовится второй пост про создание файлового редактора в браузере. Тем, кто хочет полноценно освоить CSS Grid-ы в игровой форме, могу порекомендовать вот этот сайт: https://cssgridgarden.com/.
#совет #фронтенд #css
Наткнулся сегодня на пикчу про CSS Grid-ы (скрин 1), которая зафорсилась за считаные часы. Со стороны она может показаться полезной, но не всё так однозначно. Меня удивило обилие комментариев, где люди пишут что гуглят это каждый раз 🤔. Удивило потому-что вместо использования этого рисунка можно ввести display: grid внутри DevTools-ов, после чего появится иконка где можно визуально выбрать всё что душа пожелает (вложение 2).
Сейчас готовится второй пост про создание файлового редактора в браузере. Тем, кто хочет полноценно освоить CSS Grid-ы в игровой форме, могу порекомендовать вот этот сайт: https://cssgridgarden.com/.
#совет #фронтенд #css
#исследуем
Пользователь закрыл страницу? Оповестим об этом сервер
Допустим, при закрытии страницы мы хотим на JS отправить какую-то аналитику или ошибки, которые встретил пользователь (или хотим менять статус онлайна, например). Проблема в том, что браузер может запретить отправку XHR запроса.
Beacon API - решение, позволяющее отправить асинхронный неблокирующий POST запрос и не дожидается ответа от сервера:
События, которые нам нужны:
- visibilitychange - переключение/открытие/сворачивание вкладки;
- beforeunload - перед закрытием вкладки.
Мы так-же можем использовать fetch, указывая атрибуту keepalive значение true.
#фронтенд
Пользователь закрыл страницу? Оповестим об этом сервер
Допустим, при закрытии страницы мы хотим на JS отправить какую-то аналитику или ошибки, которые встретил пользователь (или хотим менять статус онлайна, например). Проблема в том, что браузер может запретить отправку XHR запроса.
Beacon API - решение, позволяющее отправить асинхронный неблокирующий POST запрос и не дожидается ответа от сервера:
navigator.sendBeacon('/log', JSON.stringify({ meta: 'info' }));
Поддерживается почти везде. Данные можно отправлять разного типа: FormData, URLSearchParams, даже Blob и др.События, которые нам нужны:
- visibilitychange - переключение/открытие/сворачивание вкладки;
- beforeunload - перед закрытием вкладки.
Мы так-же можем использовать fetch, указывая атрибуту keepalive значение true.
#фронтенд
#исследуем
Получаем цвет любого пикселя экрана нативной пипеткой на JS (как в DevTools-ах)
Например, мы хотим дать возможность пользователю по клику вызвать пипетку, которой он сможет выбрать цвет даже вне окна браузера. Для нас избыточен
1. Получаем объект пипетки:
👨💻 Посмотреть код: https://stackblitz.com/edit/eyedropper
(пример с завершением запроса)
#фронтенд
Получаем цвет любого пикселя экрана нативной пипеткой на JS (как в DevTools-ах)
Например, мы хотим дать возможность пользователю по клику вызвать пипетку, которой он сможет выбрать цвет даже вне окна браузера. Для нас избыточен
<input type="color" />Для этого в браузере существует EyeDropper API:
1. Получаем объект пипетки:
const dropper = new EyeDropper();
2. Вызываем метод open, который возвращает промис. В результате получаем выбранный цвет в HEX формате:const { sRGBHex } = await dropper.open();Пользователь может закрыть пипетку нажав на Escape. Чтобы сделать это самостоятельно при долгом бездействии или наступлении какого-то события - используем AbortController.
👨💻 Посмотреть код: https://stackblitz.com/edit/eyedropper
(пример с завершением запроса)
#фронтенд
#блог
Почему большинство считает что фронтенд проще бэкенда? Можете объяснить?
Когда люди это говорят, то они явно не рофлят. Не утверждаю что фронтенд сложнее бэкенда, но утверждать обратное как-то странно. Раньше сам писал бэк, понимаю его сложности.
Давайте просто перечислю пару непростых веб-технологий:
WebGL; WebRTC; WebXR; WebAssembly; WebDriver; Streams Web API; Web Workers.
Это ещё не потолок. Лично у меня после этого язык не поворачивается сказать что фронтенд проще.
#блиц #бэкенд #фронтенд
Почему большинство считает что фронтенд проще бэкенда? Можете объяснить?
Когда люди это говорят, то они явно не рофлят. Не утверждаю что фронтенд сложнее бэкенда, но утверждать обратное как-то странно. Раньше сам писал бэк, понимаю его сложности.
Давайте просто перечислю пару непростых веб-технологий:
WebGL; WebRTC; WebXR; WebAssembly; WebDriver; Streams Web API; Web Workers.
Это ещё не потолок. Лично у меня после этого язык не поворачивается сказать что фронтенд проще.
#блиц #бэкенд #фронтенд
Про веб-разработку
Вы знали что сделать шейр экрана на JS/TS из браузера проще чем сделать модалку? Вот пример использования Screen Capture API. Тут мы указывает что хотим записывать видео без аудио. На 15 строке указываем что выводим этот стрим внутри html тега: <video autoplay></video>…
Останавливаем шейр экрана на JS.
Проверяем наличие стрима вызывая метод getTracks. Он возвращает массив всех текущих медиа-треков. Если такие есть, то останавливаем каждый вызывая stop().
Кстати свойство srcObject у видео относительно новое. Оно позволяет програмно устанавливать поток данных. Раньше для таких целей использовали обычный
Так-как тут используется TypeScript, то можете заметить что на 32 строке
#блиц #фронтенд
Проверяем наличие стрима вызывая метод getTracks. Он возвращает массив всех текущих медиа-треков. Если такие есть, то останавливаем каждый вызывая stop().
Кстати свойство srcObject у видео относительно новое. Оно позволяет програмно устанавливать поток данных. Раньше для таких целей использовали обычный
src
, куда вставляли ссылку созданную из URL.createObjectURL()
.Так-как тут используется TypeScript, то можете заметить что на 32 строке
(<MediaStream>video.srcObject)
явно указан тип. Дело в том что TS считает, что video.srcObject
может быть MediaStream, Blob или MediaSource. Только MediaStream имеет метод getTracks
, поэтому важно указать это явно.#блиц #фронтенд
This media is not supported in your browser
VIEW IN TELEGRAM
#исследуем
Делаем голосовые сообщения на JS/TS как в телеграмме (часть 1)
Рабочий прототип вместе с кодом можете потестить по ссылке 👨💻 или посмотреть как это работает на видео
Это вводная часть. Первым делом нужно создать звуковую-волну используя библиотеку wavesurfer.js. Не забываем так-же установить типы
1. Создаём элемент для волны
2. Кастомизируем волну
#фронтенд
Делаем голосовые сообщения на JS/TS как в телеграмме (часть 1)
Рабочий прототип вместе с кодом можете потестить по ссылке 👨💻 или посмотреть как это работает на видео
Это вводная часть. Первым делом нужно создать звуковую-волну используя библиотеку wavesurfer.js. Не забываем так-же установить типы
@types/wavesurfer.js
. 1. Создаём элемент для волны
const waveWrapper: HTMLDivElement = document.createElement("div")После чего вставляем его куда-то на страницу
2. Кастомизируем волну
const waveSurfer: WaveSurfer = WaveSurfer.create({3. Загружаем аудио и воспроизводим
container: waveWrapper,
waveColor: "#D2D2D2",
responsive: true,
...
});
waveSurfer.load('/voice.mp3')Первый шаг на пути реализации функционала голосовых сообщений готов. Напомню что ссылка на прототип сверху 👆🏻
waveSurfer.play()
#фронтенд
Что делает void оператор JS/TS? Пример использования
Допустим мы вызываем какую-то
Допустим мы вызываем какую-то
async
функцию, которая делает запрос к серверу и нам не нужно обрабатывать вернувшийся результат в Promise
. Мы можем напрямую это указать. Указывая этот оператор - всегда будет возвращаться undefined
, даже если что-то должно вернуться. С оператором void ещё можно использовать самовызывающиеся (IIFE) функции:void function deovenk() { /* ... */ }()#блиц #фронтенд