rebroadcast: scrypted rtsp parser needs timeout.

This commit is contained in:
Koushik Dutta
2022-03-14 16:51:34 -07:00
parent a7675ab62b
commit 49ec71e3f8
4 changed files with 33 additions and 24 deletions

View File

@@ -8,6 +8,7 @@ import net from 'net';
import tls from 'tls';
import { DIGEST } from 'http-auth-utils/dist/index';
import crypto from 'crypto';
import { timeoutPromise } from './promise-utils';
export const RTSP_FRAME_MAGIC = 36;
@@ -138,6 +139,7 @@ export class RtspClient extends RtspBase {
cseq = 0;
session: string;
authorization: string;
requestTimeout: number;
constructor(public url: string, console?: Console) {
super(console);
@@ -190,7 +192,7 @@ export class RtspClient extends RtspBase {
}> {
this.writeRequest(method, headers, path, body);
const message = await this.readMessage();
const message = this.requestTimeout ? await timeoutPromise(this.requestTimeout, this.readMessage()) : await this.readMessage();
const status = message[0];
const response = parseHeaders(message);
if (!status.includes('200') && !response['www-authenticate'])

View File

@@ -1,12 +1,12 @@
{
"name": "@scrypted/prebuffer-mixin",
"version": "0.1.200",
"version": "0.1.201",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@scrypted/prebuffer-mixin",
"version": "0.1.200",
"version": "0.1.201",
"license": "Apache-2.0",
"dependencies": {
"@scrypted/common": "file:../../common",

View File

@@ -1,6 +1,6 @@
{
"name": "@scrypted/prebuffer-mixin",
"version": "0.1.200",
"version": "0.1.201",
"description": "Rebroadcast and Prebuffer for VideoCameras.",
"author": "Scrypted",
"license": "Apache-2.0",

View File

@@ -570,28 +570,35 @@ class PrebufferSession {
const parser = this.getParser(rtspMode, muxingMp4, ffmpegInput.mediaStreamOptions);
if (parser === SCRYPTED_PARSER) {
usingScryptedParser = true;
this.console.log('bypassing ffmpeg: using scrypted rtsp/rfc4571 parser')
this.console.log('bypassing ffmpeg: using scrypted rtsp/rfc4571 parser');
const rtspClient = new RtspClient(ffmpegInput.url, this.console);
await rtspClient.options();
const sdpResponse = await rtspClient.describe();
const sdp = sdpResponse.body.toString().trim();
this.console.log('sdp', sdp);
this.sdp = Promise.resolve(sdp);
const { audio, video } = parseTrackIds(sdp);
let channel = 0;
if (!audioSoftMuted) {
await rtspClient.setup(channel, audio);
channel += 2;
try {
rtspClient.requestTimeout = 10000;
await rtspClient.options();
const sdpResponse = await rtspClient.describe();
const sdp = sdpResponse.body.toString().trim();
this.console.log('sdp', sdp);
this.sdp = Promise.resolve(sdp);
const { audio, video } = parseTrackIds(sdp);
let channel = 0;
if (!audioSoftMuted) {
await rtspClient.setup(channel, audio);
channel += 2;
}
await rtspClient.setup(channel, video);
const socket = await rtspClient.play();
session = await startRFC4571Parser(this.console, socket, sdp, ffmpegInput.mediaStreamOptions, true, rbo);
const sessionKill = session.kill.bind(session);
session.kill = async () => {
// issue a teardown to upstream to close gracefully but don't rely on it responding.
rtspClient.teardown().finally(sessionKill);
await sleep(500);
sessionKill();
}
}
await rtspClient.setup(channel, video);
const socket = await rtspClient.play();
session = await startRFC4571Parser(this.console, socket, sdp, ffmpegInput.mediaStreamOptions, true, rbo);
const sessionKill = session.kill.bind(session);
session.kill = async () => {
// issue a teardown to upstream to close gracefully but don't rely on it responding.
rtspClient.teardown().finally(sessionKill);
await sleep(500);
sessionKill();
catch (e) {
rtspClient.client.destroy();
throw e;
}
}
else {