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() {
|
||||
String frameRate = videoStream.get("r_frame_rate").toString();
|
||||
String frameRate = videoStream.get("r_frame_rate").getAsString();
|
||||
String[] frameRateParts = frameRate.split("/");
|
||||
|
||||
return Integer.parseInt(frameRateParts[0]) / Integer.parseInt(frameRateParts[1]);
|
||||
|
|
|
@ -39,6 +39,11 @@ RUN npm install -g typescript@latest
|
|||
# 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
|
||||
RUN rm -rf /var/lib/apt/lists/*
|
||||
RUN apt-get autoremove --purge -y
|
||||
|
|
|
@ -156,16 +156,6 @@
|
|||
<artifactId>jcodec-javase</artifactId>
|
||||
<version>0.2.3</version>
|
||||
</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>
|
||||
<groupId>io.openvidu</groupId>
|
||||
|
|
|
@ -1933,12 +1933,11 @@ public class OpenViduTestAppE2eTest {
|
|||
private void checkMultimediaFile(File file, boolean hasAudio, boolean hasVideo, double duration, String resolution,
|
||||
String audioDecoder, String videoDecoder) {
|
||||
// Check tracks, duration, resolution, framerate and decoders
|
||||
MultimediaFileMetadata metadata = new MultimediaFileMetadata(file);
|
||||
metadata.processMultimediaFile(0);
|
||||
MultimediaFileMetadata metadata = new MultimediaFileMetadata(file.getAbsolutePath());
|
||||
|
||||
if (hasVideo) {
|
||||
if (hasAudio) {
|
||||
Assert.assertTrue(metadata.hasAudioAndVideo());
|
||||
Assert.assertTrue(metadata.hasAudio() && metadata.hasVideo());
|
||||
Assert.assertTrue(metadata.getAudioDecoder().toLowerCase().contains(audioDecoder));
|
||||
} else {
|
||||
Assert.assertTrue(metadata.hasVideo());
|
||||
|
|
|
@ -18,148 +18,151 @@
|
|||
package io.openvidu.test.e2e.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
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;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
public class MultimediaFileMetadata {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MultimediaFileMetadata.class);
|
||||
|
||||
private File f;
|
||||
private MultimediaInfo mediaInfo;
|
||||
private AudioInfo audioInfo;
|
||||
private VideoInfo videoInfo;
|
||||
private VideoSize videoSize;
|
||||
private JsonObject json;
|
||||
private JsonObject formatJson;
|
||||
private JsonObject audioStreamJson;
|
||||
private JsonObject videoStreamJson;
|
||||
|
||||
public MultimediaFileMetadata(File f) {
|
||||
this.f = f;
|
||||
}
|
||||
private double duration;
|
||||
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 void processMultimediaFile(int iteration) {
|
||||
try {
|
||||
this.mediaInfo = new MultimediaObject(f).getInfo();
|
||||
this.audioInfo = mediaInfo.getAudio();
|
||||
this.videoInfo = mediaInfo.getVideo();
|
||||
if (videoInfo != null) {
|
||||
this.videoSize = videoInfo.getSize();
|
||||
}
|
||||
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 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();
|
||||
}
|
||||
|
||||
if (this.hasVideo) {
|
||||
this.videoDecoder = this.videoStreamJson.get("codec_name").getAsString();
|
||||
this.videoWidth = this.videoStreamJson.get("width").getAsInt();
|
||||
this.videoHeight = this.videoStreamJson.get("height").getAsInt();
|
||||
|
||||
String frameRate = this.videoStreamJson.get("r_frame_rate").getAsString();
|
||||
String[] frameRateParts = frameRate.split("/");
|
||||
this.framerate = Integer.parseInt(frameRateParts[0]) / Integer.parseInt(frameRateParts[1]);
|
||||
}
|
||||
|
||||
log.info("Media metadata for {}: {}", fileAbsolutePath, this.toString());
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
return mediaInfo.getDuration();
|
||||
public double getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public String getFormat(String format) {
|
||||
return mediaInfo.getFormat();
|
||||
public String getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
public long getBitrate() {
|
||||
return bitrate;
|
||||
}
|
||||
|
||||
public boolean hasAudio() {
|
||||
return audioInfo != null;
|
||||
return hasAudio;
|
||||
}
|
||||
|
||||
public boolean hasVideo() {
|
||||
return videoInfo != null;
|
||||
return hasVideo;
|
||||
}
|
||||
|
||||
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 long getAudioSampleRate() {
|
||||
return audioSampleRate;
|
||||
}
|
||||
|
||||
public String getAudioDecoder() {
|
||||
return audioInfo.getDecoder();
|
||||
return audioDecoder;
|
||||
}
|
||||
|
||||
public String getVideoDecoder() {
|
||||
return videoInfo.getDecoder();
|
||||
return videoDecoder;
|
||||
}
|
||||
|
||||
public Integer getVideoWidth() {
|
||||
if (videoSize != null) {
|
||||
return videoSize.getWidth();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
public int getVideoWidth() {
|
||||
return videoWidth;
|
||||
}
|
||||
|
||||
public Integer getVideoHeight() {
|
||||
if (videoSize != null) {
|
||||
return videoSize.getHeight();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
public int getVideoHeight() {
|
||||
return videoHeight;
|
||||
}
|
||||
|
||||
public Integer getFrameRate() {
|
||||
if (videoInfo != null) {
|
||||
return Math.round(videoInfo.getFrameRate());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
public int getFrameRate() {
|
||||
return framerate;
|
||||
}
|
||||
|
||||
private void executeCommand(String command) {
|
||||
log.info("Running bash command '{}'", command);
|
||||
private JsonObject executeFfprobeCommand(String filePath) {
|
||||
log.info("Running ffprobe command on '{}'", filePath);
|
||||
String jsonLines = "";
|
||||
try {
|
||||
String s;
|
||||
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()));
|
||||
while ((s = br.readLine()) != null)
|
||||
log.info("LINE: " + s);
|
||||
while ((s = br.readLine()) != null) {
|
||||
jsonLines += s;
|
||||
}
|
||||
p.waitFor();
|
||||
System.out.println("EXIT VALUE: " + p.exitValue());
|
||||
p.destroy();
|
||||
} catch (IOException | InterruptedException e1) {
|
||||
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