Mod simplifies the setup of Restreamer-to-Restreamer connections

This commit is contained in:
Jan Stabenow 2022-10-21 22:15:36 +02:00
parent c008fb1eef
commit 7e331d5f82
No known key found for this signature in database
GPG Key ID: 9C22DD65A9AAF133
3 changed files with 136 additions and 70 deletions

View File

@ -4,6 +4,7 @@
- Add scale filter to non-hwaccel encoders
- Add PeerTube and Media Network to publication services (plattforms, software)
- Mod simplifies the setup of Restreamer-to-Restreamer connections
- Add reset button to hide a player logo (datarhei/restreamer#431)
- Mod adds Istafeed.me as StreamKey service to Instagram's publishing service
- Mod renames "Low delay" to "Low latency (buffer)" and set false as default (requires more feedback)

View File

@ -47,8 +47,8 @@ export default function Component(props) {
return (
<Stack
direction="column"
justifyContent="center"
alignItems="center"
justifyContent={props.justifyContent}
alignItems={props.alignItems}
textAlign={props.textAlign}
spacing={1}
className={
@ -64,4 +64,6 @@ export default function Component(props) {
Component.defaultProps = {
color: 'light',
textAlign: 'left',
alignItems: 'center',
justifyContent: 'center',
};

View File

@ -1,18 +1,18 @@
import React from 'react';
import { Trans } from '@lingui/macro';
import urlparser from 'url-parse';
import Grid from '@mui/material/Grid';
import Link from '@mui/material/Link';
import MenuItem from '@mui/material/MenuItem';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import FormInlineButton from '../../../misc/FormInlineButton';
import Logo from './logos/datarhei.svg';
import Select from '../../../misc/Select';
import BoxText from '../../../misc/BoxText';
const id = 'datarheicore';
const name = 'datarhei Core';
const version = '1.0';
const version = '2.0';
const stream_key_link_rtmp = 'https://docs.datarhei.com/restreamer/knowledge-base/manual/system-settings/rtmp';
const stream_key_link_srt = 'https://docs.datarhei.com/restreamer/knowledge-base/manual/system-settings/srt';
const description = (
@ -50,13 +50,42 @@ function ServiceIcon(props) {
}
function init(settings) {
// v1.0 > v2.0
if (settings.base_url && !settings.v2_protocol) {
if (settings.base_url.length !== 0) {
settings.v2_protocol = settings.protocol;
settings.v2_host = settings.base_url;
if (settings.protocol === 'srt') {
settings.v2_address =
`srt://${settings.base_url}?mode=caller&transtype=live&streamid=#!:m=publish,r=${settings.stream_name}` +
(settings.token.length !== 0 ? `,token=${settings.token}` : '') +
(settings.srt_passphrase.length !== 0 ? `&passphrase=${settings.srt_passphrase}` : '');
settings.v2_stream_id = `#!:m=publish,r=${settings.stream_name}` + (settings.token.length !== 0 ? `,token=${settings.token}` : '');
settings.v2_passphrase = settings.srt_passphrase;
} else {
settings.v2_address =
`${settings.protocol}://${settings.base_url}/` +
(settings.app_path.length !== 0 ? `${settings.app_path}/` : '') +
settings.stream_name +
(settings.token.length !== 0 ? `?token=${settings.token}` : '');
settings.v2_stream_id = `/` + (settings.app_path.length !== 0 ? `${settings.app_path}/` : '') + settings.stream_name;
settings.v2_token = settings.token;
}
}
settings.base_url = '';
settings.app_path = '';
settings.stream_name = '';
settings.token = '';
settings.srt_passphrase = '';
}
const initSettings = {
protocol: 'rtmp',
base_url: '',
app_path: 'live',
stream_name: '',
token: '',
srt_passphrase: '',
v2_address: '',
v2_protocol: '',
v2_host: '',
v2_stream_id: '',
v2_token: '',
v2_passphrase: '',
...settings,
};
@ -71,6 +100,45 @@ function Service(props) {
settings[what] = value;
const url = urlparser(value);
if (url.protocol === 'rtmp:' || url.protocol === 'rtmps:' || url.protocol === 'srt:') {
settings.v2_protocol = url.protocol.split(':')[0];
settings.v2_host = url.host;
if (url.protocol === 'srt:') {
if (url.hash) {
if (url.hash.includes('passphrase=')) {
settings.v2_stream_id = url.hash.split('&')[0];
settings.v2_passphrase = url.hash.split('&passphrase=')[1].split('&')[0];
} else {
settings.v2_stream_id = url.hash.split('&')[0];
settings.v2_passphrase = '';
}
} else {
settings.v2_stream_id = '';
settings.v2_passphrase = '';
}
} else {
settings.v2_stream_id = url.pathname;
if (url.query) {
if (url.query.includes('token=')) {
settings.v2_token = url.query.split('token=')[1].split('&')[0];
} else {
settings.v2_token = '';
}
} else {
settings.v2_token = '';
}
}
} else {
settings.v2_protocol = '';
settings.v2_host = '';
settings.v2_port = '';
settings.v2_streamid = '';
settings.v2_token = '';
settings.v2_passphrase = '';
}
const output = createOutput(settings);
props.onChange([output], settings);
@ -82,19 +150,11 @@ function Service(props) {
options: null,
};
if (settings.protocol !== 'srt') {
output.address =
`${settings.protocol}://${settings.base_url}/` +
(settings.app_path.length !== 0 ? `${settings.app_path}/` : '') +
settings.stream_name +
(settings.token.length !== 0 ? `?token=${settings.token}` : '');
output.options = ['-f', 'flv'];
} else {
output.address =
`srt://${settings.base_url}?mode=caller&transtype=live&streamid=#!:m=publish,r=${settings.stream_name}` +
(settings.token.length !== 0 ? `,token=${settings.token}` : '') +
(settings.srt_passphrase.length !== 0 ? `&passphrase=${settings.srt_passphrase}` : '');
output.address = settings.v2_address;
if (settings.v2_address.includes('srt://')) {
output.options = ['-bsf:v', 'dump_extra', '-f', 'mpegts'];
} else {
output.options = ['-f', 'flv'];
}
return output;
@ -102,57 +162,60 @@ function Service(props) {
return (
<Grid container spacing={2}>
<Grid item xs={12} md={3}>
<Select type="select" label={<Trans>Protocol</Trans>} value={settings.protocol} onChange={handleChange('protocol')}>
<MenuItem value="rtmp">rtmp://</MenuItem>
<MenuItem value="rtmps">rtmps://</MenuItem>
<MenuItem value="srt">srt://</MenuItem>
</Select>
</Grid>
<Grid item xs={12} md={settings.protocol !== 'srt' ? 6 : 9}>
<Grid item xs={12}>
<TextField
variant="outlined"
fullWidth
label={<Trans>Address</Trans>}
placeholder="core-address:port"
value={settings.base_url}
onChange={handleChange('base_url')}
label={<Trans>Target address</Trans>}
value={settings.v2_address}
onChange={handleChange('v2_address')}
/>
</Grid>
{settings.protocol !== 'srt' && (
<Grid item xs={12} md={3}>
<TextField variant="outlined" fullWidth label={<Trans>App</Trans>} value={settings.app_path} onChange={handleChange('app_path')} />
</Grid>
)}
<Grid item xs={12} md={12}>
<TextField
variant="outlined"
fullWidth
label={<Trans>Stream name</Trans>}
value={settings.stream_name}
onChange={handleChange('stream_name')}
placeholder={'streamId'}
/>
</Grid>
<Grid item xs={12} md={settings.protocol !== 'srt' ? 9 : 4}>
<TextField variant="outlined" fullWidth label={<Trans>Security token</Trans>} value={settings.token} onChange={handleChange('token')} />
</Grid>
{settings.protocol === 'srt' && (
<Grid item xs={12} md={4}>
<TextField
variant="outlined"
fullWidth
label={<Trans>Security passphrase</Trans>}
value={settings.srt_passphrase}
onChange={handleChange('srt_passphrase')}
disabled={settings.protocol !== 'srt'}
/>
</Grid>
)}
<Grid item xs={12} md={settings.protocol !== 'srt' ? 3 : 4}>
<FormInlineButton target="blank" href={settings.protocol !== 'srt' ? stream_key_link_rtmp : stream_key_link_srt} component="a">
<Trans>GET</Trans>
</FormInlineButton>
<Grid item xs={12} align="left">
<BoxText alignItems="left" justifyContent="left">
{!settings.v2_address && (
<Typography>
<strong>
<Trans>Restreamer instructions</Trans>:
</strong>
<br />
<Trans>1. Switch to the interface of the target Restreamer.</Trans>
<br />
<Trans>2. Create a new channel and select RTMP or SRT server.</Trans>
<br />
<Trans>3. Copy the URL and paste it in the "Target address" field.</Trans>
</Typography>
)}
{settings.v2_address && (
<Typography>
<strong>
<Trans>Protocol</Trans>:
</strong>{' '}
{settings.v2_protocol}
<br />
<strong>
<Trans>Address</Trans>:
</strong>{' '}
{settings.v2_host}
<br />
<strong>Stream ID:</strong> {settings.v2_stream_id}
<br />
{settings.v2_token && (
<React.Fragment>
<strong>Token:</strong> {settings.v2_token}
</React.Fragment>
)}
{settings.v2_passphrase && (
<React.Fragment>
<strong>
<Trans>Passphrase</Trans>:
</strong>{' '}
{settings.v2_passphrase}
</React.Fragment>
)}
</Typography>
)}
</BoxText>
</Grid>
</Grid>
);