Merge branch 'dev' of https://github.com/datarhei/restreamer-ui into dev
This commit is contained in:
commit
77dfcbe749
@ -155,7 +155,7 @@ function SourceIcon(props) {
|
||||
const id = 'alsa';
|
||||
const name = <Trans>ALSA</Trans>;
|
||||
const capabilities = ['audio'];
|
||||
const ffversion = '^4.1.0 || ^5.0.0';
|
||||
const ffversion = '^4.1.0 || ^5.0.0 || ^6.1.0';
|
||||
|
||||
const func = {
|
||||
initSettings,
|
||||
|
||||
@ -220,7 +220,7 @@ function SourceIcon(props) {
|
||||
const id = 'avfoundation';
|
||||
const name = <Trans>AVFoundation</Trans>;
|
||||
const capabilities = ['audio', 'video'];
|
||||
const ffversion = '^4.1.0 || ^5.0.0';
|
||||
const ffversion = '^4.1.0 || ^5.0.0 || ^6.1.0';
|
||||
|
||||
const func = {
|
||||
initSettings,
|
||||
|
||||
@ -193,7 +193,7 @@ function SourceIcon(props) {
|
||||
const id = 'audioloop';
|
||||
const name = <Trans>Loop</Trans>;
|
||||
const capabilities = ['audio'];
|
||||
const ffversion = '^4.1.0 || ^5.0.0';
|
||||
const ffversion = '^4.1.0 || ^5.0.0 || ^6.1.0';
|
||||
|
||||
const func = {
|
||||
initSettings,
|
||||
|
||||
@ -128,7 +128,7 @@ function SourceIcon(props) {
|
||||
const id = 'fbdev';
|
||||
const name = <Trans>Framebuffer</Trans>;
|
||||
const capabilities = ['video'];
|
||||
const ffversion = '^4.1.0 || ^5.0.0';
|
||||
const ffversion = '^4.1.0 || ^5.0.0 || ^6.1.0';
|
||||
|
||||
const func = {
|
||||
initSettings,
|
||||
|
||||
@ -178,13 +178,15 @@ const initSkills = (initialSkills) => {
|
||||
};
|
||||
|
||||
const createInputs = (settings, config, skills) => {
|
||||
settings = initSettings(settings);
|
||||
config = initConfig(config);
|
||||
settings = initSettings(settings, config);
|
||||
skills = initSkills(skills);
|
||||
|
||||
let ffmpeg_version = 4;
|
||||
let ffmpeg_version = 6;
|
||||
if (SemverSatisfies(skills.ffmpeg.version, '^5.0.0')) {
|
||||
ffmpeg_version = 5;
|
||||
} else if (SemverSatisfies(skills.ffmpeg.version, '^4.1.0')) {
|
||||
ffmpeg_version = 4;
|
||||
}
|
||||
|
||||
const input = {
|
||||
@ -1173,7 +1175,7 @@ function SourceIcon(props) {
|
||||
const id = 'network';
|
||||
const name = <Trans>Network source</Trans>;
|
||||
const capabilities = ['audio', 'video'];
|
||||
const ffversion = '^4.1.0 || ^5.0.0';
|
||||
const ffversion = '^4.1.0 || ^5.0.0 || ^6.1.0';
|
||||
|
||||
const func = {
|
||||
initSettings,
|
||||
|
||||
@ -4,6 +4,18 @@ import '@testing-library/jest-dom';
|
||||
|
||||
import * as Network from './Network';
|
||||
|
||||
const $skills_ffmpeg6 = {
|
||||
ffmpeg: {
|
||||
version: '6.1.1',
|
||||
},
|
||||
formats: {
|
||||
demuxers: ['rtsp'],
|
||||
},
|
||||
protocols: {
|
||||
input: ['http', 'https', 'rtmp', 'rtmps', 'srt'],
|
||||
},
|
||||
};
|
||||
|
||||
const $skills_ffmpeg5 = {
|
||||
ffmpeg: {
|
||||
version: '5.1.2',
|
||||
@ -29,6 +41,7 @@ const $skills_ffmpeg4 = {
|
||||
};
|
||||
|
||||
const $config = {
|
||||
channelid: 'external',
|
||||
rtmp: {
|
||||
enabled: true,
|
||||
app: '/live',
|
||||
@ -64,9 +77,17 @@ test('source:network pull', async () => {
|
||||
|
||||
expect(queryByText(`This protocol is unknown or not supported by the available FFmpeg binary.`)).toBeInTheDocument();
|
||||
|
||||
rerender(<Source settings={$settings} skills={$skills_ffmpeg4} onChange={handleChange} />);
|
||||
|
||||
expect(queryByText(`This protocol is unknown or not supported by the available FFmpeg binary.`)).toBe(null);
|
||||
|
||||
rerender(<Source settings={$settings} skills={$skills_ffmpeg5} onChange={handleChange} />);
|
||||
|
||||
expect(queryByText(`This protocol is unknown or not supported by the available FFmpeg binary.`)).toBe(null);
|
||||
|
||||
rerender(<Source settings={$settings} skills={$skills_ffmpeg6} onChange={handleChange} />);
|
||||
|
||||
expect(queryByText(`This protocol is unknown or not supported by the available FFmpeg binary.`)).toBe(null);
|
||||
});
|
||||
|
||||
const pullmatrix = {
|
||||
@ -205,6 +226,56 @@ pullmatrix.tests = [
|
||||
options: ['-fflags', '+genpts', '-thread_queue_size', 512],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'RTSP',
|
||||
settings: { ...pullmatrix.settings, address: 'rtsp://127.0.0.1/live/stream' },
|
||||
skills: $skills_ffmpeg6,
|
||||
input: {
|
||||
address: 'rtsp://admin:foobar@127.0.0.1/live/stream',
|
||||
options: ['-fflags', '+genpts', '-thread_queue_size', 512, '-timeout', 5000000, '-rtsp_transport', 'tcp'],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'RTMP',
|
||||
settings: { ...pullmatrix.settings, address: 'rtmp://127.0.0.1/live/stream' },
|
||||
skills: $skills_ffmpeg6,
|
||||
input: {
|
||||
address: 'rtmp://admin:foobar@127.0.0.1/live/stream',
|
||||
options: ['-fflags', '+genpts', '-thread_queue_size', 512, '-analyzeduration', 3000000],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'HTTP',
|
||||
settings: { ...pullmatrix.settings, address: 'http://127.0.0.1/live/stream.m3u8' },
|
||||
skills: $skills_ffmpeg6,
|
||||
input: {
|
||||
address: 'http://admin:foobar@127.0.0.1/live/stream.m3u8',
|
||||
options: [
|
||||
'-fflags',
|
||||
'+genpts',
|
||||
'-thread_queue_size',
|
||||
512,
|
||||
'-analyzeduration',
|
||||
20000000,
|
||||
'-re',
|
||||
'-r',
|
||||
25,
|
||||
'-user_agent',
|
||||
'foobaz/1',
|
||||
'-referer',
|
||||
'http://example.com',
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'SRT',
|
||||
settings: { ...pullmatrix.settings, address: 'srt://127.0.0.1?mode=caller&streamid=foobar' },
|
||||
skills: $skills_ffmpeg6,
|
||||
input: {
|
||||
address: 'srt://127.0.0.1?mode=caller&streamid=foobar',
|
||||
options: ['-fflags', '+genpts', '-thread_queue_size', 512],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
test.each(pullmatrix.tests)('source:network pull $name input with ffmpeg $skills.ffmpeg.version', async (data) => {
|
||||
@ -231,6 +302,7 @@ test('source:network push', async () => {
|
||||
mode: 'push',
|
||||
push: {
|
||||
type: 'rtmp',
|
||||
name: 'external',
|
||||
},
|
||||
};
|
||||
const handleChange = (settings) => {
|
||||
@ -244,9 +316,17 @@ test('source:network push', async () => {
|
||||
|
||||
expect(queryByText(`The available FFmpeg binary doesn't support any of the required protocols.`)).toBeInTheDocument();
|
||||
|
||||
rerender(<Source settings={$settings} skills={$skills_ffmpeg4} onChange={handleChange} />);
|
||||
|
||||
expect(queryByText(`The available FFmpeg binary doesn't support any of the required protocols.`)).toBe(null);
|
||||
|
||||
rerender(<Source settings={$settings} skills={$skills_ffmpeg5} onChange={handleChange} />);
|
||||
|
||||
expect(queryByText(`The available FFmpeg binary doesn't support any of the required protocols.`)).toBe(null);
|
||||
|
||||
rerender(<Source settings={$settings} skills={$skills_ffmpeg6} onChange={handleChange} />);
|
||||
|
||||
expect(queryByText(`The available FFmpeg binary doesn't support any of the required protocols.`)).toBe(null);
|
||||
});
|
||||
|
||||
test('source:network push RTMP', async () => {
|
||||
@ -254,6 +334,7 @@ test('source:network push RTMP', async () => {
|
||||
mode: 'push',
|
||||
push: {
|
||||
type: 'rtmp',
|
||||
name: 'external',
|
||||
},
|
||||
};
|
||||
const handleChange = (settings) => {
|
||||
@ -278,6 +359,7 @@ test('source:network push SRT', async () => {
|
||||
mode: 'push',
|
||||
push: {
|
||||
type: 'srt',
|
||||
name: 'external',
|
||||
},
|
||||
};
|
||||
const handleChange = (settings) => {
|
||||
@ -302,6 +384,7 @@ const pushmatrix = {
|
||||
mode: 'push',
|
||||
push: {
|
||||
type: '',
|
||||
name: 'external',
|
||||
},
|
||||
},
|
||||
tests: [],
|
||||
@ -348,6 +431,26 @@ pushmatrix.tests = [
|
||||
options: ['-fflags', '+genpts', '-thread_queue_size', 512],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'RTMP',
|
||||
settings: { ...pushmatrix.settings, push: { ...pushmatrix.push, type: 'rtmp' } },
|
||||
skills: $skills_ffmpeg6,
|
||||
config: $config,
|
||||
input: {
|
||||
address: '{rtmp,name=external.stream}',
|
||||
options: ['-fflags', '+genpts', '-thread_queue_size', 512, '-analyzeduration', 3000000],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'SRT',
|
||||
settings: { ...pushmatrix.settings, push: { ...pushmatrix.push, type: 'srt' } },
|
||||
skills: $skills_ffmpeg6,
|
||||
config: $config,
|
||||
input: {
|
||||
address: '{srt,name=external.stream,mode=request}',
|
||||
options: ['-fflags', '+genpts', '-thread_queue_size', 512],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
test.each(pushmatrix.tests)('source:network push $name input with ffmpeg $skills.ffmpeg.version', async (data) => {
|
||||
|
||||
@ -44,7 +44,7 @@ function SourceIcon(props) {
|
||||
const id = 'noaudio';
|
||||
const name = <Trans>No audio</Trans>;
|
||||
const capabilities = ['audio'];
|
||||
const ffversion = '^4.1.0 || ^5.0.0';
|
||||
const ffversion = '^4.1.0 || ^5.0.0 || ^6.1.0';
|
||||
|
||||
const func = {
|
||||
initSettings,
|
||||
|
||||
@ -143,7 +143,7 @@ function SourceIcon(props) {
|
||||
const id = 'raspicam';
|
||||
const name = <Trans>Raspberry Pi camera</Trans>;
|
||||
const capabilities = ['video'];
|
||||
const ffversion = '^4.1.0 || ^5.0.0';
|
||||
const ffversion = '^4.1.0 || ^5.0.0 || ^6.1.0';
|
||||
|
||||
const func = {
|
||||
initSettings,
|
||||
|
||||
@ -153,7 +153,7 @@ function SourceIcon(props) {
|
||||
const id = 'video4linux2';
|
||||
const name = <Trans>Hardware device</Trans>;
|
||||
const capabilities = ['video'];
|
||||
const ffversion = '^4.1.0 || ^5.0.0';
|
||||
const ffversion = '^4.1.0 || ^5.0.0 || ^6.1.0';
|
||||
|
||||
const func = {
|
||||
initSettings,
|
||||
|
||||
@ -44,7 +44,7 @@ function SourceIcon(props) {
|
||||
const id = 'videoaudio';
|
||||
const name = <Trans>Video source</Trans>;
|
||||
const capabilities = ['audio'];
|
||||
const ffversion = '^4.1.0 || ^5.0.0';
|
||||
const ffversion = '^4.1.0 || ^5.0.0 || ^6.1.0';
|
||||
|
||||
const func = {
|
||||
initSettings,
|
||||
|
||||
@ -201,7 +201,7 @@ function SourceIcon(props) {
|
||||
const id = 'videoloop';
|
||||
const name = <Trans>Loop</Trans>;
|
||||
const capabilities = ['video'];
|
||||
const ffversion = '^4.1.0 || ^5.0.0';
|
||||
const ffversion = '^4.1.0 || ^5.0.0 || ^6.1.0';
|
||||
|
||||
const func = {
|
||||
initSettings,
|
||||
|
||||
@ -186,7 +186,7 @@ function SourceIcon(props) {
|
||||
const id = 'virtualaudio';
|
||||
const name = <Trans>Virtual source</Trans>;
|
||||
const capabilities = ['audio'];
|
||||
const ffversion = '^4.1.0 || ^5.0.0';
|
||||
const ffversion = '^4.1.0 || ^5.0.0 || ^6.1.0';
|
||||
|
||||
const func = {
|
||||
initSettings,
|
||||
|
||||
@ -205,7 +205,7 @@ function SourceIcon(props) {
|
||||
const id = 'virtualvideo';
|
||||
const name = <Trans>Virtual source</Trans>;
|
||||
const capabilities = ['video'];
|
||||
const ffversion = '^4.1.0 || ^5.0.0';
|
||||
const ffversion = '^4.1.0 || ^5.0.0 || ^6.1.0';
|
||||
|
||||
const func = {
|
||||
initSettings,
|
||||
|
||||
@ -9,9 +9,9 @@ import * as S from '../../Sources/Network';
|
||||
import BoxTextarea from '../../../../misc/BoxTextarea';
|
||||
import Textarea from '../../../../misc/Textarea';
|
||||
|
||||
const initSettings = (initialSettings) => {
|
||||
const initSettings = (initialSettings, config) => {
|
||||
const settings = {
|
||||
...S.func.initSettings(initialSettings),
|
||||
...S.func.initSettings(initialSettings, config),
|
||||
mode: 'push',
|
||||
};
|
||||
|
||||
@ -21,8 +21,8 @@ const initSettings = (initialSettings) => {
|
||||
};
|
||||
|
||||
function Source(props) {
|
||||
const settings = initSettings(props.settings);
|
||||
const config = S.func.initConfig(props.config);
|
||||
const settings = initSettings(props.settings, config);
|
||||
const skills = S.func.initSkills(props.skills);
|
||||
|
||||
const handleChange = (newSettings) => {
|
||||
|
||||
@ -11,9 +11,9 @@ import * as S from '../../Sources/Network';
|
||||
import BoxTextarea from '../../../../misc/BoxTextarea';
|
||||
import Textarea from '../../../../misc/Textarea';
|
||||
|
||||
const initSettings = (initialSettings) => {
|
||||
const initSettings = (initialSettings, config) => {
|
||||
const settings = {
|
||||
...S.func.initSettings(initialSettings),
|
||||
...S.func.initSettings(initialSettings, config),
|
||||
mode: 'push',
|
||||
};
|
||||
|
||||
@ -24,8 +24,8 @@ const initSettings = (initialSettings) => {
|
||||
|
||||
function Source(props) {
|
||||
const navigate = useNavigate();
|
||||
const settings = initSettings(props.settings);
|
||||
const config = S.func.initConfig(props.config);
|
||||
const settings = initSettings(props.settings, config);
|
||||
const skills = S.func.initSkills(props.skills);
|
||||
|
||||
const handleChange = (newSettings) => {
|
||||
|
||||
@ -11,9 +11,9 @@ import * as S from '../../Sources/Network';
|
||||
import BoxTextarea from '../../../../misc/BoxTextarea';
|
||||
import Textarea from '../../../../misc/Textarea';
|
||||
|
||||
const initSettings = (initialSettings) => {
|
||||
const initSettings = (initialSettings, config) => {
|
||||
const settings = {
|
||||
...S.func.initSettings(initialSettings),
|
||||
...S.func.initSettings(initialSettings, config),
|
||||
mode: 'push',
|
||||
};
|
||||
|
||||
@ -24,8 +24,8 @@ const initSettings = (initialSettings) => {
|
||||
|
||||
function Source(props) {
|
||||
const navigate = useNavigate();
|
||||
const settings = initSettings(props.settings);
|
||||
const config = S.func.initConfig(props.config);
|
||||
const settings = initSettings(props.settings, config);
|
||||
const skills = S.func.initSkills(props.skills);
|
||||
|
||||
const handleChange = (newSettings) => {
|
||||
|
||||
@ -10,9 +10,9 @@ import * as S from '../../Sources/Network';
|
||||
import Checkbox from '../../../../misc/Checkbox';
|
||||
import Password from '../../../../misc/Password';
|
||||
|
||||
const initSettings = (initialSettings) => {
|
||||
const initSettings = (initialSettings, config) => {
|
||||
const settings = {
|
||||
...S.func.initSettings(initialSettings),
|
||||
...S.func.initSettings(initialSettings, config),
|
||||
mode: 'pull',
|
||||
};
|
||||
|
||||
@ -20,8 +20,8 @@ const initSettings = (initialSettings) => {
|
||||
};
|
||||
|
||||
function Source(props) {
|
||||
const settings = initSettings(props.settings);
|
||||
const config = S.func.initConfig(props.config);
|
||||
const settings = initSettings(props.settings, config);
|
||||
const skills = S.func.initSkills(props.skills);
|
||||
|
||||
const handleChange = (newSettings) => {
|
||||
|
||||
@ -97,7 +97,7 @@ function Source(props) {
|
||||
options.push(
|
||||
<MenuItem key="none" value="none" disabled={true}>
|
||||
{i18n._(t`No input device available`)}
|
||||
</MenuItem>
|
||||
</MenuItem>,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user