diff --git a/src/misc/coders/Encoders/video/VP9.js b/src/misc/coders/Encoders/video/VP9.js
index 0a2e4e9..cca572b 100644
--- a/src/misc/coders/Encoders/video/VP9.js
+++ b/src/misc/coders/Encoders/video/VP9.js
@@ -27,6 +27,8 @@ function createMapping(settings) {
`${settings.bitrate}k`,
'-r',
`${settings.fps}`,
+ '-sc_threshold',
+ '0',
'-pix_fmt',
'yuv420p',
'-vsync',
@@ -34,7 +36,12 @@ function createMapping(settings) {
];
if (settings.gop !== 'auto') {
- local.push('-g', `${Math.round(parseInt(settings.fps) * parseInt(settings.gop)).toFixed(0)}`);
+ local.push(
+ '-g',
+ `${Math.round(parseInt(settings.fps) * parseInt(settings.gop)).toFixed(0)}`,
+ '-keyint_min',
+ `${Math.round(parseInt(settings.fps) * parseInt(settings.gop)).toFixed(0)}`
+ );
}
const mapping = {
diff --git a/src/misc/coders/Encoders/video/X264.js b/src/misc/coders/Encoders/video/X264.js
index ad3bbd5..c02ad90 100644
--- a/src/misc/coders/Encoders/video/X264.js
+++ b/src/misc/coders/Encoders/video/X264.js
@@ -36,6 +36,8 @@ function createMapping(settings) {
`${settings.bitrate}k`,
'-r',
`${settings.fps}`,
+ '-sc_threshold',
+ '0',
'-pix_fmt',
'yuv420p',
'-vsync',
@@ -43,7 +45,12 @@ function createMapping(settings) {
];
if (settings.gop !== 'auto') {
- local.push('-g', `${Math.round(parseInt(settings.fps) * parseInt(settings.gop)).toFixed(0)}`);
+ local.push(
+ '-g',
+ `${Math.round(parseInt(settings.fps) * parseInt(settings.gop)).toFixed(0)}`,
+ '-keyint_min',
+ `${Math.round(parseInt(settings.fps) * parseInt(settings.gop)).toFixed(0)}`
+ );
}
if (settings.profile !== 'auto') {
diff --git a/src/misc/coders/Encoders/video/X265.js b/src/misc/coders/Encoders/video/X265.js
index 019cc6e..c41345e 100644
--- a/src/misc/coders/Encoders/video/X265.js
+++ b/src/misc/coders/Encoders/video/X265.js
@@ -36,6 +36,8 @@ function createMapping(settings) {
`${settings.bitrate}k`,
'-r',
`${settings.fps}`,
+ '-sc_threshold',
+ '0',
'-pix_fmt',
'yuv420p',
'-vsync',
@@ -43,7 +45,12 @@ function createMapping(settings) {
];
if (settings.gop !== 'auto') {
- local.push('-g', `${Math.round(parseInt(settings.fps) * parseInt(settings.gop)).toFixed(0)}`);
+ local.push(
+ '-g',
+ `${Math.round(parseInt(settings.fps) * parseInt(settings.gop)).toFixed(0)}`,
+ '-keyint_min',
+ `${Math.round(parseInt(settings.fps) * parseInt(settings.gop)).toFixed(0)}`
+ );
}
if (settings.profile !== 'auto') {
diff --git a/src/utils/restreamer.js b/src/utils/restreamer.js
index 9b245ba..886a6e5 100644
--- a/src/utils/restreamer.js
+++ b/src/utils/restreamer.js
@@ -1547,48 +1547,47 @@ class Restreamer {
});
}
- // set hls storage endpoint
+ // Set hls storage endpoint
let hlsStore = 'memfs';
const output = {
id: 'output_0',
- address: `{` + hlsStore + `}/${channel.channelid}.m3u8`,
+ address: `{${hlsStore}}/${channel.channelid}.m3u8`,
options: ['-dn', '-sn', ...outputs[0].options.map((o) => '' + o)],
cleanup: [
{
- pattern: control.hls.version >= 7 ? hlsStore + `:/${channel.channelid}_*.mp4` : hlsStore + `:/${channel.channelid}_*.ts`,
+ pattern: `${hlsStore}:/${channel.channelid}_*.` + (control.hls.version >= 7 ? 'mp4' : 'ts'),
max_files: parseInt(control.hls.listSize) + 6,
max_file_age_seconds: control.hls.cleanup ? parseInt(control.hls.segmentDuration) * (parseInt(control.hls.listSize) + 6) : 0,
purge_on_delete: true,
},
{
- pattern: hlsStore + `:/${channel.channelid}.m3u8`,
+ pattern: `${hlsStore}:/${channel.channelid}.m3u8`,
max_file_age_seconds: control.hls.cleanup ? parseInt(control.hls.segmentDuration) * (parseInt(control.hls.listSize) + 6) : 0,
purge_on_delete: true,
},
],
};
- const metadata = this.GetHTTPAddresses()[0] + '/' + channel.channelid + '/oembed.json';
-
+ // Injects a metadata link as title
+ const metadata = `${this.GetHTTPAddresses()[0]}/${channel.channelid}/oembed.json`;
const metadata_options = ['-metadata', `title=${metadata}`, '-metadata', 'service_provider=datarhei-Restreamer'];
-
output.options.push(...metadata_options);
- // fetch core config
+ // Fetch core config
const core_config = this.ConfigActive();
- // fetch rtmp settings
+ // Fetch rtmp settings
const rtmp_config = core_config.source.network.rtmp;
let rtmp_enabled = false;
if (control.rtmp && control.rtmp.enable && rtmp_config.enabled) {
rtmp_enabled = true;
}
- // fetch srt settings
+ // Fetch srt settings
const srt_config = core_config.source.network.srt;
let srt_enabled = false;
- if (control.srt && control.srt.enable && srt_config.enabled) {
+ if (control.srt.enable && srt_config.enabled) {
srt_enabled = true;
}
@@ -1636,10 +1635,7 @@ class Restreamer {
['hls_list_size', '' + parseInt(control.hls.listSize)],
['hls_flags', 'append_list+delete_segments+program_date_time+independent_segments'],
['hls_delete_threshold', '4'],
- [
- 'hls_segment_filename',
- tee_muxer ? `{` + hlsStore + `^:}/${channel.channelid}_%04d.ts` : `{` + hlsStore + `}/${channel.channelid}_%04d.ts`,
- ],
+ ['hls_segment_filename', `{${hlsStore}` + (tee_muxer ? '^:' : '') + `}/${channel.channelid}_%04d.ts`],
['method', 'PUT'],
];
case 7:
@@ -1649,7 +1645,7 @@ class Restreamer {
}
// mp4 manifest cleanup
output.cleanup.push({
- pattern: hlsStore + `:/${channel.channelid}.mp4`,
+ pattern: `${hlsStore}:/${channel.channelid}.mp4`,
max_file_age_seconds: control.hls.cleanup ? parseInt(control.hls.segmentDuration) * (parseInt(control.hls.listSize) + 6) : 0,
purge_on_delete: true,
});
@@ -1662,10 +1658,7 @@ class Restreamer {
['hls_delete_threshold', '4'],
['hls_segment_type', 'fmp4'],
['hls_fmp4_init_filename', `${channel.channelid}.mp4`],
- [
- 'hls_segment_filename',
- tee_muxer ? `{` + hlsStore + `^:}/${channel.channelid}_%04d.mp4` : `{` + hlsStore + `}/${channel.channelid}_%04d.mp4`,
- ],
+ ['hls_segment_filename', `{${hlsStore}` + (tee_muxer ? '^:' : '') + `}/${channel.channelid}_%04d.mp4`],
['method', 'PUT'],
];
// case 3
@@ -1677,10 +1670,7 @@ class Restreamer {
['hls_list_size', '' + parseInt(control.hls.listSize)],
['hls_flags', 'append_list+delete_segments+program_date_time'],
['hls_delete_threshold', '4'],
- [
- 'hls_segment_filename',
- tee_muxer ? `{` + hlsStore + `^:}/${channel.channelid}_%04d.ts` : `{` + hlsStore + `}/${channel.channelid}_%04d.ts`,
- ],
+ ['hls_segment_filename', `{${hlsStore}` + (tee_muxer ? '^:' : '') + `}/${channel.channelid}_%04d.ts`],
['method', 'PUT'],
];
}
@@ -1688,7 +1678,7 @@ class Restreamer {
};
const hls_params_raw = getHLSParams(control.hls.lhls, control.hls.version);
- // push -y
+ // Overwrite output files
proc.options.push('-y');
// Returns the l/hls parameters with or without tee_muxer
@@ -1706,11 +1696,7 @@ class Restreamer {
// ['f=hls:start_number=0...]address.m3u8
// use tee_muxer formatting
output.address =
- `[` +
- hls_params +
- `]{` +
- hlsStore +
- `}/${channel.channelid}.m3u8` +
+ `[${hls_params}]{${hlsStore}}/${channel.channelid}.m3u8` +
(rtmp_enabled ? `|[f=flv]{rtmp,name=${channel.channelid}.stream}` : '') +
(srt_enabled ? `|[f=mpegts]{srt,name=${channel.channelid},mode=publish}` : '');
} else {
@@ -1752,7 +1738,7 @@ class Restreamer {
input: [
{
id: 'input_0',
- address: `{` + hlsStore + `}/${channel.channelid}.m3u8`,
+ address: `{${hlsStore}}/${channel.channelid}.m3u8`,
options: [],
},
],
diff --git a/src/views/Edit/Wizard/Sources/Network.js b/src/views/Edit/Wizard/Sources/Network.js
index 9d3cfc6..f63e359 100644
--- a/src/views/Edit/Wizard/Sources/Network.js
+++ b/src/views/Edit/Wizard/Sources/Network.js
@@ -78,14 +78,13 @@ function Source(props) {
)}
- Username} value={settings.username} onChange={update('', 'username')} />
+ Username} value={settings.username} onChange={update('', 'username')} disabled={protocol === 'srt'} />
Username for the device.
-
- Password} value={settings.password} onChange={update('', 'password')} />
+ Password} value={settings.password} onChange={update('', 'password')} disabled={protocol === 'srt'} />
Password for the device.