mirror of https://github.com/OpenVidu/openvidu.git
openvidu-test-e2e: test RTSP with all codecs
parent
5c97301c6d
commit
0fe47c4b13
|
@ -181,8 +181,7 @@ public class OpenViduEventManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 'eventNumber' is accumulative for event 'eventType-eventCategory' for one
|
// 'eventNumber' is accumulative for event 'eventType-eventCategory' for one
|
||||||
// page while it is
|
// page while it is not refreshed
|
||||||
// not refreshed
|
|
||||||
public void waitUntilEventReaches(String eventType, String eventCategory, int eventNumber) throws Exception {
|
public void waitUntilEventReaches(String eventType, String eventCategory, int eventNumber) throws Exception {
|
||||||
this.waitUntilEventReaches(eventType, eventCategory, eventNumber, this.timeOfWaitInSeconds, true);
|
this.waitUntilEventReaches(eventType, eventCategory, eventNumber, this.timeOfWaitInSeconds, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,19 +11,22 @@ import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.TrustManager;
|
||||||
import javax.net.ssl.X509TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.apache.commons.lang3.tuple.Triple;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -50,10 +53,44 @@ public class OpenViduTestE2e {
|
||||||
|
|
||||||
private final static WaitStrategy waitBrowser = Wait.forLogMessage("^.*Started Selenium Standalone.*$", 1);
|
private final static WaitStrategy waitBrowser = Wait.forLogMessage("^.*Started Selenium Standalone.*$", 1);
|
||||||
|
|
||||||
protected static String RTSP_SERVER_IMAGE = "lroktu/vlc-server:latest";
|
protected static String RTSP_SERVER_IMAGE = "bluenviron/mediamtx:latest-ffmpeg";
|
||||||
protected static String SRT_SERVER_IMAGE = "linuxserver/ffmpeg:latest";
|
|
||||||
protected static int RTSP_SRT_PORT = 8554;
|
protected static int RTSP_SRT_PORT = 8554;
|
||||||
|
|
||||||
|
// Key is the common name of the video codec. It must match the output log of
|
||||||
|
// the RTSP server when receiving it.
|
||||||
|
// Value is a pair with:
|
||||||
|
// 1. The flag value of the ffmpeg command
|
||||||
|
// 2. Any extra flags needed for that codec to work
|
||||||
|
final protected static Map<String, Pair<String, ?>> FFMPEG_VIDEO_CODEC_NAMES = new HashMap<>() {
|
||||||
|
{
|
||||||
|
put("H264", Pair.of("libx264", ""));
|
||||||
|
put("VP8", Pair.of("libvpx", ""));
|
||||||
|
put("VP9", Pair.of("libvpx-vp9", ""));
|
||||||
|
put("MPEG-4", Pair.of("mpeg4", ""));
|
||||||
|
put("M-JPEG", Pair.of("mjpeg", "-force_duplicated_matrix:v 1 -huffman:v 0"));
|
||||||
|
// put("AV1", Pair.of("libaom-av1", "")); // NOT SUPPORTED BY THE RTSP SERVER
|
||||||
|
// (maybe gstreamer?)
|
||||||
|
// put("H265", Pair.of("libx265", "")); // NOT SUPPORTED BY INGRESS
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Key is the common name of the video codec. It must match the output log of
|
||||||
|
// the RTSP server when receiving it.
|
||||||
|
// Value is a triple with:
|
||||||
|
// 1. The flag value of the ffmpeg command
|
||||||
|
// 2. Any extra flags needed for that codec to work
|
||||||
|
// 3. The string expected to appear on the server log when the stream starts
|
||||||
|
final protected static Map<String, Triple<String, String, String>> FFMPEG_AUDIO_CODEC_NAMES = new HashMap<>() {
|
||||||
|
{
|
||||||
|
put("AAC", Triple.of("aac", "-b:a 128k", "MPEG-4 Audio"));
|
||||||
|
put("AC3", Triple.of("ac3", "-b:a 128k", null));
|
||||||
|
put("OPUS", Triple.of("libopus", "", "Opus"));
|
||||||
|
put("MP3", Triple.of("libmp3lame", "", "MPEG-1/2 Audio"));
|
||||||
|
put("VORBIS", Triple.of("libvorbis", "", null));
|
||||||
|
put("G711", Triple.of("pcm_mulaw", "", "G711"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
protected static String LIVEKIT_API_KEY = "devkey";
|
protected static String LIVEKIT_API_KEY = "devkey";
|
||||||
protected static String LIVEKIT_API_SECRET = "secret";
|
protected static String LIVEKIT_API_SECRET = "secret";
|
||||||
protected static String LIVEKIT_URL = "ws://localhost:7880/";
|
protected static String LIVEKIT_URL = "ws://localhost:7880/";
|
||||||
|
@ -141,24 +178,123 @@ public class OpenViduTestE2e {
|
||||||
return edge;
|
return edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startRtspServer(boolean withAudio, boolean withVideo) throws Exception {
|
/**
|
||||||
|
* @return the rtsp URI where the stream is served
|
||||||
|
*/
|
||||||
|
public String startRtspServer(String videoCodec, String audioCodec) throws Exception {
|
||||||
|
|
||||||
GenericContainer<?> rtspServerContainer = new GenericContainer<>(DockerImageName.parse(RTSP_SERVER_IMAGE))
|
GenericContainer<?> rtspServerContainer = new GenericContainer<>(DockerImageName.parse(RTSP_SERVER_IMAGE))
|
||||||
.withNetworkMode("host")
|
.withCreateContainerCmdModifier(cmd -> cmd.withName("rtsp-" + Math.random() * 100000))
|
||||||
.withCommand(getFileUrl(withAudio, withVideo) + " --loop :sout=#gather:rtp{sdp=rtsp://:" + RTSP_SRT_PORT
|
.withEnv(Map.of("MTX_LOGLEVEL",
|
||||||
+ "/} :network-caching=1500 :sout-all :sout-keep");
|
"info", "MTX_PROTOCOLS", "tcp", "MTX_RTSPADDRESS", ":8554", "MTX_HLS",
|
||||||
|
"no", "MTX_RTSP", "yes", "MTX_WEBRTC", "yes", "MTX_SRT", "no", "MTX_RTMP", "no", "MTX_API",
|
||||||
|
"no"))
|
||||||
|
.withExposedPorts(8889, 8554).waitingFor(Wait.forHttp("/").forPort(8889).forStatusCode(404));
|
||||||
|
rtspServerContainer.setPortBindings(Arrays.asList("8554:8554"));
|
||||||
|
|
||||||
rtspServerContainer.start();
|
rtspServerContainer.start();
|
||||||
containers.add(rtspServerContainer);
|
containers.add(rtspServerContainer);
|
||||||
|
|
||||||
|
final String RTSP_PATH = "live";
|
||||||
|
String fileUrl = getFileUrl(videoCodec != null, audioCodec != null);
|
||||||
|
String codecs = getCodecs(videoCodec, audioCodec);
|
||||||
|
String rtspServerIp = rtspServerContainer.getContainerInfo().getNetworkSettings().getIpAddress();
|
||||||
|
|
||||||
|
String ffmpegCommand = "ffmpeg -i " + fileUrl + " " + codecs + " "
|
||||||
|
+ " -async 50 -strict -2 -f rtsp -rtsp_transport tcp rtsp://" + rtspServerIp + ":" + RTSP_SRT_PORT + "/"
|
||||||
|
+ RTSP_PATH;
|
||||||
|
|
||||||
|
// Clean adjacent white spaces or the ffmpeg command will fail
|
||||||
|
ffmpegCommand = ffmpegCommand.trim().replaceAll(" +", " ");
|
||||||
|
|
||||||
|
GenericContainer<?> ffmpegPublishContainer = new GenericContainer<>(DockerImageName.parse(RTSP_SERVER_IMAGE))
|
||||||
|
.withCreateContainerCmdModifier(cmd -> cmd.withName("ffmpeg-" + Math.random() * 100000))
|
||||||
|
.withEnv("MTX_PATHS_RTSP_RUNONINIT", ffmpegCommand)
|
||||||
|
.waitingFor(Wait.forLogMessage(".*Press \\[q\\] to stop.*", 1));
|
||||||
|
|
||||||
|
ffmpegPublishContainer.start();
|
||||||
|
containers.add(ffmpegPublishContainer);
|
||||||
|
|
||||||
|
if (videoCodec != null) {
|
||||||
|
String regex = ".*is publishing to path '" + RTSP_PATH + "'[^\\n]*\\([^\\n]*(?i)(" + videoCodec
|
||||||
|
+ ")[^\\n]*\\)\\n";
|
||||||
|
waitUntilLog(rtspServerContainer, regex, 15);
|
||||||
|
}
|
||||||
|
if (audioCodec != null) {
|
||||||
|
String expectedValue = FFMPEG_AUDIO_CODEC_NAMES.get(audioCodec).getRight();
|
||||||
|
String regex = ".*is publishing to path '" + RTSP_PATH + "'[^\\n]*\\([^\\n]*(?i)(" + expectedValue
|
||||||
|
+ ")[^\\n]*\\)\\n";
|
||||||
|
waitUntilLog(rtspServerContainer, regex, 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startSrtServer(boolean withAudio, boolean withVideo) throws Exception {
|
return "rtsp://host.docker.internal:" + RTSP_SRT_PORT + "/" + RTSP_PATH;
|
||||||
GenericContainer<?> srtServerContainer = new GenericContainer<>(DockerImageName.parse(SRT_SERVER_IMAGE))
|
}
|
||||||
.withNetworkMode("host").withCommand("-i " + getFileUrl(withAudio, withVideo)
|
|
||||||
+ " -c:v libx264 -f mpegts srt://:" + RTSP_SRT_PORT + "?mode=listener");
|
/**
|
||||||
|
* @return the srt URI where the stream is served
|
||||||
|
*/
|
||||||
|
public String startSrtServer(String videoCodec, String audioCodec) throws Exception {
|
||||||
|
|
||||||
|
String fileUrl = getFileUrl(videoCodec != null, audioCodec != null);
|
||||||
|
String codecs = getCodecs(videoCodec, audioCodec);
|
||||||
|
|
||||||
|
String ffmpegCommand = "ffmpeg -i " + fileUrl + " " + codecs + " -strict -2 -f mpegts srt://:" + RTSP_SRT_PORT
|
||||||
|
+ "?mode=listener";
|
||||||
|
|
||||||
|
// Clean adjacent white spaces or the ffmpeg command will fail
|
||||||
|
ffmpegCommand = ffmpegCommand.trim().replaceAll(" +", " ");
|
||||||
|
|
||||||
|
GenericContainer<?> srtServerContainer = new GenericContainer<>(DockerImageName.parse(RTSP_SERVER_IMAGE))
|
||||||
|
.withCreateContainerCmdModifier(cmd -> cmd.withName("ffmpeg-" + Math.random() * 100000))
|
||||||
|
.withEnv("MTX_PATHS_RTSP_RUNONINIT", ffmpegCommand)
|
||||||
|
.waitingFor(Wait.forLogMessage(".*" + fileUrl + ".+", 1));
|
||||||
|
|
||||||
srtServerContainer.start();
|
srtServerContainer.start();
|
||||||
containers.add(srtServerContainer);
|
containers.add(srtServerContainer);
|
||||||
|
|
||||||
|
String srtServerIp = srtServerContainer.getContainerInfo().getNetworkSettings().getIpAddress();
|
||||||
|
|
||||||
|
return "srt://" + srtServerIp + ":" + RTSP_SRT_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getFileUrl(boolean withAudio, boolean withVideo) throws Exception {
|
private void waitUntilLog(GenericContainer<?> container, String regex, int secondsTimeout) {
|
||||||
|
int t = secondsTimeout * 2; // We wait half a second between retries
|
||||||
|
Pattern pattern = Pattern.compile(regex);
|
||||||
|
while (t > 0) {
|
||||||
|
String logs = container.getLogs();
|
||||||
|
if (pattern.matcher(logs).find()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Thread.sleep(500);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
t--;
|
||||||
|
}
|
||||||
|
if (!pattern.matcher(container.getLogs()).find()) {
|
||||||
|
Assertions.fail("RTSP server has not published media in " + secondsTimeout + " seconds. Looking for regex "
|
||||||
|
+ regex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getCodecs(String videoCodec, String audioCodec) {
|
||||||
|
String codecs = " ";
|
||||||
|
if (videoCodec != null) {
|
||||||
|
String ffmpegVideoCodecFlag = FFMPEG_VIDEO_CODEC_NAMES.get(videoCodec).getLeft();
|
||||||
|
codecs += " -vcodec " + ffmpegVideoCodecFlag + " ";
|
||||||
|
codecs += FFMPEG_VIDEO_CODEC_NAMES.get(videoCodec).getRight() + " ";
|
||||||
|
}
|
||||||
|
if (audioCodec != null) {
|
||||||
|
String ffmpegAudioCodecFlag = FFMPEG_AUDIO_CODEC_NAMES.get(audioCodec).getLeft();
|
||||||
|
codecs += " -acodec " + ffmpegAudioCodecFlag + " ";
|
||||||
|
codecs += FFMPEG_AUDIO_CODEC_NAMES.get(audioCodec).getMiddle() + " ";
|
||||||
|
}
|
||||||
|
codecs = codecs.trim().replaceAll(" +", " ");
|
||||||
|
return " " + codecs + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFileUrl(boolean withVideo, boolean withAudio) throws Exception {
|
||||||
String fileUrl;
|
String fileUrl;
|
||||||
if (withAudio && withVideo) {
|
if (withAudio && withVideo) {
|
||||||
fileUrl = "https://s3.eu-west-1.amazonaws.com/public.openvidu.io/bbb_sunflower_1080p_60fps_normal.mp4";
|
fileUrl = "https://s3.eu-west-1.amazonaws.com/public.openvidu.io/bbb_sunflower_1080p_60fps_normal.mp4";
|
||||||
|
@ -399,28 +535,14 @@ public class OpenViduTestE2e {
|
||||||
it1.remove();
|
it1.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop and remove all browser containers if necessary
|
// Stop and remove all containers
|
||||||
Iterator<GenericContainer<?>> it2 = containers.iterator();
|
Iterator<GenericContainer<?>> it2 = containers.iterator();
|
||||||
List<String> waitUntilContainerIsRemovedCommands = new ArrayList<>();
|
|
||||||
containers.forEach(c -> {
|
|
||||||
waitUntilContainerIsRemovedCommands
|
|
||||||
.add("while docker inspect " + c.getContainerId() + " >/dev/null 2>&1; do sleep 1; done");
|
|
||||||
});
|
|
||||||
while (it2.hasNext()) {
|
while (it2.hasNext()) {
|
||||||
GenericContainer<?> c = it2.next();
|
GenericContainer<?> c = it2.next();
|
||||||
stopContainerIfPossible(c);
|
c.stop();
|
||||||
|
c.close();
|
||||||
it2.remove();
|
it2.remove();
|
||||||
}
|
}
|
||||||
waitUntilContainerIsRemovedCommands.forEach(command -> {
|
|
||||||
commandLine.executeCommand(command, 30);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void stopContainerIfPossible(GenericContainer<?> container) {
|
|
||||||
if (container != null && container.isRunning()) {
|
|
||||||
container.stop();
|
|
||||||
container.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void closeAllRooms(RoomServiceClient client) {
|
protected void closeAllRooms(RoomServiceClient client) {
|
||||||
|
|
|
@ -1661,7 +1661,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
||||||
user.getEventManager().waitUntilEventReaches("connected", "RoomEvent", 1);
|
user.getEventManager().waitUntilEventReaches("connected", "RoomEvent", 1);
|
||||||
|
|
||||||
// Try publishing H264 with 2 layer simulcast
|
// Try publishing H264 with 2 layer simulcast
|
||||||
createIngress(user, "H264_540P_25FPS_2_LAYERS", null, true, "HTTP");
|
createIngress(user, "H264_540P_25FPS_2_LAYERS", null, true, "HTTP", null);
|
||||||
|
|
||||||
user.getEventManager().waitUntilEventReaches("trackSubscribed", "ParticipantEvent", 1);
|
user.getEventManager().waitUntilEventReaches("trackSubscribed", "ParticipantEvent", 1);
|
||||||
user.getWaiter().until(ExpectedConditions.numberOfElementsToBe(By.tagName("video"), 1));
|
user.getWaiter().until(ExpectedConditions.numberOfElementsToBe(By.tagName("video"), 1));
|
||||||
|
@ -1690,7 +1690,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
||||||
user.getEventManager().waitUntilEventReaches("participantDisconnected", "RoomEvent", 1);
|
user.getEventManager().waitUntilEventReaches("participantDisconnected", "RoomEvent", 1);
|
||||||
|
|
||||||
// Try publishing H264 with 3 layer simulcast
|
// Try publishing H264 with 3 layer simulcast
|
||||||
createIngress(user, "H264_1080P_30FPS_3_LAYERS_HIGH_MOTION", null, true, "HTTP");
|
createIngress(user, "H264_1080P_30FPS_3_LAYERS_HIGH_MOTION", null, true, "HTTP", null);
|
||||||
user.getEventManager().waitUntilEventReaches("trackSubscribed", "ParticipantEvent", 1);
|
user.getEventManager().waitUntilEventReaches("trackSubscribed", "ParticipantEvent", 1);
|
||||||
user.getWaiter().until(ExpectedConditions.numberOfElementsToBe(By.tagName("video"), 1));
|
user.getWaiter().until(ExpectedConditions.numberOfElementsToBe(By.tagName("video"), 1));
|
||||||
numberOfVideos = user.getDriver().findElements(By.tagName("video")).size();
|
numberOfVideos = user.getDriver().findElements(By.tagName("video")).size();
|
||||||
|
@ -1715,58 +1715,347 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("RTSP ingress")
|
@DisplayName("RTSP ingress H264 + OPUS")
|
||||||
void rtspIngressTest() throws Exception {
|
void rtspIngressH264_OPUSTest() throws Exception {
|
||||||
startRtspServer(true, true);
|
log.info("RTSP ingress H264 + OPUS");
|
||||||
urPullCommon("RTSP", true, true);
|
String rtspUri = startRtspServer("H264", "OPUS");
|
||||||
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("RTSP ingress only video")
|
@DisplayName("RTSP ingress H264 + G711")
|
||||||
void rtspIngressTestOnlyVideo() throws Exception {
|
void rtspIngressH264_G711Test() throws Exception {
|
||||||
startRtspServer(false, true);
|
log.info("RTSP ingress H264 + G711");
|
||||||
urPullCommon("RTSP", false, true);
|
String rtspUri = startRtspServer("H264", "G711");
|
||||||
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("RTSP ingress only audio")
|
@DisplayName("RTSP ingress H264 + MP3")
|
||||||
void rtspIngressTestOnlyAudio() throws Exception {
|
void rtspIngressH264_MP3Test() throws Exception {
|
||||||
startRtspServer(true, false);
|
log.info("RTSP ingress H264 + MP3");
|
||||||
urPullCommon("RTSP", true, false);
|
String rtspUri = startRtspServer("H264", "MP3");
|
||||||
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("SRT ingress")
|
@DisplayName("RTSP ingress H264 + AAC")
|
||||||
@Disabled
|
void rtspIngressH264_AACTest() throws Exception {
|
||||||
void srtIngressTest() throws Exception {
|
log.info("RTSP ingress H264 + AAC");
|
||||||
startSrtServer(true, true);
|
String rtspUri = startRtspServer("H264", "AAC");
|
||||||
urPullCommon("SRT", true, true);
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("SRT ingress only video")
|
@DisplayName("RTSP ingress VP8 + OPUS")
|
||||||
@Disabled
|
void rtspIngressVP8_OPUSTest() throws Exception {
|
||||||
void srtIngressTestOnlyVideo() throws Exception {
|
log.info("RTSP ingress VP8 + OPUS");
|
||||||
startSrtServer(false, true);
|
String rtspUri = startRtspServer("VP8", "OPUS");
|
||||||
urPullCommon("SRT", false, true);
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("SRT ingress only audio")
|
@DisplayName("RTSP ingress VP8 + G711")
|
||||||
@Disabled
|
void rtspIngressVP8_G711Test() throws Exception {
|
||||||
void srtIngressTestOnlyAudio() throws Exception {
|
log.info("RTSP ingress VP8 + G711");
|
||||||
startSrtServer(true, false);
|
String rtspUri = startRtspServer("VP8", "G711");
|
||||||
urPullCommon("SRT", true, false);
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void urPullCommon(String urlType, boolean withAudio, boolean withVideo) throws Exception {
|
@Test
|
||||||
|
@DisplayName("RTSP ingress VP8 + MP3")
|
||||||
|
void rtspIngressVP8_MP3Test() throws Exception {
|
||||||
|
log.info("RTSP ingress VP8 + MP3");
|
||||||
|
String rtspUri = startRtspServer("VP8", "MP3");
|
||||||
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress MPEG4 + OPUS")
|
||||||
|
void rtspIngressMPEG4_OPUSTest() throws Exception {
|
||||||
|
log.info("RTSP ingress MPEG4 + OPUS");
|
||||||
|
String rtspUri = startRtspServer("MPEG-4", "OPUS");
|
||||||
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress MPEG4 + G711")
|
||||||
|
void rtspIngressMPEG4_G711Test() throws Exception {
|
||||||
|
log.info("RTSP ingress MPEG4 + G711");
|
||||||
|
String rtspUri = startRtspServer("MPEG-4", "G711");
|
||||||
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress MPEG4 + MP3")
|
||||||
|
void rtspIngressMPEG4_MP3Test() throws Exception {
|
||||||
|
log.info("RTSP ingress MPEG4 + MP3");
|
||||||
|
String rtspUri = startRtspServer("MPEG-4", "MP3");
|
||||||
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress VP9 + OPUS")
|
||||||
|
void rtspIngressVP9_OPUSTest() throws Exception {
|
||||||
|
log.info("RTSP ingress VP9 + OPUS");
|
||||||
|
String rtspUri = startRtspServer("VP9", "OPUS");
|
||||||
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress VP9 + G711")
|
||||||
|
void rtspIngressVP9_G711Test() throws Exception {
|
||||||
|
log.info("RTSP ingress VP9 + G711");
|
||||||
|
String rtspUri = startRtspServer("VP9", "G711");
|
||||||
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress VP9 + MP3")
|
||||||
|
void rtspIngressVP9_MP3Test() throws Exception {
|
||||||
|
log.info("RTSP ingress VP9 + MP3");
|
||||||
|
String rtspUri = startRtspServer("VP9", "MP3");
|
||||||
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress M-JPEG + OPUS")
|
||||||
|
void rtspIngressMJPEG_OPUSTest() throws Exception {
|
||||||
|
log.info("RTSP ingress M-JPEG + OPUS");
|
||||||
|
String rtspUri = startRtspServer("M-JPEG", "OPUS");
|
||||||
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress M-JPEG + G711")
|
||||||
|
void rtspIngressMJPEG_G711Test() throws Exception {
|
||||||
|
log.info("RTSP ingress M-JPEG + G711");
|
||||||
|
String rtspUri = startRtspServer("M-JPEG", "G711");
|
||||||
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress M-JPEG + MP3")
|
||||||
|
void rtspIngressMJPEG_MP3Test() throws Exception {
|
||||||
|
log.info("RTSP ingress M-JPEG + MP3");
|
||||||
|
String rtspUri = startRtspServer("M-JPEG", "MP3");
|
||||||
|
urPullCommon("RTSP", rtspUri, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress H264")
|
||||||
|
void rtspIngressH264Test() throws Exception {
|
||||||
|
log.info("RTSP ingress H264");
|
||||||
|
String rtspUri = startRtspServer("H264", null);
|
||||||
|
urPullCommon("RTSP", rtspUri, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress VP8")
|
||||||
|
void rtspIngressVP8Test() throws Exception {
|
||||||
|
log.info("RTSP ingress VP8");
|
||||||
|
String rtspUri = startRtspServer("VP8", null);
|
||||||
|
urPullCommon("RTSP", rtspUri, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress MPEG-4")
|
||||||
|
void rtspIngressMPEG4Test() throws Exception {
|
||||||
|
log.info("RTSP ingress MPEG-4");
|
||||||
|
String rtspUri = startRtspServer("MPEG-4", null);
|
||||||
|
urPullCommon("RTSP", rtspUri, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress VP9")
|
||||||
|
void rtspIngressVP9Test() throws Exception {
|
||||||
|
log.info("RTSP ingress VP9");
|
||||||
|
String rtspUri = startRtspServer("VP9", null);
|
||||||
|
urPullCommon("RTSP", rtspUri, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress M-JPEG")
|
||||||
|
void rtspIngressMJPEGTest() throws Exception {
|
||||||
|
log.info("RTSP ingress M-JPEG");
|
||||||
|
String rtspUri = startRtspServer("M-JPEG", null);
|
||||||
|
urPullCommon("RTSP", rtspUri, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress AAC")
|
||||||
|
void rtspIngressAACTest() throws Exception {
|
||||||
|
log.info("RTSP ingress AAC");
|
||||||
|
String rtspUri = startRtspServer(null, "AAC");
|
||||||
|
urPullCommon("RTSP", rtspUri, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress MP3")
|
||||||
|
void rtspIngressMP3Test() throws Exception {
|
||||||
|
log.info("RTSP ingress MP3");
|
||||||
|
String rtspUri = startRtspServer(null, "MP3");
|
||||||
|
urPullCommon("RTSP", rtspUri, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress OPUS")
|
||||||
|
void rtspIngressOPUSTest() throws Exception {
|
||||||
|
log.info("RTSP ingress OPUS");
|
||||||
|
String rtspUri = startRtspServer(null, "OPUS");
|
||||||
|
urPullCommon("RTSP", rtspUri, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress G711")
|
||||||
|
@Disabled // Ingress fails with error "Not found"
|
||||||
|
void rtspIngressG711Test() throws Exception {
|
||||||
|
log.info("RTSP ingress G711");
|
||||||
|
String rtspUri = startRtspServer(null, "G711");
|
||||||
|
urPullCommon("RTSP", rtspUri, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("RTSP ingress AC3")
|
||||||
|
@Disabled // AC3 audio codec not supported through RTSP server with a single audio PCMU
|
||||||
|
// track
|
||||||
|
void rtspIngressAC3Test() throws Exception {
|
||||||
|
log.info("RTSP ingress AC3");
|
||||||
|
String rtspUri = startRtspServer(null, "AC3");
|
||||||
|
urPullCommon("RTSP", rtspUri, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NOTE 1: ingress with SRT pull does not work in the local network when ingress
|
||||||
|
* process is a Docker container
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* NOTE 2: ingress SRT seems to support only video codecs H264 and MPEG-4
|
||||||
|
*/
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("SRT ingress H264 + AAC")
|
||||||
|
// @Disabled // AAC audio codec stream fails if sent along a video stream
|
||||||
|
// void srtIngressTestH264_AAC() throws Exception {
|
||||||
|
// log.info("SRT ingress H264 + AAC");
|
||||||
|
// String srtUri = startSrtServer("H264", "AAC");
|
||||||
|
// urPullCommon("SRT", srtUri, true, true);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("SRT ingress H264 + AC3")
|
||||||
|
// void srtIngressTestH264_AC3() throws Exception {
|
||||||
|
// log.info("SRT ingress H264 + AC3");
|
||||||
|
// String srtUri = startSrtServer("H264", "AC3");
|
||||||
|
// urPullCommon("SRT", srtUri, true, true);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("SRT ingress H264 + OPUS")
|
||||||
|
// void srtIngressTestH264_OPUS() throws Exception {
|
||||||
|
// log.info("SRT ingress H264 + OPUS");
|
||||||
|
// String srtUri = startSrtServer("H264", "OPUS");
|
||||||
|
// urPullCommon("SRT", srtUri, true, true);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("SRT ingress H264 + MP3")
|
||||||
|
// void srtIngressTestH264_MP3() throws Exception {
|
||||||
|
// log.info("SRT ingress H264 + MP3");
|
||||||
|
// String srtUri = startSrtServer("H264", "MP3");
|
||||||
|
// urPullCommon("SRT", srtUri, true, true);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("SRT ingress MPEG-4 + AAC")
|
||||||
|
// @Disabled // AAC audio codec stream fails if sent along a video stream
|
||||||
|
// void srtIngressTestMPEG-4_AAC() throws Exception {
|
||||||
|
// log.info("SRT ingress MPEG-4 + AAC");
|
||||||
|
// String srtUri = startSrtServer("MPEG-4", "AAC");
|
||||||
|
// urPullCommon("SRT", srtUri, true, true);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("SRT ingress MPEG-4 + AC3")
|
||||||
|
// void srtIngressTestMPEG-4_AC3() throws Exception {
|
||||||
|
// log.info("SRT ingress MPEG-4 + AC3");
|
||||||
|
// String srtUri = startSrtServer("MPEG-4", "AC3");
|
||||||
|
// urPullCommon("SRT", srtUri, true, true);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("SRT ingress MPEG-4 + OPUS")
|
||||||
|
// void srtIngressTestMPEG-4_OPUS() throws Exception {
|
||||||
|
// log.info("SRT ingress MPEG-4 + OPUS");
|
||||||
|
// String srtUri = startSrtServer("MPEG-4", "OPUS");
|
||||||
|
// urPullCommon("SRT", srtUri, true, true);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("SRT ingress MPEG-4 + MP3")
|
||||||
|
// void srtIngressTestMPEG-4_MP3() throws Exception {
|
||||||
|
// log.info("SRT ingress MPEG-4 + MP3");
|
||||||
|
// String srtUri = startSrtServer("MPEG-4", "MP3");
|
||||||
|
// urPullCommon("SRT", srtUri, true, true);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("SRT ingress H264")
|
||||||
|
// void srtIngressTestH264() throws Exception {
|
||||||
|
// log.info("SRT ingress H264");
|
||||||
|
// String srtUri = startSrtServer("H264", null);
|
||||||
|
// urPullCommon("SRT", srtUri, true, false);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("SRT ingress MPEG-4")
|
||||||
|
// void srtIngressTestMPEG-4() throws Exception {
|
||||||
|
// log.info("SRT ingress MPEG-4");
|
||||||
|
// String srtUri = startSrtServer("MPEG-4", null);
|
||||||
|
// urPullCommon("SRT", srtUri, true, false);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("SRT ingress AAC")
|
||||||
|
// void srtIngressTestAAC() throws Exception {
|
||||||
|
// log.info("SRT ingress AAC");
|
||||||
|
// String srtUri = startSrtServer(null, "AAC");
|
||||||
|
// urPullCommon("SRT", srtUri, false, true);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("SRT ingress AC3")
|
||||||
|
// void srtIngressTestAC3() throws Exception {
|
||||||
|
// log.info("SRT ingress AC3");
|
||||||
|
// String srtUri = startSrtServer(null, "AC3");
|
||||||
|
// urPullCommon("SRT", srtUri, false, true);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("SRT ingress MP3")
|
||||||
|
// void srtIngressTestMP3() throws Exception {
|
||||||
|
// log.info("SRT ingress MP3");
|
||||||
|
// String srtUri = startSrtServer(null, "MP3");
|
||||||
|
// urPullCommon("SRT", srtUri, false, true);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("SRT ingress OPUS")
|
||||||
|
// @Disabled // A single OPUS audio stream fails
|
||||||
|
// void srtIngressTestOPUS() throws Exception {
|
||||||
|
// log.info("SRT ingress OPUS");
|
||||||
|
// String srtUri = startSrtServer(null, "OPUS");
|
||||||
|
// urPullCommon("SRT", srtUri, false, true);
|
||||||
|
// }
|
||||||
|
|
||||||
|
private void urPullCommon(String urlType, String uri, boolean withVideo, boolean withAudio) throws Exception {
|
||||||
OpenViduTestappUser user = setupBrowserAndConnectToOpenViduTestapp("chrome");
|
OpenViduTestappUser user = setupBrowserAndConnectToOpenViduTestapp("chrome");
|
||||||
this.addSubscriber(user, false);
|
this.addSubscriber(user, false);
|
||||||
user.getDriver().findElements(By.className("connect-btn")).forEach(el -> el.sendKeys(Keys.ENTER));
|
user.getDriver().findElements(By.className("connect-btn")).forEach(el -> el.sendKeys(Keys.ENTER));
|
||||||
user.getEventManager().waitUntilEventReaches("connected", "RoomEvent", 1);
|
user.getEventManager().waitUntilEventReaches("connected", "RoomEvent", 1);
|
||||||
createIngress(user, null, "VP8", false, urlType);
|
createIngress(user, null, "VP8", false, urlType, uri);
|
||||||
|
|
||||||
if (withAudio && withVideo) {
|
if (withVideo && withAudio) {
|
||||||
user.getEventManager().waitUntilEventReaches("trackSubscribed", "ParticipantEvent", 2);
|
user.getEventManager().waitUntilEventReaches("trackSubscribed", "ParticipantEvent", 2);
|
||||||
} else {
|
} else {
|
||||||
user.getEventManager().waitUntilEventReaches("trackSubscribed", "ParticipantEvent", 1);
|
user.getEventManager().waitUntilEventReaches("trackSubscribed", "ParticipantEvent", 1);
|
||||||
|
@ -1822,7 +2111,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
||||||
|
|
||||||
user.getEventManager().waitUntilEventReaches("connected", "RoomEvent", 1);
|
user.getEventManager().waitUntilEventReaches("connected", "RoomEvent", 1);
|
||||||
|
|
||||||
createIngress(user, preset, codec, simulcast, "HTTP");
|
createIngress(user, preset, codec, simulcast, "HTTP", null);
|
||||||
|
|
||||||
user.getEventManager().waitUntilEventReaches("trackSubscribed", "ParticipantEvent", 1);
|
user.getEventManager().waitUntilEventReaches("trackSubscribed", "ParticipantEvent", 1);
|
||||||
|
|
||||||
|
@ -2175,8 +2464,8 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createIngress(OpenViduTestappUser user, String preset, String codec, boolean simulcast, String urlType)
|
private void createIngress(OpenViduTestappUser user, String preset, String codec, boolean simulcast, String urlType,
|
||||||
throws InterruptedException {
|
String urlUri) throws InterruptedException {
|
||||||
if (!user.getDriver().findElements(By.id("close-dialog-btn")).isEmpty()) {
|
if (!user.getDriver().findElements(By.id("close-dialog-btn")).isEmpty()) {
|
||||||
user.getDriver().findElement(By.id("close-dialog-btn")).click();
|
user.getDriver().findElement(By.id("close-dialog-btn")).click();
|
||||||
Thread.sleep(300);
|
Thread.sleep(300);
|
||||||
|
@ -2200,6 +2489,9 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
||||||
Thread.sleep(300);
|
Thread.sleep(300);
|
||||||
user.getDriver().findElement(By.cssSelector("#mat-option-" + urlType.toUpperCase())).click();
|
user.getDriver().findElement(By.cssSelector("#mat-option-" + urlType.toUpperCase())).click();
|
||||||
}
|
}
|
||||||
|
if (urlUri != null) {
|
||||||
|
user.getDriver().findElement(By.cssSelector("#ingress-url-uri-field")).sendKeys(urlUri);
|
||||||
|
}
|
||||||
user.getDriver().findElement(By.cssSelector("#create-ingress-api-btn")).click();
|
user.getDriver().findElement(By.cssSelector("#create-ingress-api-btn")).click();
|
||||||
user.getDriver().findElement(By.cssSelector("#close-dialog-btn")).click();
|
user.getDriver().findElement(By.cssSelector("#close-dialog-btn")).click();
|
||||||
Thread.sleep(300);
|
Thread.sleep(300);
|
||||||
|
|
Loading…
Reference in New Issue