mirror of https://github.com/OpenVidu/openvidu.git
openvidu-test-e2e: use ffmpeg to get media files metadata
parent
d6921a963d
commit
eac716abf9
|
@ -103,7 +103,7 @@ public class RecordingInfoUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getVideoFramerate() {
|
public int getVideoFramerate() {
|
||||||
String frameRate = videoStream.get("r_frame_rate").toString();
|
String frameRate = videoStream.get("r_frame_rate").getAsString();
|
||||||
String[] frameRateParts = frameRate.split("/");
|
String[] frameRateParts = frameRate.split("/");
|
||||||
|
|
||||||
return Integer.parseInt(frameRateParts[0]) / Integer.parseInt(frameRateParts[1]);
|
return Integer.parseInt(frameRateParts[0]) / Integer.parseInt(frameRateParts[1]);
|
||||||
|
|
|
@ -39,6 +39,11 @@ RUN npm install -g typescript@latest
|
||||||
# sudo
|
# sudo
|
||||||
RUN apt-get -y install sudo
|
RUN apt-get -y install sudo
|
||||||
|
|
||||||
|
# ffmpeg (for ffprobe)
|
||||||
|
RUN add-apt-repository ppa:jonathonf/ffmpeg-4
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install -y ffmpeg
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
RUN rm -rf /var/lib/apt/lists/*
|
RUN rm -rf /var/lib/apt/lists/*
|
||||||
RUN apt-get autoremove --purge -y
|
RUN apt-get autoremove --purge -y
|
||||||
|
|
|
@ -156,16 +156,6 @@
|
||||||
<artifactId>jcodec-javase</artifactId>
|
<artifactId>jcodec-javase</artifactId>
|
||||||
<version>0.2.3</version>
|
<version>0.2.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>ws.schild</groupId>
|
|
||||||
<artifactId>jave-core</artifactId>
|
|
||||||
<version>2.4.5</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>ws.schild</groupId>
|
|
||||||
<artifactId>jave-native-linux64</artifactId>
|
|
||||||
<version>2.4.5</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.openvidu</groupId>
|
<groupId>io.openvidu</groupId>
|
||||||
|
|
|
@ -1933,12 +1933,11 @@ public class OpenViduTestAppE2eTest {
|
||||||
private void checkMultimediaFile(File file, boolean hasAudio, boolean hasVideo, double duration, String resolution,
|
private void checkMultimediaFile(File file, boolean hasAudio, boolean hasVideo, double duration, String resolution,
|
||||||
String audioDecoder, String videoDecoder) {
|
String audioDecoder, String videoDecoder) {
|
||||||
// Check tracks, duration, resolution, framerate and decoders
|
// Check tracks, duration, resolution, framerate and decoders
|
||||||
MultimediaFileMetadata metadata = new MultimediaFileMetadata(file);
|
MultimediaFileMetadata metadata = new MultimediaFileMetadata(file.getAbsolutePath());
|
||||||
metadata.processMultimediaFile(0);
|
|
||||||
|
|
||||||
if (hasVideo) {
|
if (hasVideo) {
|
||||||
if (hasAudio) {
|
if (hasAudio) {
|
||||||
Assert.assertTrue(metadata.hasAudioAndVideo());
|
Assert.assertTrue(metadata.hasAudio() && metadata.hasVideo());
|
||||||
Assert.assertTrue(metadata.getAudioDecoder().toLowerCase().contains(audioDecoder));
|
Assert.assertTrue(metadata.getAudioDecoder().toLowerCase().contains(audioDecoder));
|
||||||
} else {
|
} else {
|
||||||
Assert.assertTrue(metadata.hasVideo());
|
Assert.assertTrue(metadata.hasVideo());
|
||||||
|
|
|
@ -18,148 +18,151 @@
|
||||||
package io.openvidu.test.e2e.utils;
|
package io.openvidu.test.e2e.utils;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import ws.schild.jave.AudioInfo;
|
import com.google.gson.JsonArray;
|
||||||
import ws.schild.jave.EncoderException;
|
import com.google.gson.JsonObject;
|
||||||
import ws.schild.jave.MultimediaInfo;
|
import com.google.gson.JsonParser;
|
||||||
import ws.schild.jave.MultimediaObject;
|
|
||||||
import ws.schild.jave.VideoInfo;
|
|
||||||
import ws.schild.jave.VideoSize;
|
|
||||||
|
|
||||||
public class MultimediaFileMetadata {
|
public class MultimediaFileMetadata {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(MultimediaFileMetadata.class);
|
private static final Logger log = LoggerFactory.getLogger(MultimediaFileMetadata.class);
|
||||||
|
|
||||||
private File f;
|
private JsonObject json;
|
||||||
private MultimediaInfo mediaInfo;
|
private JsonObject formatJson;
|
||||||
private AudioInfo audioInfo;
|
private JsonObject audioStreamJson;
|
||||||
private VideoInfo videoInfo;
|
private JsonObject videoStreamJson;
|
||||||
private VideoSize videoSize;
|
|
||||||
|
|
||||||
public MultimediaFileMetadata(File f) {
|
private double duration;
|
||||||
this.f = f;
|
private String format;
|
||||||
|
private long bitrate;
|
||||||
|
private boolean hasAudio;
|
||||||
|
private boolean hasVideo;
|
||||||
|
private long audioSampleRate;
|
||||||
|
private String audioDecoder;
|
||||||
|
private String videoDecoder;
|
||||||
|
private int videoWidth;
|
||||||
|
private int videoHeight;
|
||||||
|
private int framerate;
|
||||||
|
|
||||||
|
public MultimediaFileMetadata(String fileAbsolutePath) {
|
||||||
|
|
||||||
|
log.info("Extracting media metadata info from file {}", fileAbsolutePath);
|
||||||
|
|
||||||
|
this.json = this.executeFfprobeCommand(fileAbsolutePath);
|
||||||
|
this.formatJson = json.get("format").getAsJsonObject();
|
||||||
|
JsonArray streams = json.get("streams").getAsJsonArray();
|
||||||
|
|
||||||
|
streams.forEach(e -> { // Only supposed for 2 streams max
|
||||||
|
String codecType = e.getAsJsonObject().get("codec_type").getAsString();
|
||||||
|
switch (codecType) {
|
||||||
|
case "audio":
|
||||||
|
this.audioStreamJson = e.getAsJsonObject();
|
||||||
|
break;
|
||||||
|
case "video":
|
||||||
|
this.videoStreamJson = e.getAsJsonObject();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.duration = formatJson.get("duration").getAsDouble();
|
||||||
|
this.format = formatJson.get("format_name").getAsString();
|
||||||
|
this.bitrate = formatJson.get("bit_rate").getAsLong();
|
||||||
|
this.hasAudio = this.audioStreamJson != null;
|
||||||
|
this.hasVideo = this.videoStreamJson != null;
|
||||||
|
|
||||||
|
if (this.hasAudio) {
|
||||||
|
this.audioDecoder = this.audioStreamJson.get("codec_name").getAsString();
|
||||||
|
this.audioSampleRate = this.audioStreamJson.get("sample_rate").getAsLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processMultimediaFile(int iteration) {
|
if (this.hasVideo) {
|
||||||
try {
|
this.videoDecoder = this.videoStreamJson.get("codec_name").getAsString();
|
||||||
this.mediaInfo = new MultimediaObject(f).getInfo();
|
this.videoWidth = this.videoStreamJson.get("width").getAsInt();
|
||||||
this.audioInfo = mediaInfo.getAudio();
|
this.videoHeight = this.videoStreamJson.get("height").getAsInt();
|
||||||
this.videoInfo = mediaInfo.getVideo();
|
|
||||||
if (videoInfo != null) {
|
String frameRate = this.videoStreamJson.get("r_frame_rate").getAsString();
|
||||||
this.videoSize = videoInfo.getSize();
|
String[] frameRateParts = frameRate.split("/");
|
||||||
}
|
this.framerate = Integer.parseInt(frameRateParts[0]) / Integer.parseInt(frameRateParts[1]);
|
||||||
log.info("File {} {} an audio track", f.getName(), this.audioInfo != null ? "has" : "doesn't have");
|
|
||||||
log.info("File {} {} a video track", f.getName(), this.videoInfo != null ? "has" : "doesn't have");
|
|
||||||
} catch (EncoderException e) {
|
|
||||||
log.error("Error getting multimedia information from file {}. Error: {}", f.getAbsolutePath(),
|
|
||||||
e.getMessage());
|
|
||||||
try {
|
|
||||||
Thread.sleep(1000);
|
|
||||||
} catch (InterruptedException e1) {
|
|
||||||
e1.printStackTrace();
|
|
||||||
}
|
|
||||||
log.info(System.getProperty("user.name"));
|
|
||||||
this.executeCommand("ls -la /tmp/jave/");
|
|
||||||
if (iteration == 0) {
|
|
||||||
this.executeCommand("chmod 777 /tmp/jave/ffmpeg*");
|
|
||||||
} else if (iteration < 5) {
|
|
||||||
this.processMultimediaFile(++iteration);
|
|
||||||
} else {
|
|
||||||
log.error("Couldn't run jave in 5 iterations");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getDuration() {
|
log.info("Media metadata for {}: {}", fileAbsolutePath, this.toString());
|
||||||
return mediaInfo.getDuration();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFormat(String format) {
|
public double getDuration() {
|
||||||
return mediaInfo.getFormat();
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormat() {
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getBitrate() {
|
||||||
|
return bitrate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAudio() {
|
public boolean hasAudio() {
|
||||||
return audioInfo != null;
|
return hasAudio;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasVideo() {
|
public boolean hasVideo() {
|
||||||
return videoInfo != null;
|
return hasVideo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAudioAndVideo() {
|
public long getAudioSampleRate() {
|
||||||
return this.hasAudio() && this.hasVideo();
|
return audioSampleRate;
|
||||||
}
|
|
||||||
|
|
||||||
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() {
|
public String getAudioDecoder() {
|
||||||
return audioInfo.getDecoder();
|
return audioDecoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getVideoDecoder() {
|
public String getVideoDecoder() {
|
||||||
return videoInfo.getDecoder();
|
return videoDecoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getVideoWidth() {
|
public int getVideoWidth() {
|
||||||
if (videoSize != null) {
|
return videoWidth;
|
||||||
return videoSize.getWidth();
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getVideoHeight() {
|
public int getVideoHeight() {
|
||||||
if (videoSize != null) {
|
return videoHeight;
|
||||||
return videoSize.getHeight();
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getFrameRate() {
|
public int getFrameRate() {
|
||||||
if (videoInfo != null) {
|
return framerate;
|
||||||
return Math.round(videoInfo.getFrameRate());
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeCommand(String command) {
|
private JsonObject executeFfprobeCommand(String filePath) {
|
||||||
log.info("Running bash command '{}'", command);
|
log.info("Running ffprobe command on '{}'", filePath);
|
||||||
|
String jsonLines = "";
|
||||||
try {
|
try {
|
||||||
String s;
|
String s;
|
||||||
Process p;
|
Process p;
|
||||||
p = Runtime.getRuntime().exec(command);
|
p = Runtime.getRuntime().exec("ffprobe -v quiet -print_format json -show_format -show_streams " + filePath);
|
||||||
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||||
while ((s = br.readLine()) != null)
|
while ((s = br.readLine()) != null) {
|
||||||
log.info("LINE: " + s);
|
jsonLines += s;
|
||||||
|
}
|
||||||
p.waitFor();
|
p.waitFor();
|
||||||
System.out.println("EXIT VALUE: " + p.exitValue());
|
|
||||||
p.destroy();
|
p.destroy();
|
||||||
} catch (IOException | InterruptedException e1) {
|
} catch (IOException | InterruptedException e1) {
|
||||||
log.info("Error updateing permissions of jave executable. Error: {}" + e1.getMessage());
|
log.info("Error updateing permissions of jave executable. Error: {}" + e1.getMessage());
|
||||||
}
|
}
|
||||||
|
JsonParser parser = new JsonParser();
|
||||||
|
return parser.parse(jsonLines).getAsJsonObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{duration=" + this.duration + ", format=" + this.format + ", bitrate=" + this.bitrate + ", hasAudio="
|
||||||
|
+ this.hasAudio + ", hasVideo=" + this.hasVideo + ", audioSampleRate=" + this.audioSampleRate
|
||||||
|
+ ", audioDecoder=" + this.audioDecoder + ", videoDecoder=" + this.videoDecoder + ", videoWidth="
|
||||||
|
+ this.videoWidth + ", videoHeight=" + this.videoHeight + ", framerate=" + this.framerate + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue