Mod simplifies the setup of Restreamer-to-Restreamer connections
This commit is contained in:
parent
c008fb1eef
commit
7e331d5f82
@ -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)
|
||||
|
||||
@ -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',
|
||||
};
|
||||
|
||||
@ -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>
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user