#исследуем
🎞 Запись видео на 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 за счёт JIT
PHP 8 порадовал появлением JIT (Just-In-Time) компилятора, который значительно улучшает производительность. Реализован он как часть OPcache.
Как он работает?
Во время того как PHP интерпретируется - JIT компилирует код, после чего формируется кэш машинного кода, который потом переиспользуется. Главное преимущество в том что исходный код по-прежнему не требует предварительной компиляции. Если что-то будет изменено, то #php просто запустится без JIT (кэш пересоберётся).
Как его включить?
Забавно что он поставляется из коробки, но по сути выключен.
Необходимо всего то внутри
#бэкенд
Ускоряем PHP за счёт JIT
PHP 8 порадовал появлением JIT (Just-In-Time) компилятора, который значительно улучшает производительность. Реализован он как часть OPcache.
Как он работает?
Во время того как PHP интерпретируется - JIT компилирует код, после чего формируется кэш машинного кода, который потом переиспользуется. Главное преимущество в том что исходный код по-прежнему не требует предварительной компиляции. Если что-то будет изменено, то #php просто запустится без JIT (кэш пересоберётся).
Как его включить?
Забавно что он поставляется из коробки, но по сути выключен.
Необходимо всего то внутри
php.ini
включить OPCache обязательно задав сколько памяти JIT может использовать для своего буфера (значение буфера по умолчанию 0, которое означает что он отключен):opcache.enable=1📖 Подробно про конфигурацию JIT можете почитать тут
opcache.enable_cli=1
opcache.jit_buffer_size=256M
#бэкенд
Взрыв мозга 🤯. Большое спасибо всем двум тысячам подписчиков, которые подписались на меня за первый месяц существования канала 🥳. Отдельное спасибо тем 130 людям, которые следят за моим телеграмом ❤️.
Помогите мне пожалуйста лучше вас узнать. Долго ли вы занимаетесь программированием или может только начинаете? Какого рода контент вам интересен (обучающий, новостной, узкоспециализированный или др.)? Может посоветуете что-то. Жду комментариев, не стесняйтесь 😳.
#канал #блог
Помогите мне пожалуйста лучше вас узнать. Долго ли вы занимаетесь программированием или может только начинаете? Какого рода контент вам интересен (обучающий, новостной, узкоспециализированный или др.)? Может посоветуете что-то. Жду комментариев, не стесняйтесь 😳.
#канал #блог
Можно ли новичку выдавать более качественное программное решение, при этом экономя время?
Однозначно да! Казалось бы: "за двумя зайцами погонишься, ни одного не поймаешь", но не тут то было. Просто программисты (особенно начинающие), иногда изобретают велосипед, даже не подозревая про существование паттерна под их задачу.
Шаблоны (паттерны) проектирования - проверенные решения большинства проблем, которые возникают при проектировании архитектуры. Необязательно изучать их досконально. Достаточно знать то, какую проблему решает каждый шаблон. Идеально было бы попробовать реализовать каждый, основываясь на конкретных примерах (так можно ещё: подтянуть знания #ооп; улучшить стиль кода).
📖 Подробное объяснение паттернов с примерами можете почитать тут. Есть псевдокод + реализации на: #php, #typescript, #python, java, c#, c++, ruby, swift, #go.
Другие примеры:
- Паттерны на PHP;
- Паттерны на JS.
#статьи #бэкенд #фронтенд
Однозначно да! Казалось бы: "за двумя зайцами погонишься, ни одного не поймаешь", но не тут то было. Просто программисты (особенно начинающие), иногда изобретают велосипед, даже не подозревая про существование паттерна под их задачу.
Шаблоны (паттерны) проектирования - проверенные решения большинства проблем, которые возникают при проектировании архитектуры. Необязательно изучать их досконально. Достаточно знать то, какую проблему решает каждый шаблон. Идеально было бы попробовать реализовать каждый, основываясь на конкретных примерах (так можно ещё: подтянуть знания #ооп; улучшить стиль кода).
📖 Подробное объяснение паттернов с примерами можете почитать тут. Есть псевдокод + реализации на: #php, #typescript, #python, java, c#, c++, ruby, swift, #go.
Другие примеры:
- Паттерны на PHP;
- Паттерны на JS.
#статьи #бэкенд #фронтенд
#новость
Вышел Laravel 9 🔥
Буквально час назад вышла 9 версия одного из самых популярных #php фреймворков. Минимальная требуемая версия PHP для его установки: 8.0.
Нововведений много, поэтому разберём основные:
- Были улучшены аксессоры и мутаторы. Теперь вместо
- Используя
- Появилась возможность рендерить шаблоны
- Новые
- Стартовый комплект
- Страница исключений была полностью переработана;
- Можно создавать полнотекстовые индексы и искать по ним
-
- Новые хелперы
- Улучшенный валидатор вложенных массивов (
#бэкенд
Вышел Laravel 9 🔥
Буквально час назад вышла 9 версия одного из самых популярных #php фреймворков. Минимальная требуемая версия PHP для его установки: 8.0.
Нововведений много, поэтому разберём основные:
- Были улучшены аксессоры и мутаторы. Теперь вместо
getNameAttribute
/setNameAttribute
достаточно создать один метод без лишних префиксов;- Используя
enum
был реализован: кастинг атрибутов; неявные привязки маршрутов;- Появилась возможность рендерить шаблоны
Blade
из любого места (Blade::render
);- Новые
Blade
директивы @checked
и @selected
(+ сокращенные названия слотов);- Стартовый комплект
Laravel Breeze
получил api
режим + реализацию интерфейса Next.js
;- Страница исключений была полностью переработана;
- Можно создавать полнотекстовые индексы и искать по ним
DB::table('users')->whereFullText('bio', 'web developer')
;-
Artisan
теперь показывает процент покрытия тестами (+ улучшенный route:list
);- Новые хелперы
str
, to_route
;- Улучшенный валидатор вложенных массивов (
Rule::forEach
);#бэкенд
#исследуем
Делаем генератор кастомного 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
💬 Пишите вопросы в комментариях#фронтенд
#исследуем
🔥 Топовый способ освоить терминал Linux
Нудное заучивание команд отошло на второй план. Есть практическая игра, которая сделала процесс изучения максимально интересным. Пост должен быть полезен большинству, потому-что каждый разработчик (рано или поздно) использует терминал.
Вы играете за "хаЦкера", который ищет пароли на сервере, тем самым выполняя задания для перехода на следующий уровень. На данный момент этих уровней больше 33. Есть подсказки про то, какие команды можно использовать + полезные материалы для чтения. Топорных гайдов вы там не найдёте, потому-что нужно уметь искать информацию самостоятельно, что является важнейшим навыком для программиста.
Каждый уровень сложнее по нарастающей, что позволяет охватывать больше интересных команд.
👨💻 Сама игра: https://overthewire.org/wargames/bandit/
На этом сайте есть ещё другие игры, которые можно играть освоив базисы тут.
#статья #девопс #бэкенд #linux
🔥 Топовый способ освоить терминал Linux
Нудное заучивание команд отошло на второй план. Есть практическая игра, которая сделала процесс изучения максимально интересным. Пост должен быть полезен большинству, потому-что каждый разработчик (рано или поздно) использует терминал.
Вы играете за "хаЦкера", который ищет пароли на сервере, тем самым выполняя задания для перехода на следующий уровень. На данный момент этих уровней больше 33. Есть подсказки про то, какие команды можно использовать + полезные материалы для чтения. Топорных гайдов вы там не найдёте, потому-что нужно уметь искать информацию самостоятельно, что является важнейшим навыком для программиста.
Каждый уровень сложнее по нарастающей, что позволяет охватывать больше интересных команд.
👨💻 Сама игра: https://overthewire.org/wargames/bandit/
На этом сайте есть ещё другие игры, которые можно играть освоив базисы тут.
#статья #девопс #бэкенд #linux
#совет дня
Если поле находится за пределами формы, то вы можете установить 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
#совет дня по #laravel
Изменение модели без обновления дат
Бывают случаи когда нужно внести мелкое изменение не меня поле updated_at. Чтобы не лезть внутрь БД меняя поле вручную - можете установить значение
☕️ Поддержать чашечкой кофе
#бэкенд #php
Изменение модели без обновления дат
Бывают случаи когда нужно внести мелкое изменение не меня поле updated_at. Чтобы не лезть внутрь БД меняя поле вручную - можете установить значение
timestamps = false
. Таким образом поле updated_at останется не тронутым.☕️ Поддержать чашечкой кофе
#бэкенд #php
#совет дня по #css
Сделать на всю высоту и ширину элемент с фиксированным/абсолютным позиционированием - можно без top, left, right, bottom 🤔. Достаточно один раз указать
☕️ Поддержать чашечкой кофе
#фронтенд
Сделать на всю высоту и ширину элемент с фиксированным/абсолютным позиционированием - можно без top, left, right, bottom 🤔. Достаточно один раз указать
inset: 0
.☕️ Поддержать чашечкой кофе
#фронтенд
#совет дня по #laravel
Упрощаем проверку существования поля в запросе используя whenFilled(). Часто для таких целей мы прибегаем за помощью к if-ам, но вместо этого можем использовать фитчу от самого ларавеля
☕️ Поддержать чашечкой кофе
#бэкенд #php
Упрощаем проверку существования поля в запросе используя whenFilled(). Часто для таких целей мы прибегаем за помощью к if-ам, но вместо этого можем использовать фитчу от самого ларавеля
☕️ Поддержать чашечкой кофе
#бэкенд #php