From e217b315c23caffe620f2f1a2dca2cebbbf37a4c Mon Sep 17 00:00:00 2001 From: Koushik Dutta Date: Wed, 2 Mar 2022 10:33:33 -0800 Subject: [PATCH] rebroadcast: fix bug where packet length was parsed as signed integer. --- common/src/rtsp-server.ts | 8 +++++++- common/src/sdp-utils.ts | 19 +++++++++++++++++++ plugins/prebuffer-mixin/package-lock.json | 4 ++-- plugins/prebuffer-mixin/package.json | 2 +- plugins/prebuffer-mixin/src/main.ts | 8 +++++--- plugins/prebuffer-mixin/src/rfc4571.ts | 4 ++-- 6 files changed, 36 insertions(+), 9 deletions(-) diff --git a/common/src/rtsp-server.ts b/common/src/rtsp-server.ts index 5801a80a5..79722bf49 100644 --- a/common/src/rtsp-server.ts +++ b/common/src/rtsp-server.ts @@ -109,7 +109,13 @@ export class RtspClient extends RtspBase { async request(method: string, headers?: Headers, path?: string, body?: Buffer) { headers = headers || {}; - const line = `${method} ${this.url}${path || ''} RTSP/1.0`; + let fullUrl: string; + if (path) + fullUrl = new URL(path, this.url).toString(); + else + fullUrl = this.url; + + const line = `${method} ${fullUrl} RTSP/1.0`; headers['CSeq'] = (this.cseq++).toString(); this.write(line, headers, body); diff --git a/common/src/sdp-utils.ts b/common/src/sdp-utils.ts index 2c5af111b..84c036cbc 100644 --- a/common/src/sdp-utils.ts +++ b/common/src/sdp-utils.ts @@ -15,3 +15,22 @@ export function parsePayloadTypes(sdp: string) { videoPayloadTypes, } } + +function getTrackId(track: string) { + if (!track) + return; + const lines = track.split('\n').map(line => line.trim()); + const control = lines.find(line => line.startsWith('a=control:')); + return control?.split('a=control:')?.[1]; +} + +export function parseTrackIds(sdp: string) { + const tracks = sdp.split('m='); + + const audioTrack = tracks.find(track => track.startsWith('audio')); + const videoTrack = tracks.find(track => track.startsWith('video')); + return { + audio: getTrackId(audioTrack), + video: getTrackId(videoTrack), + }; +} diff --git a/plugins/prebuffer-mixin/package-lock.json b/plugins/prebuffer-mixin/package-lock.json index d0b098596..19a799470 100644 --- a/plugins/prebuffer-mixin/package-lock.json +++ b/plugins/prebuffer-mixin/package-lock.json @@ -1,12 +1,12 @@ { "name": "@scrypted/prebuffer-mixin", - "version": "0.1.170", + "version": "0.1.171", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@scrypted/prebuffer-mixin", - "version": "0.1.170", + "version": "0.1.171", "license": "Apache-2.0", "dependencies": { "@scrypted/common": "file:../../common", diff --git a/plugins/prebuffer-mixin/package.json b/plugins/prebuffer-mixin/package.json index 7d1f559d3..13c81739c 100644 --- a/plugins/prebuffer-mixin/package.json +++ b/plugins/prebuffer-mixin/package.json @@ -1,6 +1,6 @@ { "name": "@scrypted/prebuffer-mixin", - "version": "0.1.170", + "version": "0.1.171", "description": "Rebroadcast and Prebuffer for VideoCameras.", "author": "Scrypted", "license": "Apache-2.0", diff --git a/plugins/prebuffer-mixin/src/main.ts b/plugins/prebuffer-mixin/src/main.ts index 0ac97c289..db73c50b0 100644 --- a/plugins/prebuffer-mixin/src/main.ts +++ b/plugins/prebuffer-mixin/src/main.ts @@ -7,7 +7,7 @@ import { handleRebroadcasterClient, ParserOptions, ParserSession, startParserSes import { createMpegTsParser, createFragmentedMp4Parser, StreamChunk, StreamParser } from '@scrypted/common/src/stream-parser'; import { AutoenableMixinProvider } from '@scrypted/common/src/autoenable-mixin-provider'; import { listenZeroSingleClient } from '@scrypted/common/src/listen-cluster'; -import { parsePayloadTypes } from '@scrypted/common/src/sdp-utils'; +import { parsePayloadTypes, parseTrackIds } from '@scrypted/common/src/sdp-utils'; import { createRtspParser, RtspClient, RtspServer } from '@scrypted/common/src/rtsp-server'; import { Duplex } from 'stream'; import net from 'net'; @@ -446,8 +446,10 @@ class PrebufferSession { const sdpResponse = await rtspClient.describe(); const sdp = sdpResponse.body.toString().trim(); this.sdp = Promise.resolve(sdp); - await rtspClient.setup(0, '/audio'); - await rtspClient.setup(2, '/video'); + const { audio, video } = parseTrackIds(sdp); + // handle no audio? + await rtspClient.setup(0, audio); + await rtspClient.setup(2, video); const socket = await rtspClient.play(); session = await startRFC4571Parser(socket, sdp, ffmpegInput.mediaStreamOptions, true, rbo); } diff --git a/plugins/prebuffer-mixin/src/rfc4571.ts b/plugins/prebuffer-mixin/src/rfc4571.ts index 3f502c0da..f33020d6a 100644 --- a/plugins/prebuffer-mixin/src/rfc4571.ts +++ b/plugins/prebuffer-mixin/src/rfc4571.ts @@ -70,11 +70,11 @@ export async function startRFC4571Parser(socket: net.Socket, sdp: string, mediaS let length: number; if (hasRstpPrefix) { header = await readLength(socket, 4); - length = header.readInt16BE(2); + length = header.readUInt16BE(2); } else { header = await readLength(socket, 2); - length = header.readInt16BE(0); + length = header.readUInt16BE(0); } const data = await readLength(socket, length);