mirror of https://github.com/OpenVidu/openvidu.git
openvidu-test-e2e: enable the SRT ingress tests
The 14 srtIngress* tests had been commented out with three notes: SRT pull does not work when the ingress runs in a container, AAC fails alongside video, and a single OPUS stream fails. All 14 pass now. The first note was the networking. The listener ran on the bridge network testcontainers uses and the test handed the ingress a container IP that the deployment's own network cannot reach. Moving it to the host network is not enough on its own: host.docker.internal resolves to the gateway of Docker's default bridge, while the ingress sits on another network, so a listener bound to 0.0.0.0 answers the handshake from whatever source address routing picks for that network, and libsrt drops a reply that comes from an address it never contacted. TCP is immune, which is why RTSP never had the problem. The listener now binds the very address the ingress calls, taken from the Docker API, on a free UDP port. The second note does not reproduce: H264 + AAC and MPEG-4 + AAC pass unchanged, so it was a casualty of the networking problem. The third was a real product bug, in the ingress rather than here, and is fixed there. Both helpers now run mediamtx with RTSP over TCP and every other server off. On the host network its defaults collide with the deployment (1935 is the ingress RTMP port) or with another mediamtx (8000/8001 for RTP, and the MoQ server on 8892, which 1.21 extends to 8893), and the container exits. mediamtx moves to 1.21.0 in the same step. The RTSP AC3 test stays disabled, with the cause it actually has: ffmpeg's RTP muxer cannot payload AC-3, so the publisher never produces the stream. Verified against a local deployment: the 44 tests that use the mediamtx image, 30 RTSP and 14 SRT, all pass except that disabled one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>pull/910/merge
parent
7f6f1381d7
commit
adfd19c8fa
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Reference in New Issue