Skip to content

Commit

Permalink
rebroadcast: Fix up output arguments handling and rtsp rebroadcast
Browse files Browse the repository at this point in the history
  • Loading branch information
koush committed Aug 27, 2023
1 parent 7ecee42 commit 1c2a9d7
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 48 deletions.
4 changes: 2 additions & 2 deletions plugins/prebuffer-mixin/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plugins/prebuffer-mixin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@scrypted/prebuffer-mixin",
"version": "0.9.97",
"version": "0.9.99",
"description": "Video Stream Rebroadcast, Prebuffer, and Management Plugin for Scrypted.",
"author": "Scrypted",
"license": "Apache-2.0",
Expand Down
86 changes: 41 additions & 45 deletions plugins/prebuffer-mixin/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class PrebufferSession {
}

get canPrebuffer() {
return this.advertisedMediaStreamOptions.container !== 'rawvideo' && this.advertisedMediaStreamOptions.container !== 'ffmpeg';
return (this.advertisedMediaStreamOptions.container !== 'rawvideo' && this.advertisedMediaStreamOptions.container !== 'ffmpeg') || this.storage.getItem(this.ffmpegOutputArgumentsKey);
}

getLastH264Probe(): H264Info {
Expand Down Expand Up @@ -288,7 +288,7 @@ class PrebufferSession {
key: this.ffmpegOutputArgumentsKey,
value: this.storage.getItem(this.ffmpegOutputArgumentsKey),
choices: [
'-vcodec h264 -bf 0'
'-c:v libx264 -pix_fmt yuvj420p -preset ultrafast -bf 0'
],
combobox: true,
},
Expand Down Expand Up @@ -443,39 +443,6 @@ class PrebufferSession {
detectedAudioCodec = null;

this.audioDisabled = false;
let acodec: string[];

if (audioSoftMuted) {
// no audio? explicitly disable it.
acodec = ['-an'];
this.audioDisabled = true;
}
else {
acodec = [
'-acodec',
'copy',
];
}

const vcodec = [
'-vcodec', 'copy',
// 3/6/2022
// Add SPS/PPS to all keyframes. Not all cameras do this!
// This isn't really necessary for a few reasons:
// MPEG-TS and MP4 will automatically do this, since there's no out of band
// way to get the SPS/PPS.
// RTSP mode may send the SPS/PPS out of band via the sdp, and then may not have
// SPS/PPS in the bit stream.
// Adding this argument isn't strictly necessary, but it normalizes the bitstream
// so consumers that expect the SPS/PPS will have it. Ran into an issue where
// the HomeKit plugin was blasting RTP packets out from RTSP mode,
// but the bitstream had no SPS/PPS information, resulting in the video never loading
// in the Home app.
// 3/7/2022
// I believe this is causing errors in recordings and possibly streaming as well
// for some users. This may need to be a homekit specific transcoding argument.
// '-bsf:v', 'dump_extra',
];

const rbo: ParserOptions<PrebufferParsers> = {
console: this.console,
Expand All @@ -485,15 +452,6 @@ class PrebufferSession {
};
this.parsers = rbo.parsers;


const parser = createRtspParser({
vcodec,
// the rtsp parser should always stream copy unless audio is soft muted.
acodec: audioSoftMuted ? acodec : ['-acodec', 'copy'],
});
this.sdp = parser.sdp;
rbo.parsers.rtsp = parser;

const mo = await this.mixinDevice.getVideoStream(mso);
const isRfc4571 = mo.mimeType === 'x-scrypted/x-rfc4571';

Expand Down Expand Up @@ -537,6 +495,9 @@ class PrebufferSession {
}

if (this.usingScryptedParser) {
const rtspParser = createRtspParser();
rbo.parsers.rtsp = rtspParser;

session = await startRtspSession(this.console, ffmpegInput.url, ffmpegInput.mediaStreamOptions, {
useUdp: parser === SCRYPTED_PARSER_UDP,
audioSoftMuted,
Expand All @@ -545,6 +506,26 @@ class PrebufferSession {
this.sdp = session.sdp.then(buffers => Buffer.concat(buffers).toString());
}
else {
let acodec: string[];

if (audioSoftMuted) {
// no audio? explicitly disable it.
acodec = ['-an'];
this.audioDisabled = true;
}
else {
acodec = [
'-acodec',
'copy',
];
}

let vcodec = [
'-vcodec', 'copy',
];

acodec = audioSoftMuted ? acodec : ['-acodec', 'copy'];

if (parser === FFMPEG_PARSER_UDP)
ffmpegInput.inputArguments = ['-rtsp_transport', 'udp', '-i', ffmpegInput.url];
else if (parser === FFMPEG_PARSER_TCP)
Expand All @@ -553,7 +534,22 @@ class PrebufferSession {
const extraInputArguments = this.storage.getItem(this.ffmpegInputArgumentsKey) || DEFAULT_FFMPEG_INPUT_ARGUMENTS;
const extraOutputArguments = this.storage.getItem(this.ffmpegOutputArgumentsKey) || '';
ffmpegInput.inputArguments.unshift(...extraInputArguments.split(' '));
rbo.parsers.rtsp.outputArguments.push(...extraOutputArguments.split(' ').filter(d => !!d));

// extraOutputArguments must contain full codec information
if (extraOutputArguments) {
vcodec = [...extraOutputArguments.split(' ').filter(d => !!d)];
}
if (ffmpegInput.h264FilterArguments)
vcodec.push(...ffmpegInput.h264FilterArguments)

const rtspParser = createRtspParser({
vcodec,
// the rtsp parser should always stream copy unless audio is soft muted.
acodec,
});
this.sdp = rtspParser.sdp;
rbo.parsers.rtsp = rtspParser;

session = await startParserSession(ffmpegInput, rbo);
}
}
Expand Down

0 comments on commit 1c2a9d7

Please sign in to comment.