diff --git a/openvidu-test-e2e/pom.xml b/openvidu-test-e2e/pom.xml
index 75fa6ec6..d3c5e571 100644
--- a/openvidu-test-e2e/pom.xml
+++ b/openvidu-test-e2e/pom.xml
@@ -156,7 +156,16 @@
jcodec-javase
0.2.3
-
+
+ ws.schild
+ jave-core
+ 2.4.5
+
+
+ ws.schild
+ jave-native-linux64
+ 2.4.5
+
io.openvidu
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 24486e16..e3ac8f92 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
@@ -81,6 +81,7 @@ import io.openvidu.test.e2e.browser.ChromeAndroidUser;
import io.openvidu.test.e2e.browser.ChromeUser;
import io.openvidu.test.e2e.browser.FirefoxUser;
import io.openvidu.test.e2e.browser.OperaUser;
+import io.openvidu.test.e2e.utils.MultimediaFileMetadata;
/**
* E2E tests for openvidu-testapp.
@@ -1233,6 +1234,82 @@ public class OpenViduTestAppE2eTest {
gracefullyLeaveParticipants(2);
}
+ /*@Test
+ @DisplayName("Remote record cross-browser audio-only and video-only")
+ void remoteRecordAudioOnlyVideoOnlyTest() throws Exception {
+
+ setupBrowser("chrome");
+
+ log.info("Remote record cross-browser audio-only and video-only");
+
+ Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
+ public void uncaughtException(Thread th, Throwable ex) {
+ System.out.println("Uncaught exception: " + ex);
+ synchronized (lock) {
+ OpenViduTestAppE2eTest.ex = new Exception(ex);
+ }
+ }
+ };
+
+ Thread t = new Thread(() -> {
+ BrowserUser user2 = new FirefoxUser("FirefoxUser", 30);
+ user2.getDriver().get(APP_URL);
+ WebElement urlInput = user2.getDriver().findElement(By.id("openvidu-url"));
+ urlInput.clear();
+ urlInput.sendKeys(OPENVIDU_URL);
+ WebElement secretInput = user2.getDriver().findElement(By.id("openvidu-secret"));
+ secretInput.clear();
+ secretInput.sendKeys(OPENVIDU_SECRET);
+
+ user2.getEventManager().startPolling();
+
+ user2.getDriver().findElement(By.id("add-user-btn")).click();
+ user2.getDriver().findElement(By.className("join-btn")).click();
+ try {
+ user.getEventManager().waitUntilEventReaches("connectionCreated", 4);
+ user.getEventManager().waitUntilEventReaches("accessAllowed", 2);
+ user.getEventManager().waitUntilEventReaches("streamCreated", 8);
+ user.getEventManager().waitUntilEventReaches("streamPlaying", 8);
+
+ Assert.assertTrue(user2.getEventManager()
+ .assertMediaTracks(user2.getDriver().findElements(By.tagName("video")), true, true));
+
+ user2.getEventManager().waitUntilEventReaches("streamDestroyed", 1);
+ user2.getEventManager().waitUntilEventReaches("connectionDestroyed", 1);
+ user2.getDriver().findElement(By.id("remove-user-btn")).click();
+ user2.getEventManager().waitUntilEventReaches("sessionDisconnected", 1);
+ } catch (Exception e) {
+ e.printStackTrace();
+ Thread.currentThread().interrupt();
+ }
+ user2.dispose();
+ });
+ t.setUncaughtExceptionHandler(h);
+ t.start();
+
+ user.getDriver().findElement(By.id("add-user-btn")).click();
+ user.getDriver().findElement(By.className("join-btn")).click();
+
+ user.getEventManager().waitUntilEventReaches("connectionCreated", 4);
+ user.getEventManager().waitUntilEventReaches("accessAllowed", 2);
+ user.getEventManager().waitUntilEventReaches("streamCreated", 8);
+ user.getEventManager().waitUntilEventReaches("streamPlaying", 8);
+
+ Assert.assertEquals(user.getDriver().findElements(By.tagName("video")).size(), 2);
+ Assert.assertTrue(user.getEventManager().assertMediaTracks(user.getDriver().findElements(By.tagName("video")),
+ true, true));
+
+ gracefullyLeaveParticipants(1);
+
+ t.join();
+
+ synchronized (lock) {
+ if (OpenViduTestAppE2eTest.ex != null) {
+ throw OpenViduTestAppE2eTest.ex;
+ }
+ }
+ }*/
+
@Test
@DisplayName("REST API: Fetch all, fetch one, force disconnect, force unpublish, close session")
void restApiFetchForce() throws Exception {
@@ -1643,10 +1720,13 @@ public class OpenViduTestAppE2eTest {
}
private boolean recordedFileFine(File file, Recording recording) {
+ this.checkMultimediaFile(file, true, true, recording.getDuration(), recording.getResolution(), 30, "h264",
+ "aac");
+
boolean isFine = false;
Picture frame;
try {
- // Get a frame at 75% duration
+ // Get a frame at 75% duration and check that it has the expected color
frame = FrameGrab.getFrameAtSec(file, (double) (recording.getDuration() * 0.75));
BufferedImage image = AWTUtil.toBufferedImage(frame);
Map colorMap = this.averageColor(image);
@@ -1662,6 +1742,30 @@ public class OpenViduTestAppE2eTest {
return isFine;
}
+ private void checkMultimediaFile(File file, boolean hasAudio, boolean hasVideo, double duration, String resolution,
+ int framerate, String videoDecoder, String audioDecoder) {
+ // Check tracks, duration, resolution, framerate and decoders
+ MultimediaFileMetadata metadata = new MultimediaFileMetadata(file);
+
+ if (hasVideo) {
+ if (hasAudio) {
+ Assert.assertTrue(metadata.hasAudioAndVideo());
+ Assert.assertTrue(metadata.getAudioDecoder().toLowerCase().contains(audioDecoder));
+ } else {
+ Assert.assertTrue(metadata.hasVideo());
+ }
+ Assert.assertEquals(resolution, metadata.getVideoWidth() + "x" + metadata.getVideoHeight());
+ Assert.assertEquals(metadata.getFrameRate(), new Integer(30));
+ Assert.assertTrue(metadata.getVideoDecoder().toLowerCase().contains(videoDecoder));
+ } else if (hasAudio) {
+ Assert.assertTrue(metadata.hasAudio());
+ Assert.assertTrue(metadata.getAudioDecoder().toLowerCase().contains(audioDecoder));
+ } else {
+ Assert.fail("Cannot check a file witho no audio and no video");
+ }
+ Assert.assertTrue((double) metadata.getDuration() / 1000 == duration);
+ }
+
private boolean thumbnailIsFine(File file) {
boolean isFine = false;
BufferedImage image = null;
diff --git a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/utils/MultimediaFileMetadata.java b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/utils/MultimediaFileMetadata.java
new file mode 100644
index 00000000..7cdf9f06
--- /dev/null
+++ b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/utils/MultimediaFileMetadata.java
@@ -0,0 +1,123 @@
+/*
+ * (C) Copyright 2017-2019 OpenVidu (https://openvidu.io/)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package io.openvidu.test.e2e.utils;
+
+import java.io.File;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ws.schild.jave.AudioInfo;
+import ws.schild.jave.EncoderException;
+import ws.schild.jave.MultimediaInfo;
+import ws.schild.jave.MultimediaObject;
+import ws.schild.jave.VideoInfo;
+import ws.schild.jave.VideoSize;
+
+public class MultimediaFileMetadata {
+
+ private static final Logger log = LoggerFactory.getLogger(MultimediaFileMetadata.class);
+
+ private MultimediaInfo mediaInfo;
+ private AudioInfo audioInfo;
+ private VideoInfo videoInfo;
+ private VideoSize videoSize;
+
+ public MultimediaFileMetadata(File f) {
+ try {
+ this.mediaInfo = new MultimediaObject(f).getInfo();
+ this.audioInfo = mediaInfo.getAudio();
+ this.videoInfo = mediaInfo.getVideo();
+ if (videoInfo != null) {
+ this.videoSize = videoInfo.getSize();
+ }
+ } catch (EncoderException e) {
+ log.error("Error getting multimedia information from file {}. Error: ", f.getAbsolutePath(),
+ e.getMessage());
+ }
+ }
+
+ public long getDuration() {
+ return mediaInfo.getDuration();
+ }
+
+ public String getFormat(String format) {
+ return mediaInfo.getFormat();
+ }
+
+ public boolean hasAudio() {
+ return audioInfo != null;
+ }
+
+ public boolean hasVideo() {
+ return videoInfo != null;
+ }
+
+ public boolean hasAudioAndVideo() {
+ return this.hasAudio() && this.hasVideo();
+ }
+
+ public Integer getAudioBitrate() {
+ if (audioInfo != null) {
+ return audioInfo.getBitRate();
+ } else {
+ return null;
+ }
+ }
+
+ public Integer getVideoBitrate() {
+ if (videoInfo != null) {
+ return videoInfo.getBitRate();
+ } else {
+ return null;
+ }
+ }
+
+ public String getAudioDecoder() {
+ return audioInfo.getDecoder();
+ }
+
+ public String getVideoDecoder() {
+ return videoInfo.getDecoder();
+ }
+
+ public Integer getVideoWidth() {
+ if (videoSize != null) {
+ return videoSize.getWidth();
+ } else {
+ return null;
+ }
+ }
+
+ public Integer getVideoHeight() {
+ if (videoSize != null) {
+ return videoSize.getHeight();
+ } else {
+ return null;
+ }
+ }
+
+ public Integer getFrameRate() {
+ if (videoInfo != null) {
+ return Math.round(videoInfo.getFrameRate());
+ } else {
+ return null;
+ }
+ }
+
+}