mirror of https://github.com/OpenVidu/openvidu.git
openvidu-test-e2e: refactor recording utilities to openvidu-test-browsers
parent
0561c6aab7
commit
eaa1361d04
|
@ -87,11 +87,20 @@
|
|||
<artifactId>unirest-java</artifactId>
|
||||
<version>${version.unirest}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jcodec</groupId>
|
||||
<artifactId>jcodec-javase</artifactId>
|
||||
<version>${version.jcodec}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.openvidu</groupId>
|
||||
<artifactId>openvidu-java-client</artifactId>
|
||||
<version>${version.openvidu.java.client}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${version.junit}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -0,0 +1,264 @@
|
|||
package io.openvidu.test.browsers.utils;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.jcodec.api.FrameGrab;
|
||||
import org.jcodec.api.JCodecException;
|
||||
import org.jcodec.common.model.Picture;
|
||||
import org.jcodec.scale.AWTUtil;
|
||||
import org.junit.Assert;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
|
||||
import io.openvidu.java.client.Recording;
|
||||
|
||||
public class RecordingUtils {
|
||||
|
||||
protected static final Logger log = LoggerFactory.getLogger(RecordingUtils.class);
|
||||
|
||||
public boolean recordedGreenFileFine(File file, Recording recording) throws IOException {
|
||||
return this.recordedFileFine(file, recording, RecordingUtils::checkVideoAverageRgbGreen);
|
||||
}
|
||||
|
||||
public boolean recordedRedFileFine(File file, Recording recording) throws IOException {
|
||||
return this.recordedFileFine(file, recording, RecordingUtils::checkVideoAverageRgbRed);
|
||||
}
|
||||
|
||||
private boolean recordedFileFine(File file, Recording recording,
|
||||
Function<Map<String, Long>, Boolean> colorCheckFunction) throws IOException {
|
||||
this.checkMultimediaFile(file, recording.hasAudio(), recording.hasVideo(), recording.getDuration(),
|
||||
recording.getResolution(), "aac", "h264", true);
|
||||
|
||||
boolean isFine = false;
|
||||
Picture frame;
|
||||
try {
|
||||
// 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<String, Long> colorMap = this.averageColor(image);
|
||||
|
||||
String realResolution = image.getWidth() + "x" + image.getHeight();
|
||||
Assert.assertEquals(
|
||||
"Resolution (" + recording.getResolution()
|
||||
+ ") of recording entity is not equal to real video resolution (" + realResolution + ")",
|
||||
recording.getResolution(), realResolution);
|
||||
|
||||
log.info("Recording map color: {}", colorMap.toString());
|
||||
log.info("Recording frame below");
|
||||
System.out.println(bufferedImageToBase64PngString(image));
|
||||
isFine = colorCheckFunction.apply(colorMap);
|
||||
} catch (IOException | JCodecException e) {
|
||||
log.warn("Error getting frame from video recording: {}", e.getMessage());
|
||||
isFine = false;
|
||||
}
|
||||
return isFine;
|
||||
}
|
||||
|
||||
public static boolean checkVideoAverageRgbGreen(Map<String, Long> rgb) {
|
||||
// GREEN color: {r < 15, g > 130, b <15}
|
||||
return (rgb.get("r") < 15) && (rgb.get("g") > 130) && (rgb.get("b") < 15);
|
||||
}
|
||||
|
||||
public static boolean checkVideoAverageRgbGray(Map<String, Long> rgb) {
|
||||
// GRAY color: {r < 50, g < 50, b < 50} and the absolute difference between them
|
||||
// not greater than 2
|
||||
return (rgb.get("r") < 50) && (rgb.get("g") < 50) && (rgb.get("b") < 50)
|
||||
&& (Math.abs(rgb.get("r") - rgb.get("g")) <= 2) && (Math.abs(rgb.get("r") - rgb.get("b")) <= 2)
|
||||
&& (Math.abs(rgb.get("b") - rgb.get("g")) <= 2);
|
||||
}
|
||||
|
||||
public static boolean checkVideoAverageRgbRed(Map<String, Long> rgb) {
|
||||
// RED color: {r > 240, g < 15, b <15}
|
||||
return (rgb.get("r") > 240) && (rgb.get("g") < 15) && (rgb.get("b") < 15);
|
||||
}
|
||||
|
||||
private String bufferedImageToBase64PngString(BufferedImage image) {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
String imageString = null;
|
||||
try {
|
||||
ImageIO.write(image, "png", bos);
|
||||
byte[] imageBytes = bos.toByteArray();
|
||||
imageString = "data:image/png;base64," + Base64.getEncoder().encodeToString(imageBytes);
|
||||
bos.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return imageString;
|
||||
}
|
||||
|
||||
public void checkIndividualRecording(String recPath, Recording recording, int numberOfVideoFiles,
|
||||
String audioDecoder, String videoDecoder, boolean checkAudio) throws IOException {
|
||||
|
||||
// Should be only 2 files: zip and metadata
|
||||
File folder = new File(recPath);
|
||||
Assert.assertEquals("There are more than 2 files (ZIP and metadata) inside individual recording folder "
|
||||
+ recPath + ": " + Arrays.toString(folder.listFiles()), 2, folder.listFiles().length);
|
||||
|
||||
File file1 = new File(recPath + recording.getName() + ".zip");
|
||||
File file2 = new File(recPath + ".recording." + recording.getId());
|
||||
|
||||
Assert.assertTrue("File " + file1.getAbsolutePath() + " does not exist or is empty",
|
||||
file1.exists() && file1.length() > 0);
|
||||
Assert.assertTrue("File " + file2.getAbsolutePath() + " does not exist or is empty",
|
||||
file2.exists() && file2.length() > 0);
|
||||
|
||||
List<File> unzippedWebmFiles = new Unzipper().unzipFile(recPath, recording.getName() + ".zip");
|
||||
|
||||
Assert.assertEquals("Expecting " + numberOfVideoFiles + " videos inside ZIP file but "
|
||||
+ unzippedWebmFiles.size() + " found: " + unzippedWebmFiles.toString(), numberOfVideoFiles,
|
||||
unzippedWebmFiles.size());
|
||||
|
||||
File jsonSyncFile = new File(recPath + recording.getName() + ".json");
|
||||
Assert.assertTrue("JSON sync file " + jsonSyncFile.getAbsolutePath() + "does not exist or is empty",
|
||||
jsonSyncFile.exists() && jsonSyncFile.length() > 0);
|
||||
|
||||
JsonObject jsonSyncMetadata;
|
||||
try {
|
||||
Gson gson = new Gson();
|
||||
JsonReader reader = new JsonReader(new FileReader(jsonSyncFile));
|
||||
jsonSyncMetadata = gson.fromJson(reader, JsonObject.class);
|
||||
} catch (Exception e) {
|
||||
log.error("Cannot read JSON sync metadata file from {}. Error: {}", jsonSyncFile.getAbsolutePath(),
|
||||
e.getMessage());
|
||||
Assert.fail("Cannot read JSON sync metadata file from " + jsonSyncFile.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
|
||||
long totalFileSize = 0;
|
||||
JsonArray syncArray = jsonSyncMetadata.get("files").getAsJsonArray();
|
||||
for (File webmFile : unzippedWebmFiles) {
|
||||
totalFileSize += webmFile.length();
|
||||
|
||||
Assert.assertTrue("WEBM file " + webmFile.getAbsolutePath() + " does not exist or is empty",
|
||||
webmFile.exists() && webmFile.length() > 0);
|
||||
|
||||
double durationInSeconds = 0;
|
||||
boolean found = false;
|
||||
for (int i = 0; i < syncArray.size(); i++) {
|
||||
JsonObject j = syncArray.get(i).getAsJsonObject();
|
||||
if (webmFile.getName().contains(j.get("streamId").getAsString())) {
|
||||
durationInSeconds = (double) (j.get("endTimeOffset").getAsDouble()
|
||||
- j.get("startTimeOffset").getAsDouble()) / 1000;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertTrue("Couldn't find in JSON sync object information for webm file " + webmFile.getName(),
|
||||
found);
|
||||
|
||||
log.info("Duration of {} according to sync metadata json file: {} s", webmFile.getName(),
|
||||
durationInSeconds);
|
||||
this.checkMultimediaFile(webmFile, recording.hasAudio(), recording.hasVideo(), durationInSeconds,
|
||||
recording.getResolution(), audioDecoder, videoDecoder, checkAudio);
|
||||
webmFile.delete();
|
||||
}
|
||||
|
||||
Assert.assertEquals("Size of recording entity (" + recording.getSessionId()
|
||||
+ ") is not equal to real file size (" + totalFileSize + ")", recording.getSize(), totalFileSize);
|
||||
|
||||
jsonSyncFile.delete();
|
||||
}
|
||||
|
||||
public void checkMultimediaFile(File file, boolean hasAudio, boolean hasVideo, double duration, String resolution,
|
||||
String audioDecoder, String videoDecoder, boolean checkAudio) throws IOException {
|
||||
// Check tracks, duration, resolution, framerate and decoders
|
||||
MultimediaFileMetadata metadata = new MultimediaFileMetadata(file.getAbsolutePath());
|
||||
|
||||
if (hasVideo) {
|
||||
if (checkAudio) {
|
||||
if (hasAudio) {
|
||||
Assert.assertTrue("Media file " + file.getAbsolutePath() + " should have audio",
|
||||
metadata.hasAudio() && metadata.hasVideo());
|
||||
Assert.assertTrue(metadata.getAudioDecoder().toLowerCase().contains(audioDecoder));
|
||||
} else {
|
||||
Assert.assertTrue("Media file " + file.getAbsolutePath() + " should have video",
|
||||
metadata.hasVideo());
|
||||
Assert.assertFalse(metadata.hasAudio());
|
||||
}
|
||||
}
|
||||
if (resolution != null) {
|
||||
Assert.assertEquals(resolution, metadata.getVideoWidth() + "x" + metadata.getVideoHeight());
|
||||
}
|
||||
Assert.assertTrue(metadata.getVideoDecoder().toLowerCase().contains(videoDecoder));
|
||||
} else if (hasAudio && checkAudio) {
|
||||
Assert.assertTrue(metadata.hasAudio());
|
||||
Assert.assertFalse(metadata.hasVideo());
|
||||
Assert.assertTrue(metadata.getAudioDecoder().toLowerCase().contains(audioDecoder));
|
||||
} else {
|
||||
Assert.fail("Cannot check a file witho no audio and no video");
|
||||
}
|
||||
// Check duration with 1 decimal precision
|
||||
DecimalFormat df = new DecimalFormat("#0.0");
|
||||
df.setRoundingMode(RoundingMode.UP);
|
||||
log.info("Duration of {} according to ffmpeg: {} s", file.getName(), metadata.getDuration());
|
||||
log.info("Duration of {} according to 'duration' property: {} s", file.getName(), duration);
|
||||
log.info("Difference in s duration: {}", Math.abs(metadata.getDuration() - duration));
|
||||
final double difference = 10;
|
||||
Assert.assertTrue(
|
||||
"Difference between recording entity duration (" + duration + ") and real video duration ("
|
||||
+ metadata.getDuration() + ") is greater than " + difference + " in file " + file.getName(),
|
||||
Math.abs((metadata.getDuration() - duration)) < difference);
|
||||
}
|
||||
|
||||
public boolean thumbnailIsFine(File file, Function<Map<String, Long>, Boolean> colorCheckFunction) {
|
||||
boolean isFine = false;
|
||||
BufferedImage image = null;
|
||||
try {
|
||||
image = ImageIO.read(file);
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
log.info("Recording thumbnail dimensions: {}x{}", image.getWidth(), image.getHeight());
|
||||
Map<String, Long> colorMap = this.averageColor(image);
|
||||
log.info("Thumbnail map color: {}", colorMap.toString());
|
||||
isFine = colorCheckFunction.apply(colorMap);
|
||||
return isFine;
|
||||
}
|
||||
|
||||
private Map<String, Long> averageColor(BufferedImage bi) {
|
||||
int x0 = 0;
|
||||
int y0 = 0;
|
||||
int w = bi.getWidth();
|
||||
int h = bi.getHeight();
|
||||
int x1 = x0 + w;
|
||||
int y1 = y0 + h;
|
||||
long sumr = 0, sumg = 0, sumb = 0;
|
||||
for (int x = x0; x < x1; x++) {
|
||||
for (int y = y0; y < y1; y++) {
|
||||
Color pixel = new Color(bi.getRGB(x, y));
|
||||
sumr += pixel.getRed();
|
||||
sumg += pixel.getGreen();
|
||||
sumb += pixel.getBlue();
|
||||
}
|
||||
}
|
||||
int num = w * h;
|
||||
Map<String, Long> colorMap = new HashMap<>();
|
||||
colorMap.put("r", (long) (sumr / num));
|
||||
colorMap.put("g", (long) (sumg / num));
|
||||
colorMap.put("b", (long) (sumb / num));
|
||||
return colorMap;
|
||||
}
|
||||
|
||||
}
|
|
@ -108,12 +108,6 @@
|
|||
<artifactId>gson</artifactId>
|
||||
<version>${version.gson}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jcodec</groupId>
|
||||
<artifactId>jcodec-javase</artifactId>
|
||||
<version>${version.jcodec}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mashape.unirest</groupId>
|
||||
<artifactId>unirest-java</artifactId>
|
||||
|
|
|
@ -2,37 +2,18 @@ package io.openvidu.test.e2e;
|
|||
|
||||
import static org.openqa.selenium.OutputType.BASE64;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.math.RoundingMode;
|
||||
import java.nio.file.Path;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import com.mashape.unirest.http.HttpMethod;
|
||||
import io.openvidu.test.browsers.utils.CustomHttpClient;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.jcodec.api.FrameGrab;
|
||||
import org.jcodec.api.JCodecException;
|
||||
import org.jcodec.common.model.Picture;
|
||||
import org.jcodec.scale.AWTUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.openqa.selenium.By;
|
||||
|
@ -45,26 +26,22 @@ import org.openqa.selenium.support.ui.ExpectedConditions;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.mashape.unirest.http.HttpMethod;
|
||||
|
||||
import io.github.bonigarcia.wdm.WebDriverManager;
|
||||
import io.openvidu.java.client.OpenVidu;
|
||||
import io.openvidu.java.client.OpenViduHttpException;
|
||||
import io.openvidu.java.client.OpenViduJavaClientException;
|
||||
import io.openvidu.java.client.Recording;
|
||||
import io.openvidu.java.client.VideoCodec;
|
||||
import io.openvidu.test.browsers.BrowserUser;
|
||||
import io.openvidu.test.browsers.ChromeAndroidUser;
|
||||
import io.openvidu.test.browsers.ChromeUser;
|
||||
import io.openvidu.test.browsers.FirefoxUser;
|
||||
import io.openvidu.test.browsers.OperaUser;
|
||||
import io.openvidu.test.browsers.utils.CommandLineExecutor;
|
||||
import io.openvidu.test.browsers.utils.MultimediaFileMetadata;
|
||||
import io.openvidu.test.browsers.utils.Unzipper;
|
||||
import io.openvidu.test.browsers.utils.CustomHttpClient;
|
||||
import io.openvidu.test.browsers.utils.RecordingUtils;
|
||||
|
||||
public class AbstractOpenViduTestAppE2eTest {
|
||||
|
||||
|
@ -96,6 +73,8 @@ public class AbstractOpenViduTestAppE2eTest {
|
|||
|
||||
protected static OpenVidu OV;
|
||||
|
||||
protected RecordingUtils recordingUtils = new RecordingUtils();
|
||||
|
||||
protected static void checkFfmpegInstallation() {
|
||||
String ffmpegOutput = commandLine.executeCommand("which ffmpeg");
|
||||
if (ffmpegOutput == null || ffmpegOutput.isEmpty()) {
|
||||
|
@ -298,24 +277,6 @@ public class AbstractOpenViduTestAppE2eTest {
|
|||
};
|
||||
}
|
||||
|
||||
protected static boolean checkVideoAverageRgbGreen(Map<String, Long> rgb) {
|
||||
// GREEN color: {r < 15, g > 130, b <15}
|
||||
return (rgb.get("r") < 15) && (rgb.get("g") > 130) && (rgb.get("b") < 15);
|
||||
}
|
||||
|
||||
protected static boolean checkVideoAverageRgbGray(Map<String, Long> rgb) {
|
||||
// GRAY color: {r < 50, g < 50, b < 50} and the absolute difference between them
|
||||
// not greater than 2
|
||||
return (rgb.get("r") < 50) && (rgb.get("g") < 50) && (rgb.get("b") < 50)
|
||||
&& (Math.abs(rgb.get("r") - rgb.get("g")) <= 2) && (Math.abs(rgb.get("r") - rgb.get("b")) <= 2)
|
||||
&& (Math.abs(rgb.get("b") - rgb.get("g")) <= 2);
|
||||
}
|
||||
|
||||
protected static boolean checkVideoAverageRgbRed(Map<String, Long> rgb) {
|
||||
// RED color: {r > 240, g < 15, b <15}
|
||||
return (rgb.get("r") > 240) && (rgb.get("g") < 15) && (rgb.get("b") < 15);
|
||||
}
|
||||
|
||||
protected void gracefullyLeaveParticipants(int numberOfParticipants) throws Exception {
|
||||
int accumulatedConnectionDestroyed = 0;
|
||||
for (int j = 1; j <= numberOfParticipants; j++) {
|
||||
|
@ -333,215 +294,6 @@ public class AbstractOpenViduTestAppE2eTest {
|
|||
return "data:image/png;base64," + screenshotBase64;
|
||||
}
|
||||
|
||||
protected boolean recordedFileFine(File file, Recording recording,
|
||||
Function<Map<String, Long>, Boolean> colorCheckFunction) throws IOException {
|
||||
this.checkMultimediaFile(file, recording.hasAudio(), recording.hasVideo(), recording.getDuration(),
|
||||
recording.getResolution(), "aac", "h264", true);
|
||||
|
||||
boolean isFine = false;
|
||||
Picture frame;
|
||||
try {
|
||||
// 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<String, Long> colorMap = this.averageColor(image);
|
||||
|
||||
String realResolution = image.getWidth() + "x" + image.getHeight();
|
||||
Assert.assertEquals(
|
||||
"Resolution (" + recording.getResolution()
|
||||
+ ") of recording entity is not equal to real video resolution (" + realResolution + ")",
|
||||
recording.getResolution(), realResolution);
|
||||
|
||||
log.info("Recording map color: {}", colorMap.toString());
|
||||
log.info("Recording frame below");
|
||||
System.out.println(bufferedImageToBase64PngString(image));
|
||||
isFine = colorCheckFunction.apply(colorMap);
|
||||
} catch (IOException | JCodecException e) {
|
||||
log.warn("Error getting frame from video recording: {}", e.getMessage());
|
||||
isFine = false;
|
||||
}
|
||||
return isFine;
|
||||
}
|
||||
|
||||
protected boolean recordedGreenFileFine(File file, Recording recording) throws IOException {
|
||||
return this.recordedFileFine(file, recording, OpenViduTestAppE2eTest::checkVideoAverageRgbGreen);
|
||||
}
|
||||
|
||||
protected boolean recordedRedFileFine(File file, Recording recording) throws IOException {
|
||||
return this.recordedFileFine(file, recording, OpenViduTestAppE2eTest::checkVideoAverageRgbRed);
|
||||
}
|
||||
|
||||
protected String bufferedImageToBase64PngString(BufferedImage image) {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
String imageString = null;
|
||||
try {
|
||||
ImageIO.write(image, "png", bos);
|
||||
byte[] imageBytes = bos.toByteArray();
|
||||
imageString = "data:image/png;base64," + Base64.getEncoder().encodeToString(imageBytes);
|
||||
bos.close();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return imageString;
|
||||
}
|
||||
|
||||
protected void checkIndividualRecording(String recPath, Recording recording, int numberOfVideoFiles,
|
||||
String audioDecoder, String videoDecoder, boolean checkAudio) throws IOException {
|
||||
|
||||
// Should be only 2 files: zip and metadata
|
||||
File folder = new File(recPath);
|
||||
Assert.assertEquals("There are more than 2 files (ZIP and metadata) inside individual recording folder "
|
||||
+ recPath + ": " + Arrays.toString(folder.listFiles()), 2, folder.listFiles().length);
|
||||
|
||||
File file1 = new File(recPath + recording.getName() + ".zip");
|
||||
File file2 = new File(recPath + ".recording." + recording.getId());
|
||||
|
||||
Assert.assertTrue("File " + file1.getAbsolutePath() + " does not exist or is empty",
|
||||
file1.exists() && file1.length() > 0);
|
||||
Assert.assertTrue("File " + file2.getAbsolutePath() + " does not exist or is empty",
|
||||
file2.exists() && file2.length() > 0);
|
||||
|
||||
List<File> unzippedWebmFiles = new Unzipper().unzipFile(recPath, recording.getName() + ".zip");
|
||||
|
||||
Assert.assertEquals("Expecting " + numberOfVideoFiles + " videos inside ZIP file but "
|
||||
+ unzippedWebmFiles.size() + " found: " + unzippedWebmFiles.toString(), numberOfVideoFiles,
|
||||
unzippedWebmFiles.size());
|
||||
|
||||
File jsonSyncFile = new File(recPath + recording.getName() + ".json");
|
||||
Assert.assertTrue("JSON sync file " + jsonSyncFile.getAbsolutePath() + "does not exist or is empty",
|
||||
jsonSyncFile.exists() && jsonSyncFile.length() > 0);
|
||||
|
||||
JsonObject jsonSyncMetadata;
|
||||
try {
|
||||
Gson gson = new Gson();
|
||||
JsonReader reader = new JsonReader(new FileReader(jsonSyncFile));
|
||||
jsonSyncMetadata = gson.fromJson(reader, JsonObject.class);
|
||||
} catch (Exception e) {
|
||||
log.error("Cannot read JSON sync metadata file from {}. Error: {}", jsonSyncFile.getAbsolutePath(),
|
||||
e.getMessage());
|
||||
Assert.fail("Cannot read JSON sync metadata file from " + jsonSyncFile.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
|
||||
long totalFileSize = 0;
|
||||
JsonArray syncArray = jsonSyncMetadata.get("files").getAsJsonArray();
|
||||
for (File webmFile : unzippedWebmFiles) {
|
||||
totalFileSize += webmFile.length();
|
||||
|
||||
Assert.assertTrue("WEBM file " + webmFile.getAbsolutePath() + " does not exist or is empty",
|
||||
webmFile.exists() && webmFile.length() > 0);
|
||||
|
||||
double durationInSeconds = 0;
|
||||
boolean found = false;
|
||||
for (int i = 0; i < syncArray.size(); i++) {
|
||||
JsonObject j = syncArray.get(i).getAsJsonObject();
|
||||
if (webmFile.getName().contains(j.get("streamId").getAsString())) {
|
||||
durationInSeconds = (double) (j.get("endTimeOffset").getAsDouble()
|
||||
- j.get("startTimeOffset").getAsDouble()) / 1000;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertTrue("Couldn't find in JSON sync object information for webm file " + webmFile.getName(),
|
||||
found);
|
||||
|
||||
log.info("Duration of {} according to sync metadata json file: {} s", webmFile.getName(),
|
||||
durationInSeconds);
|
||||
this.checkMultimediaFile(webmFile, recording.hasAudio(), recording.hasVideo(), durationInSeconds,
|
||||
recording.getResolution(), audioDecoder, videoDecoder, checkAudio);
|
||||
webmFile.delete();
|
||||
}
|
||||
|
||||
Assert.assertEquals("Size of recording entity (" + recording.getSessionId()
|
||||
+ ") is not equal to real file size (" + totalFileSize + ")", recording.getSize(), totalFileSize);
|
||||
|
||||
jsonSyncFile.delete();
|
||||
}
|
||||
|
||||
protected void checkMultimediaFile(File file, boolean hasAudio, boolean hasVideo, double duration,
|
||||
String resolution, String audioDecoder, String videoDecoder, boolean checkAudio) throws IOException {
|
||||
// Check tracks, duration, resolution, framerate and decoders
|
||||
MultimediaFileMetadata metadata = new MultimediaFileMetadata(file.getAbsolutePath());
|
||||
|
||||
if (hasVideo) {
|
||||
if (checkAudio) {
|
||||
if (hasAudio) {
|
||||
Assert.assertTrue("Media file " + file.getAbsolutePath() + " should have audio",
|
||||
metadata.hasAudio() && metadata.hasVideo());
|
||||
Assert.assertTrue(metadata.getAudioDecoder().toLowerCase().contains(audioDecoder));
|
||||
} else {
|
||||
Assert.assertTrue("Media file " + file.getAbsolutePath() + " should have video",
|
||||
metadata.hasVideo());
|
||||
Assert.assertFalse(metadata.hasAudio());
|
||||
}
|
||||
}
|
||||
if (resolution != null) {
|
||||
Assert.assertEquals(resolution, metadata.getVideoWidth() + "x" + metadata.getVideoHeight());
|
||||
}
|
||||
Assert.assertTrue(metadata.getVideoDecoder().toLowerCase().contains(videoDecoder));
|
||||
} else if (hasAudio && checkAudio) {
|
||||
Assert.assertTrue(metadata.hasAudio());
|
||||
Assert.assertFalse(metadata.hasVideo());
|
||||
Assert.assertTrue(metadata.getAudioDecoder().toLowerCase().contains(audioDecoder));
|
||||
} else {
|
||||
Assert.fail("Cannot check a file witho no audio and no video");
|
||||
}
|
||||
// Check duration with 1 decimal precision
|
||||
DecimalFormat df = new DecimalFormat("#0.0");
|
||||
df.setRoundingMode(RoundingMode.UP);
|
||||
log.info("Duration of {} according to ffmpeg: {} s", file.getName(), metadata.getDuration());
|
||||
log.info("Duration of {} according to 'duration' property: {} s", file.getName(), duration);
|
||||
log.info("Difference in s duration: {}", Math.abs(metadata.getDuration() - duration));
|
||||
final double difference = 10;
|
||||
Assert.assertTrue(
|
||||
"Difference between recording entity duration (" + duration + ") and real video duration ("
|
||||
+ metadata.getDuration() + ") is greater than " + difference + " in file " + file.getName(),
|
||||
Math.abs((metadata.getDuration() - duration)) < difference);
|
||||
}
|
||||
|
||||
protected boolean thumbnailIsFine(File file, Function<Map<String, Long>, Boolean> colorCheckFunction) {
|
||||
boolean isFine = false;
|
||||
BufferedImage image = null;
|
||||
try {
|
||||
image = ImageIO.read(file);
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
log.info("Recording thumbnail dimensions: {}x{}", image.getWidth(), image.getHeight());
|
||||
Map<String, Long> colorMap = this.averageColor(image);
|
||||
log.info("Thumbnail map color: {}", colorMap.toString());
|
||||
isFine = colorCheckFunction.apply(colorMap);
|
||||
return isFine;
|
||||
}
|
||||
|
||||
protected Map<String, Long> averageColor(BufferedImage bi) {
|
||||
int x0 = 0;
|
||||
int y0 = 0;
|
||||
int w = bi.getWidth();
|
||||
int h = bi.getHeight();
|
||||
int x1 = x0 + w;
|
||||
int y1 = y0 + h;
|
||||
long sumr = 0, sumg = 0, sumb = 0;
|
||||
for (int x = x0; x < x1; x++) {
|
||||
for (int y = y0; y < y1; y++) {
|
||||
Color pixel = new Color(bi.getRGB(x, y));
|
||||
sumr += pixel.getRed();
|
||||
sumg += pixel.getGreen();
|
||||
sumb += pixel.getBlue();
|
||||
}
|
||||
}
|
||||
int num = w * h;
|
||||
Map<String, Long> colorMap = new HashMap<>();
|
||||
colorMap.put("r", (long) (sumr / num));
|
||||
colorMap.put("g", (long) (sumg / num));
|
||||
colorMap.put("b", (long) (sumb / num));
|
||||
return colorMap;
|
||||
}
|
||||
|
||||
protected void startKms() {
|
||||
log.info("Starting KMS");
|
||||
commandLine.executeCommand("/usr/bin/kurento-media-server &>> /kms.log &");
|
||||
|
|
|
@ -168,7 +168,7 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
String recPath = "/opt/openvidu/recordings/" + sessionName + "/";
|
||||
Recording recording = new OpenVidu(OpenViduTestAppE2eTest.OPENVIDU_URL, OpenViduTestAppE2eTest.OPENVIDU_SECRET)
|
||||
.getRecording(sessionName);
|
||||
checkIndividualRecording(recPath, recording, 4, "opus", "vp8", true);
|
||||
this.recordingUtils.checkIndividualRecording(recPath, recording, 4, "opus", "vp8", true);
|
||||
|
||||
// Analyze INDIVIDUAL recording metadata
|
||||
new Unzipper().unzipFile(recPath, recording.getName() + ".zip");
|
||||
|
|
|
@ -73,6 +73,7 @@ import io.openvidu.java.client.SessionProperties;
|
|||
import io.openvidu.java.client.VideoCodec;
|
||||
import io.openvidu.test.browsers.FirefoxUser;
|
||||
import io.openvidu.test.browsers.utils.CustomHttpClient;
|
||||
import io.openvidu.test.browsers.utils.RecordingUtils;
|
||||
import io.openvidu.test.browsers.utils.layout.CustomLayoutHandler;
|
||||
import io.openvidu.test.browsers.utils.webhook.CustomWebhook;
|
||||
|
||||
|
@ -1082,10 +1083,10 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
Assert.assertTrue("File " + file3.getAbsolutePath() + " does not exist or is empty",
|
||||
file3.exists() && file3.length() > 0);
|
||||
|
||||
Assert.assertTrue("Recorded file " + file1.getAbsolutePath() + " is not fine", this.recordedGreenFileFine(file1,
|
||||
new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(sessionName)));
|
||||
Assert.assertTrue("Recorded file " + file1.getAbsolutePath() + " is not fine", this.recordingUtils
|
||||
.recordedGreenFileFine(file1, new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(sessionName)));
|
||||
Assert.assertTrue("Thumbnail " + file3.getAbsolutePath() + " is not fine",
|
||||
this.thumbnailIsFine(file3, OpenViduTestAppE2eTest::checkVideoAverageRgbGreen));
|
||||
this.recordingUtils.thumbnailIsFine(file3, RecordingUtils::checkVideoAverageRgbGreen));
|
||||
|
||||
// Try to get the stopped recording
|
||||
user.getDriver().findElement(By.id("get-recording-btn")).click();
|
||||
|
@ -1368,7 +1369,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
String recPath = recordingsPath + sessionName + "/";
|
||||
|
||||
Recording recording = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(sessionName);
|
||||
this.checkIndividualRecording(recPath, recording, 2, "opus", "vp8", true);
|
||||
this.recordingUtils.checkIndividualRecording(recPath, recording, 2, "opus", "vp8", true);
|
||||
|
||||
// Try to get the stopped recording
|
||||
user.getDriver().findElement(By.id("get-recording-btn")).click();
|
||||
|
@ -1592,24 +1593,24 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
// Check video-only COMPOSED recording
|
||||
String recPath = recordingsPath + SESSION_NAME + "/";
|
||||
Recording recording = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(SESSION_NAME);
|
||||
this.checkMultimediaFile(new File(recPath + recording.getName() + ".mp4"), false, true, recording.getDuration(),
|
||||
recording.getResolution(), null, "h264", true);
|
||||
this.recordingUtils.checkMultimediaFile(new File(recPath + recording.getName() + ".mp4"), false, true,
|
||||
recording.getDuration(), recording.getResolution(), null, "h264", true);
|
||||
|
||||
// Check audio-only COMPOSED recording
|
||||
recPath = recordingsPath + SESSION_NAME + "-1/";
|
||||
recording = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(SESSION_NAME + "-1");
|
||||
this.checkMultimediaFile(new File(recPath + recording.getName() + ".webm"), true, false,
|
||||
this.recordingUtils.checkMultimediaFile(new File(recPath + recording.getName() + ".webm"), true, false,
|
||||
recording.getDuration(), null, "opus", null, true);
|
||||
|
||||
// Check video-only INDIVIDUAL recording
|
||||
recPath = recordingsPath + SESSION_NAME + "-2/";
|
||||
recording = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(SESSION_NAME + "-2");
|
||||
this.checkIndividualRecording(recPath, recording, 3, "opus", "vp8", true);
|
||||
this.recordingUtils.checkIndividualRecording(recPath, recording, 3, "opus", "vp8", true);
|
||||
|
||||
// Check audio-only INDIVIDUAL recording
|
||||
recPath = recordingsPath + SESSION_NAME + "-3/";
|
||||
recording = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(SESSION_NAME + "-3");
|
||||
this.checkIndividualRecording(recPath, recording, 2, "opus", "vp8", true);
|
||||
this.recordingUtils.checkIndividualRecording(recPath, recording, 2, "opus", "vp8", true);
|
||||
|
||||
user.getDriver().findElement(By.id("close-dialog-btn")).click();
|
||||
Thread.sleep(500);
|
||||
|
@ -1685,10 +1686,10 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
File file1 = new File(recordingsPath + SESSION_NAME + ".mp4");
|
||||
File file2 = new File(recordingsPath + SESSION_NAME + ".jpg");
|
||||
|
||||
Assert.assertTrue("Recorded file " + file1.getAbsolutePath() + " is not fine", this.recordedRedFileFine(file1,
|
||||
new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(SESSION_NAME)));
|
||||
Assert.assertTrue("Recorded file " + file1.getAbsolutePath() + " is not fine", this.recordingUtils
|
||||
.recordedRedFileFine(file1, new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(SESSION_NAME)));
|
||||
Assert.assertTrue("Thumbnail " + file2.getAbsolutePath() + " is not fine",
|
||||
this.thumbnailIsFine(file2, OpenViduTestAppE2eTest::checkVideoAverageRgbRed));
|
||||
this.recordingUtils.thumbnailIsFine(file2, RecordingUtils::checkVideoAverageRgbRed));
|
||||
|
||||
// Custom layout from external URL
|
||||
CountDownLatch initLatch = new CountDownLatch(1);
|
||||
|
@ -1737,10 +1738,11 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
file1 = new File(recordingsPath + SESSION_NAME + "-1.mp4");
|
||||
file2 = new File(recordingsPath + SESSION_NAME + "-1.jpg");
|
||||
|
||||
Assert.assertTrue("Recorded file " + file1.getAbsolutePath() + " is not fine", this.recordedRedFileFine(
|
||||
file1, new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(SESSION_NAME + "-1")));
|
||||
Assert.assertTrue("Recorded file " + file1.getAbsolutePath() + " is not fine",
|
||||
this.recordingUtils.recordedRedFileFine(file1,
|
||||
new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(SESSION_NAME + "-1")));
|
||||
Assert.assertTrue("Thumbnail " + file2.getAbsolutePath() + " is not fine",
|
||||
this.thumbnailIsFine(file2, OpenViduTestAppE2eTest::checkVideoAverageRgbRed));
|
||||
this.recordingUtils.thumbnailIsFine(file2, RecordingUtils::checkVideoAverageRgbRed));
|
||||
|
||||
} finally {
|
||||
CustomLayoutHandler.shutDown();
|
||||
|
@ -1902,7 +1904,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
// Analyze Chrome fake video stream without gray filter (GREEN color)
|
||||
Map<String, Long> rgb = user.getEventManager().getAverageRgbFromVideo(subscriberVideo);
|
||||
System.out.println(rgb.toString());
|
||||
Assert.assertTrue("Video is not average green", checkVideoAverageRgbGreen(rgb));
|
||||
Assert.assertTrue("Video is not average green", RecordingUtils.checkVideoAverageRgbGreen(rgb));
|
||||
|
||||
// Try to apply none allowed filter
|
||||
user.getDriver().findElement(By.cssSelector(".filter-btn")).click();
|
||||
|
@ -1941,7 +1943,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
Thread.sleep(500);
|
||||
rgb = user.getEventManager().getAverageRgbFromVideo(subscriberVideo);
|
||||
System.out.println(rgb.toString());
|
||||
Assert.assertTrue("Video is not average gray", checkVideoAverageRgbGray(rgb));
|
||||
Assert.assertTrue("Video is not average gray", RecordingUtils.checkVideoAverageRgbGray(rgb));
|
||||
|
||||
// Execute filter method
|
||||
WebElement filterMethodInput = user.getDriver().findElement(By.id("filter-method-field"));
|
||||
|
@ -1959,7 +1961,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
Thread.sleep(500);
|
||||
rgb = user.getEventManager().getAverageRgbFromVideo(subscriberVideo);
|
||||
System.out.println(rgb.toString());
|
||||
Assert.assertTrue("Video is not average green", checkVideoAverageRgbGreen(rgb));
|
||||
Assert.assertTrue("Video is not average green", RecordingUtils.checkVideoAverageRgbGreen(rgb));
|
||||
|
||||
user.getDriver().findElement(By.id("close-dialog-btn")).click();
|
||||
Thread.sleep(500);
|
||||
|
@ -1984,7 +1986,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
subscriberVideo = user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 video"));
|
||||
rgb = user.getEventManager().getAverageRgbFromVideo(subscriberVideo);
|
||||
System.out.println(rgb.toString());
|
||||
Assert.assertTrue("Video is not average gray", checkVideoAverageRgbGray(rgb));
|
||||
Assert.assertTrue("Video is not average gray", RecordingUtils.checkVideoAverageRgbGray(rgb));
|
||||
|
||||
// Remove filter
|
||||
user.getDriver().findElement(By.cssSelector(".filter-btn")).click();
|
||||
|
@ -1998,7 +2000,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
// Analyze Chrome fake video stream with gray filter (GREEN color)
|
||||
rgb = user.getEventManager().getAverageRgbFromVideo(subscriberVideo);
|
||||
System.out.println(rgb.toString());
|
||||
Assert.assertTrue("Video is not average green", checkVideoAverageRgbGreen(rgb));
|
||||
Assert.assertTrue("Video is not average green", RecordingUtils.checkVideoAverageRgbGreen(rgb));
|
||||
|
||||
user.getDriver().findElement(By.id("close-dialog-btn")).click();
|
||||
Thread.sleep(500);
|
||||
|
@ -2457,8 +2459,8 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
Assert.assertFalse("Session shouldn't be being recorded", session.isBeingRecorded());
|
||||
Assert.assertFalse("OpenVidu.fetch() should return false", OV.fetch());
|
||||
|
||||
this.checkIndividualRecording("/opt/openvidu/recordings/" + customSessionId + "/", recording, 2, "opus", "vp8",
|
||||
false);
|
||||
this.recordingUtils.checkIndividualRecording("/opt/openvidu/recordings/" + customSessionId + "/", recording, 2,
|
||||
"opus", "vp8", false);
|
||||
|
||||
user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .change-publisher-btn")).click();
|
||||
user.getEventManager().waitUntilEventReaches("streamDestroyed", 4);
|
||||
|
@ -2522,9 +2524,9 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
file3.exists() && file3.length() > 0);
|
||||
|
||||
Assert.assertTrue("Recorded file " + file1.getAbsolutePath() + " is not fine",
|
||||
this.recordedGreenFileFine(file1, recording2));
|
||||
this.recordingUtils.recordedGreenFileFine(file1, recording2));
|
||||
Assert.assertTrue("Thumbnail " + file3.getAbsolutePath() + " is not fine",
|
||||
this.thumbnailIsFine(file3, OpenViduTestAppE2eTest::checkVideoAverageRgbGreen));
|
||||
this.recordingUtils.thumbnailIsFine(file3, RecordingUtils::checkVideoAverageRgbGreen));
|
||||
|
||||
try {
|
||||
OV.deleteRecording("NOT_EXISTS");
|
||||
|
@ -2614,24 +2616,20 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
session.close();
|
||||
|
||||
/** Test transcoding defined properties */
|
||||
SessionProperties.Builder basePropertiesBuilder = new SessionProperties.Builder()
|
||||
.mediaMode(MediaMode.ROUTED).recordingMode(RecordingMode.ALWAYS)
|
||||
.defaultOutputMode(OutputMode.INDIVIDUAL);
|
||||
SessionProperties.Builder basePropertiesBuilder = new SessionProperties.Builder().mediaMode(MediaMode.ROUTED)
|
||||
.recordingMode(RecordingMode.ALWAYS).defaultOutputMode(OutputMode.INDIVIDUAL);
|
||||
|
||||
SessionProperties propertiesDefaultCodec = basePropertiesBuilder.build();
|
||||
SessionProperties propertiesH264AllowTranscoding = basePropertiesBuilder
|
||||
.forcedVideoCodec(VideoCodec.H264)
|
||||
.allowTranscoding(true)
|
||||
.build();
|
||||
SessionProperties propertiesVP9AllowTranscoding = basePropertiesBuilder
|
||||
.forcedVideoCodec(VideoCodec.VP9)
|
||||
.allowTranscoding(true)
|
||||
.build();
|
||||
SessionProperties propertiesH264AllowTranscoding = basePropertiesBuilder.forcedVideoCodec(VideoCodec.H264)
|
||||
.allowTranscoding(true).build();
|
||||
SessionProperties propertiesVP9AllowTranscoding = basePropertiesBuilder.forcedVideoCodec(VideoCodec.VP9)
|
||||
.allowTranscoding(true).build();
|
||||
|
||||
Session sessionDefaultCodec = OV.createSession(propertiesDefaultCodec);
|
||||
Session sessionH264AllowTranscoding = OV.createSession(propertiesH264AllowTranscoding);
|
||||
Session sessionVP9AllowTranscoding = OV.createSession(propertiesVP9AllowTranscoding);
|
||||
assertTranscodingSessionProperties(sessionDefaultCodec, sessionH264AllowTranscoding, sessionVP9AllowTranscoding);
|
||||
assertTranscodingSessionProperties(sessionDefaultCodec, sessionH264AllowTranscoding,
|
||||
sessionVP9AllowTranscoding);
|
||||
|
||||
// Fetch sessions
|
||||
Assert.assertFalse(sessionDefaultCodec.fetch());
|
||||
|
@ -2639,13 +2637,15 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
Assert.assertFalse(sessionVP9AllowTranscoding.fetch());
|
||||
|
||||
// Check transcoding session properties
|
||||
assertTranscodingSessionProperties(sessionDefaultCodec, sessionH264AllowTranscoding, sessionVP9AllowTranscoding);
|
||||
assertTranscodingSessionProperties(sessionDefaultCodec, sessionH264AllowTranscoding,
|
||||
sessionVP9AllowTranscoding);
|
||||
|
||||
// Fetch all sessions
|
||||
Assert.assertFalse(OV.fetch());
|
||||
|
||||
// Check transcoding session properties
|
||||
assertTranscodingSessionProperties(sessionDefaultCodec, sessionH264AllowTranscoding, sessionVP9AllowTranscoding);
|
||||
assertTranscodingSessionProperties(sessionDefaultCodec, sessionH264AllowTranscoding,
|
||||
sessionVP9AllowTranscoding);
|
||||
|
||||
sessionDefaultCodec.close();
|
||||
sessionH264AllowTranscoding.close();
|
||||
|
@ -3101,8 +3101,12 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
// Check all sessions data
|
||||
res = restClient.rest(HttpMethod.GET, "/openvidu/api/sessions", HttpStatus.SC_OK);
|
||||
Assert.assertEquals(res.get("numberOfElements").getAsInt(), 1);
|
||||
Assert.assertEquals(VideoCodec.valueOf(res.get("content").getAsJsonArray().get(0).getAsJsonObject().get("forcedVideoCodec").getAsString()), defaultForcedVideoCodec);
|
||||
Assert.assertEquals(res.get("content").getAsJsonArray().get(0).getAsJsonObject().get("allowTranscoding").getAsBoolean(), defaultAllowTranscoding);
|
||||
Assert.assertEquals(VideoCodec.valueOf(
|
||||
res.get("content").getAsJsonArray().get(0).getAsJsonObject().get("forcedVideoCodec").getAsString()),
|
||||
defaultForcedVideoCodec);
|
||||
Assert.assertEquals(
|
||||
res.get("content").getAsJsonArray().get(0).getAsJsonObject().get("allowTranscoding").getAsBoolean(),
|
||||
defaultAllowTranscoding);
|
||||
|
||||
// Remove session
|
||||
restClient.rest(HttpMethod.DELETE, "/openvidu/api/sessions/CUSTOM_SESSION_ID", HttpStatus.SC_NO_CONTENT);
|
||||
|
@ -3117,8 +3121,12 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
// Check all sessions data
|
||||
res = restClient.rest(HttpMethod.GET, "/openvidu/api/sessions", HttpStatus.SC_OK);
|
||||
Assert.assertEquals(res.get("numberOfElements").getAsInt(), 1);
|
||||
Assert.assertEquals(VideoCodec.valueOf(res.get("content").getAsJsonArray().get(0).getAsJsonObject().get("forcedVideoCodec").getAsString()), VideoCodec.H264);
|
||||
Assert.assertEquals(res.get("content").getAsJsonArray().get(0).getAsJsonObject().get("allowTranscoding").getAsBoolean(), true);
|
||||
Assert.assertEquals(VideoCodec.valueOf(
|
||||
res.get("content").getAsJsonArray().get(0).getAsJsonObject().get("forcedVideoCodec").getAsString()),
|
||||
VideoCodec.H264);
|
||||
Assert.assertEquals(
|
||||
res.get("content").getAsJsonArray().get(0).getAsJsonObject().get("allowTranscoding").getAsBoolean(),
|
||||
true);
|
||||
|
||||
restClient.rest(HttpMethod.DELETE, "/openvidu/api/sessions/CUSTOM_SESSION_ID", HttpStatus.SC_NO_CONTENT);
|
||||
}
|
||||
|
@ -3248,7 +3256,8 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
Assert.assertTrue("Recording duration exceeds valid value. Expected no more than 0.2 seconds, got "
|
||||
+ differenceInDuration, differenceInDuration < 0.2);
|
||||
|
||||
this.checkIndividualRecording("/opt/openvidu/recordings/TestSession/", rec, 1, "opus", "vp8", true);
|
||||
this.recordingUtils.checkIndividualRecording("/opt/openvidu/recordings/TestSession/", rec, 1, "opus", "vp8",
|
||||
true);
|
||||
|
||||
WebElement pubBtn = user.getDriver().findElements(By.cssSelector("#openvidu-instance-1 .pub-btn")).get(0);
|
||||
pubBtn.click();
|
||||
|
@ -3672,7 +3681,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
CustomWebhook.waitForEvent("recordingStatusChanged", 1); // Ready
|
||||
|
||||
Recording recording = new OpenVidu(OPENVIDU_URL, OPENVIDU_SECRET).getRecording(recId);
|
||||
this.checkIndividualRecording(recPath + recId + "/", recording, 1, "opus", "vp8", true);
|
||||
this.recordingUtils.checkIndividualRecording(recPath + recId + "/", recording, 1, "opus", "vp8", true);
|
||||
|
||||
// Test IPCAM individual recording (IPCAM video only, recording audio and video)
|
||||
|
||||
|
@ -4042,8 +4051,11 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
|
||||
/**
|
||||
* Test to force specified codec and allowTranscoding
|
||||
* @param codec codec to force. If null, default value in openvidu config will be used.
|
||||
* @param allowTranscoding If true, allow transcoding. If null, default value in openvidu config will be used.
|
||||
*
|
||||
* @param codec codec to force. If null, default value in openvidu
|
||||
* config will be used.
|
||||
* @param allowTranscoding If true, allow transcoding. If null, default value in
|
||||
* openvidu config will be used.
|
||||
*/
|
||||
private void forceCodecGenericE2eTest(VideoCodec codec, Boolean allowTranscoding) throws Exception {
|
||||
CustomHttpClient restClient = new CustomHttpClient(OPENVIDU_URL, "OPENVIDUAPP", OPENVIDU_SECRET);
|
||||
|
@ -4084,9 +4096,13 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
|
||||
// Load properties from session object of node-client
|
||||
user.getDriver().findElement(By.id("session-info-btn-0")).click();
|
||||
JsonObject res = JsonParser.parseString(user.getDriver().findElement(By.id("session-text-area")).getAttribute("value")).getAsJsonObject();
|
||||
VideoCodec sessionCodecNodeClient = VideoCodec.valueOf(res.get("properties").getAsJsonObject().get("forcedVideoCodec").getAsString());
|
||||
boolean sessionAllowTranscodingNodeClient = res.get("properties").getAsJsonObject().get("allowTranscoding").getAsBoolean();
|
||||
JsonObject res = JsonParser
|
||||
.parseString(user.getDriver().findElement(By.id("session-text-area")).getAttribute("value"))
|
||||
.getAsJsonObject();
|
||||
VideoCodec sessionCodecNodeClient = VideoCodec
|
||||
.valueOf(res.get("properties").getAsJsonObject().get("forcedVideoCodec").getAsString());
|
||||
boolean sessionAllowTranscodingNodeClient = res.get("properties").getAsJsonObject().get("allowTranscoding")
|
||||
.getAsBoolean();
|
||||
user.getDriver().findElement(By.id("close-dialog-btn")).click();
|
||||
|
||||
final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size();
|
||||
|
@ -4128,6 +4144,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
|
||||
/**
|
||||
* Force codec not allowed by opened browser
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private void forceNotSupportedCodec(VideoCodec codec, boolean allowTranscoding) throws Exception {
|
||||
|
@ -4164,7 +4181,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
sessionName2.sendKeys(sessionName);
|
||||
|
||||
List<WebElement> joinButtons = user.getDriver().findElements(By.className("join-btn"));
|
||||
for(WebElement el : joinButtons) {
|
||||
for (WebElement el : joinButtons) {
|
||||
Thread.sleep(5000);
|
||||
el.sendKeys(Keys.ENTER);
|
||||
}
|
||||
|
@ -4193,18 +4210,25 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest {
|
|||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
private void assertTranscodingSessionProperties(Session sessionDefaultCodec, Session sessionH264AllowTranscoding, Session sessionVP9AllowTranscoding) {
|
||||
private void assertTranscodingSessionProperties(Session sessionDefaultCodec, Session sessionH264AllowTranscoding,
|
||||
Session sessionVP9AllowTranscoding) {
|
||||
// Check session with default transcoding params
|
||||
Assert.assertEquals("Wrong default forcedVideoCodec", defaultForcedVideoCodec, sessionDefaultCodec.getProperties().forcedVideoCodec());
|
||||
Assert.assertEquals("Wrong default allowTranscoding", defaultAllowTranscoding, sessionDefaultCodec.getProperties().isTranscodingAllowed());
|
||||
Assert.assertEquals("Wrong default forcedVideoCodec", defaultForcedVideoCodec,
|
||||
sessionDefaultCodec.getProperties().forcedVideoCodec());
|
||||
Assert.assertEquals("Wrong default allowTranscoding", defaultAllowTranscoding,
|
||||
sessionDefaultCodec.getProperties().isTranscodingAllowed());
|
||||
|
||||
// Check session which use H264 and allow transcoding
|
||||
Assert.assertEquals("Wrong default forcedVideoCodec", VideoCodec.H264, sessionH264AllowTranscoding.getProperties().forcedVideoCodec());
|
||||
Assert.assertEquals("Wrong default allowTranscoding", true, sessionH264AllowTranscoding.getProperties().isTranscodingAllowed());
|
||||
Assert.assertEquals("Wrong default forcedVideoCodec", VideoCodec.H264,
|
||||
sessionH264AllowTranscoding.getProperties().forcedVideoCodec());
|
||||
Assert.assertEquals("Wrong default allowTranscoding", true,
|
||||
sessionH264AllowTranscoding.getProperties().isTranscodingAllowed());
|
||||
|
||||
// Check session which use VP9 and allow transcoding
|
||||
Assert.assertEquals("Wrong default forcedVideoCodec", VideoCodec.VP9, sessionVP9AllowTranscoding.getProperties().forcedVideoCodec());
|
||||
Assert.assertEquals("Wrong default allowTranscoding", true, sessionVP9AllowTranscoding.getProperties().isTranscodingAllowed());
|
||||
Assert.assertEquals("Wrong default forcedVideoCodec", VideoCodec.VP9,
|
||||
sessionVP9AllowTranscoding.getProperties().forcedVideoCodec());
|
||||
Assert.assertEquals("Wrong default allowTranscoding", true,
|
||||
sessionVP9AllowTranscoding.getProperties().isTranscodingAllowed());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue