Для потока mjpeg, созданного с помощью node.js, как мне закодировать его в другом формате, а затем в поток? - PullRequest
4 голосов
/ 16 июня 2011

Я создаю небольшое приложение с nodejs, которое передает данные multipart / x-mixed-replace в браузер.

Эти данные создаются с данными изображения, но данные изображения могут изменяться со временем, поэтому в браузере это выглядит как видео. Данные изображения создаются с веб-камеры, поэтому в браузере это выглядит как прямая трансляция.

Но производительность не очень хорошая.

Я пробовал некоторые другие подходы: - Во-первых: используйте socket.io для отправки изображений в браузер, здесь я использую данные base64 из изображения (push-данные), а в браузере воссоздаю изображение (jpeg): работает хорошо, но только с одним или двумя клиентами. _ Второе: использовать опрос из браузера на сервер nodejs ... мне это не нравится.

Итак, вот код: (часть кода моего сервера nodejs) Я использую экспресс для создания http-сервера:

app.get('/videoStream',function(req,response){   
    response.writeHead(200,{
        'Content-Type': 'multipart/x-mixed-replace;boundary="' + boundary + '"',
        'Connection': 'keep-alive',
        'Expires': 'Fri, 01 Jan 1990 00:00:00 GMT',
        'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
        'Pragma': 'no-cache'
    });
    response.write('--'+boundary+'\n');

    events.addListener('imagen_recibida',function(){
        fs.readFile(__dirname + '/image.jpeg',function(err,data){
             if(err) return send404(response);
             response.write('Content-Type: image/jpeg\n Content-Length: '+data.length+'\n\n');
             response.write(data);
            response.write('\n--'+boundary+'\n');
           });
    });

Когда возникает событие «imagen_recibida», оно считывает изображение с диска и записывает данные в браузер.

Итак, два вопроса:

Есть ли какой-нибудь подход к улучшению производительности этого? (записать изображение на диск и затем прочитать, чтобы отправить в браузер, не похоже на хороший трюк)

Есть ли способ кодировать это в другой формат для повышения производительности?

Большое спасибо.

PD: изображение записывается на диск и затем читается для отправки в браузер, потому что я получаю данные изображения из другого процесса в другой функции через вызовы RPC.

1 Ответ

3 голосов
/ 16 июня 2011

Вы можете попытаться с помощью socket.io просто нажать URL-адреса сгенерированных файлов, а затем на клиенте использовать Javascript для замены атрибута «src» тега img, показывающего фрейм. В этом случае вы можете использовать обычный веб-сервер для сервера статических файлов или модуль connect для обслуживания статических файлов. Это, вероятно, более эффективно, чем отправка данных в кодировке base64.

Если вы собираетесь использовать описанный выше подход, по крайней мере, не используйте fs.readFile ... это каждый раз помещает весь файл в память. Используйте util.pump () или вручную используйте ReadStream / WriteStream с «сливными» событиями, чтобы минимизировать использование памяти. Возможно, проблемы с производительностью связаны с сборкой мусора при подключении нескольких клиентов.

Другим подходом может быть фоновый процесс, который подает изображения в ffmpeg для кодирования правильного видеопотока, а затем в ffserver для его потоковой передачи на видеопроигрыватель.

...