Веду разработку сервиса, который позволяет создавать "живые счетчики" (например, показывающие сколько осталось секунд до наступления того или иного события). Эти счетчики конечно же реализованы с использованием JS. Встала задача создать механизм позволяющий делиться этими счетчиками в соц-сетях, да так чтобы они оставались живыми (то есть чтобы юзер увидев пост мог лицезреть бегущие циферки). Единственным решением я увидел стриминг. То есть видео-стрим. Тот же ВК позволяет создавать видео-трансляции и делится ими. Для создания трансляции со своего рабочего стола достаточно установить необходимый софт, и в его настройках ввести ссылку (URL) и ключ (KEY) потока. Эти данные представляются самим VK при создании трансляции. Но.. как мне сделать так чтобы сервер запускал этот стрим? Причем этот стрим должен захватывать конкретный "живой счетчик"...
Все это в данный момент работает на PHP (Ubuntu + Nginx), но разумеется чтобы решить такую задачу одним только PHP не обойтись. В моей голове выстроилась такая схема
Вопрос(ы)
Насколько вообще такой подход жизнеспособен? Не упадет ли сервер если таких стримов будет сразу очень много? Возможно ли вообще нечто подобное провернуть на сервере с Ubuntu? Может есть какие-то более оптимальные варианты решения такой задачи? Знаю что есть puppeteer для эмуляции бразуера, но можно ли его как-то приспособить для стриминга?
Удалось найти решение, не известно насколько удачное, но мало ли, может кому-то пригодится. Решение таки заключается в онлайн-трансляции виджетов (по сути веб-страниц) в соц-сети.
Как это работает?
Что нам для этого нужно?
Node.js + puppeteer - puppeteer это API для управления браузером chrome. То есть при помощи puppeteer сервер как-раз сможет заходить на страницы и рендерить их в картинку. Но есть одно "но" - puppeteer работает на nodejs, поэтому в начале нужно установить сам nodejs на сервер, а затем при помощи нодовского пакетного менеджера npm установить puppeteer. Код "скринкастера" у меня получился таким:
(async () => {
try{
// Заходим на страницу
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({width: WIDTH, height: HEIGHT});
await page.goto(URL);
await console.log('Some kind of screen casting started...');
// Начинаем неистово скриншотить
// Использую здесь именно for для уникальности названия временных файлов
for(let i = 0; i < Number.MAX_SAFE_INTEGER; i++)
{
try{
// Скриншотим во временный файл, затем его переименовываем
// для избежания проблем с блокировкой ресурса
await page.screenshot({path: __dirname+'/../frames/frame_'+ID+'.tmp.jpg',quality: QUALITY});
await fs.renameSync(__dirname+'/../frames/frame_'+ID+'.tmp.jpg',__dirname+'/../frames/frame_'+ID+'.jpg');
}
catch(err){
await console.log(err);
}
}
// Выход из браузера
await browser.close();
await console.log('Some kind of screen casting stopped.');
}catch(error){
console.log(error);
process.exit();
}
})();
FFmpeg - для трансляции этого изображения в соц-сети. FFmpeg в целом это инструмент для работы с видео, но он также поддерживает возможность трансляции видео по протоколу rtmp, который и используют большинство соц-сетей для проведения трансляций. Во первых нужно установить ffmpeg на сервер, во вторых нужно подобрать правильные параметры запуска чтобы транслировать наш постоянно-меняющийся скриншот как видео. В итоге у меня получилась примерно такая команда: ffmpeg -re -y -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -framerate 15 -re -loop 1 -f image2 -i {$pathToFrame} -c:a aac -strict -2 -ac 2 -ar 44100 -b:a 128k -b:v 2500K -vcodec libx264 -pix_fmt yuv420p -vf scale=1280:-1 -r 30 -g 60 -f flv {$rtmpUrl}
. Это запустит трансляцию видео с частотой кадров 15 FPS, битрейтом 2500K, пустой звуковой дорожкой с частотой дискретизации 44100 и битрейтом 128k (иногда соц-сети не запускают трансляцию без аудио). Исходная картинка $pathToFrame должна по размерам соответствовать необходимым требованиям соц-сетей. $rtmpUrl - это сам URL трансляции представляющий из себя URL/KEY (через слеш)
В итоге можно запустить 2 процесса - один это nodejs который скринкастит нужную страницу, и второй это ffmpeg который транслирует этот кадр как видео. Всё это конечно только предварительное решение и многое еще нужно оптимизировать, но в целом можно осуществлять онлайн трансляцию веб-страниц таким образом.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Создать массив «Список покупок»Каждый элемент массива является объектом, который содержит название продукта, необходимое количество и куплен...
У меня есть компонент(в этом случае не важно какой, важна суть), в котором что-то записано в template, все по дефолту
Я не силен в js и только начинаю разбираться с нимСмог смастерить вот такой код, его задача:
Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском