diff --git a/openvidu-test-e2e/src/main/java/io/openvidu/test/e2e/OpenViduTestE2e.java b/openvidu-test-e2e/src/main/java/io/openvidu/test/e2e/OpenViduTestE2e.java index d9ca1ec60..cc0ae86c6 100644 --- a/openvidu-test-e2e/src/main/java/io/openvidu/test/e2e/OpenViduTestE2e.java +++ b/openvidu-test-e2e/src/main/java/io/openvidu/test/e2e/OpenViduTestE2e.java @@ -3,6 +3,7 @@ package io.openvidu.test.e2e; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.net.DatagramSocket; import java.net.ServerSocket; import java.net.URI; import java.net.URISyntaxException; @@ -32,6 +33,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.testcontainers.DockerClientFactory; import org.testcontainers.containers.BindMode; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.Network; @@ -60,8 +62,7 @@ public class OpenViduTestE2e { private final static WaitStrategy waitBrowser = Wait.forLogMessage("^.*Started Selenium Standalone.*$", 1); - protected static String RTSP_SERVER_IMAGE = "bluenviron/mediamtx:1.19.2-ffmpeg"; - protected static int RTSP_SRT_PORT = 8554; + protected static String RTSP_SERVER_IMAGE = "bluenviron/mediamtx:1.21.0-ffmpeg"; // Key is the common name of the video codec. It must match the output log of // the RTSP server when receiving it. @@ -296,7 +297,7 @@ public class OpenViduTestE2e { .withCreateContainerCmdModifier(cmd -> cmd.withName("rtsp-" + Math.random() * 100000)) .withEnv(Map.of("MTX_LOGLEVEL", "info", "MTX_RTSPTRANSPORTS", "tcp", "MTX_RTSPADDRESS", ":" + rtspPort, "MTX_HLS", "no", "MTX_RTSP", "yes", "MTX_WEBRTC", "no", "MTX_SRT", "no", "MTX_RTMP", "no", - "MTX_API", "no")) + "MTX_MOQ", "no", "MTX_API", "no")) .withNetworkMode("host") .waitingFor(Wait.forLogMessage("^.*\\[RTSP\\] started with listeners on :" + rtspPort + ".*$", 1)); @@ -351,27 +352,50 @@ public class OpenViduTestE2e { */ public String startSrtServer(String videoCodec, String audioCodec) throws Exception { + int srtPort; + try (DatagramSocket socket = new DatagramSocket(0)) { + srtPort = socket.getLocalPort(); + } + String hostGatewayIp = getDockerHostGatewayIp(); + int unusedRtspPort; + try (ServerSocket socket = new ServerSocket(0)) { + unusedRtspPort = socket.getLocalPort(); + } + String fileUrl = getFileUrl(videoCodec != null, audioCodec != null, true); String codecs = getCodecs(videoCodec, audioCodec); // -re: see startRtspServer. - String ffmpegCommand = "ffmpeg -re -i " + fileUrl + " " + codecs + " -strict -2 -f mpegts srt://:" - + RTSP_SRT_PORT + "?mode=listener"; + String ffmpegCommand = "ffmpeg -re -i " + fileUrl + " " + codecs + " -strict -2 -f mpegts srt://" + + hostGatewayIp + + ":" + srtPort + "?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) + .withEnv(Map.ofEntries(Map.entry("MTX_LOGLEVEL", "info"), Map.entry("MTX_RTSPTRANSPORTS", "tcp"), + Map.entry("MTX_RTSPADDRESS", ":" + unusedRtspPort), Map.entry("MTX_HLS", "no"), + Map.entry("MTX_RTSP", "yes"), Map.entry("MTX_WEBRTC", "no"), Map.entry("MTX_SRT", "no"), + Map.entry("MTX_RTMP", "no"), Map.entry("MTX_MOQ", "no"), Map.entry("MTX_API", "no"), + Map.entry("MTX_PATHS_RTSP_RUNONINIT", ffmpegCommand))) + .withNetworkMode("host") .waitingFor(Wait.forLogMessage(".*" + fileUrl + ".+", 1)); srtServerContainer.start(); containers.add(srtServerContainer); - String srtServerIp = srtServerContainer.getContainerInfo().getNetworkSettings().getIpAddress(); + return "srt://host.docker.internal:" + srtPort; + } - return "srt://" + srtServerIp + ":" + RTSP_SRT_PORT; + /** + * The host address that host.docker.internal resolves to inside containers + * created with host-gateway: the gateway of Docker's default bridge network. + */ + private String getDockerHostGatewayIp() { + return DockerClientFactory.instance().client().inspectNetworkCmd().withNetworkId("bridge").exec().getIpam() + .getConfig().get(0).getGateway(); } public void startServerSdkPublisher(String sdk, String roomName, String codec) throws Exception { diff --git a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java index 4f13b7002..2040e13bd 100644 --- a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java +++ b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java @@ -4621,8 +4621,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest { @Test @DisplayName("RTSP ingress AC3") - @Disabled // AC3 audio codec not supported through RTSP server with a single audio PCMU - // track + @Disabled // ffmpeg cannot payload AC-3 into RTP, see above void rtspIngressAC3Test() throws Exception { log.info("RTSP ingress AC3"); String rtspUri = startRtspServer(null, "AC3"); @@ -4630,127 +4629,121 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest { } /** - * 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 + * NOTE: SRT ingest carries MPEG-TS, so only the codecs MPEG-TS can carry are + * tested: H264 and MPEG-4 video; AAC, AC3, MP3 and OPUS audio. */ - // @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); - // } + @Test + @DisplayName("SRT ingress H264 + AAC") + void srtIngressH264_AACTest() 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 srtIngressH264_AC3Test() 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 srtIngressH264_OPUSTest() 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 srtIngressH264_MP3Test() 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") + void srtIngressMPEG4_AACTest() 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 srtIngressMPEG4_AC3Test() 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 srtIngressMPEG4_OPUSTest() 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 srtIngressMPEG4_MP3Test() 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 srtIngressH264Test() throws Exception { + log.info("SRT ingress H264"); + String srtUri = startSrtServer("H264", null); + urPullCommon("SRT", srtUri, true, false); + } + + @Test + @DisplayName("SRT ingress MPEG-4") + void srtIngressMPEG4Test() 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 srtIngressAACTest() throws Exception { + log.info("SRT ingress AAC"); + String srtUri = startSrtServer(null, "AAC"); + urPullCommon("SRT", srtUri, false, true); + } + + @Test + @DisplayName("SRT ingress AC3") + void srtIngressAC3Test() throws Exception { + log.info("SRT ingress AC3"); + String srtUri = startSrtServer(null, "AC3"); + urPullCommon("SRT", srtUri, false, true); + } + + @Test + @DisplayName("SRT ingress MP3") + void srtIngressMP3Test() throws Exception { + log.info("SRT ingress MP3"); + String srtUri = startSrtServer(null, "MP3"); + urPullCommon("SRT", srtUri, false, true); + } + + @Test + @DisplayName("SRT ingress OPUS") + void srtIngressOPUSTest() 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");