Как стримить в NestJS если данные передаются через броккер NATS?

Всем привет.
Имею стример с rtsp на mpegts (ffmpeg обернутый Express для публикаций), который передает путем bublish в NATS Jetstream.

const  options =
    [
        "-rtsp_transport", "tcp",
        "-i", streamUrl,
        '-f', 'mpegts',
        '-pix_fmt',  'yuv420p',
        '-c:v', 'h264',
        '-b:v', '800k',
        '-r', '30',
        '-muxdelay', '0.4',
        '-movflags', 'frag_keyframe+empty_moov',
        '-'
    ];
try {
        const natsConnection = await nats.connect({
            servers: 'ws://127.0.0.1:9222',
            preserveBuffers: true
        })

        const stream = spawn('ffmpeg', options);

        stream.stdout.on('data', (chunk) => {
            console.log(chunk);
            natsConnection.publish('stream.1', chunk);
        });

        stream.stdout.on('error', (error) => {
            console.error('FFmpeg error:', error);
        });

        stream.stdout.on('close', (code) => {
            console.log('FFmpeg process closed with code:', code);
        });
    } catch (e) {
        console.error(e);
    }


Пописывается на это все дело приложения NestJS когда посетитель переходит по роуту.
Сам метод контроллера
@Get()
  async findOne(
    @Headers() headers,
    @Res() res,
  ) {
    const streamObservable = this.natsService.subscribeStreamEvents('1');

    // Set appropriate headers for video streaming
    res.setHeader('Content-Type', 'video/mp4');
    res.setHeader('Transfer-Encoding', 'chunked');

    res.status(200);

    // Write data chunks directly to the response
    const subscription = streamObservable.subscribe({
      next: (chunk) => {
        console.log('wwwww', chunk);
        res.write(chunk);
      },
      error: (error) => {
        console.error('Error streaming video:', error);
      },
      complete: () => {
        res.end();
      },
    });

    res.on('close', () => {
      subscription.unsubscribe();
    });
  }


Ну и собсно сервис
subscribeToCameraEvents(cameraId: string) {
    const subject = new Subject<any>();

    this.natsConnection.subscribe(`stream.${cameraId}`, {
      callback: (err, msg: Msg) => {
        if (err) {
          subject.error(err);
          return;
        }
        // console.log(msg.data);
        subject.next(msg.data);
      },
    });

    return subject.asObservable();
  }


Данные консолятся как Буффер.

пытаюсь воспроизвести поток
<!DOCTYPE html>
<html>
<head>
    <title>Video Streaming Example</title>
</head>
<body>
<video controls width="640" height="480" style="background: black">
    <source src="http://localhost:3301/api/streams" type="video/mp4">
    Your browser does not support the video tag.
</video>
</body>
</html>


роут верный в сурсе.

Проблема заключается в том, что через VLC и ffplay - localhost:3301/api/streams стрим отображается, и все работает прекрасно, без каких либо доп настроек.

А вот в html не хочет.

Что я делаю не так? Буду рад любым коментариям и доп вопросам.
  • Вопрос задан
  • 210 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы