Skip to content
Snippets Groups Projects
Commit bbe6d3a3 authored by srosse's avatar srosse
Browse files

Merge remote-tracking branch 'origin/OpenOLAT_14.0' into OpenOLAT_14.1

parents a8181b44 7b95bfe3
No related branches found
No related tags found
No related merge requests found
......@@ -1884,7 +1884,12 @@
<dependency>
<groupId>org.jcodec</groupId>
<artifactId>jcodec</artifactId>
<version>0.1.6-3</version>
<version>0.2.3</version>
</dependency>
<dependency>
<groupId>org.jcodec</groupId>
<artifactId>jcodec-javase</artifactId>
<version>0.2.3</version>
</dependency>
<dependency>
<groupId>org.mnode.ical4j</groupId>
......
......@@ -28,17 +28,19 @@ import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;
import org.apache.logging.log4j.Logger;
import org.jcodec.api.FrameGrab;
import org.jcodec.common.FileChannelWrapper;
import org.jcodec.common.Codec;
import org.jcodec.common.io.FileChannelWrapper;
import org.jcodec.containers.mp4.boxes.MovieBox;
import org.jcodec.containers.mp4.demuxer.MP4Demuxer;
import org.jcodec.scale.AWTUtil;
import org.olat.core.commons.services.image.Size;
import org.olat.core.commons.services.image.spi.ImageHelperImpl;
import org.olat.core.commons.services.thumbnail.CannotGenerateThumbnailException;
import org.olat.core.commons.services.thumbnail.FinalSize;
import org.olat.core.commons.services.thumbnail.ThumbnailSPI;
import org.olat.core.commons.services.video.spi.FLVParser;
import org.apache.logging.log4j.Logger;
import org.olat.core.logging.Tracing;
import org.olat.core.util.FileUtils;
import org.olat.core.util.WorkThreadInformations;
......@@ -59,18 +61,18 @@ public class MovieServiceImpl implements MovieService, ThumbnailSPI {
private static final Logger log = Tracing.createLoggerFor(MovieServiceImpl.class);
private static final List<String> extensions = new ArrayList<>();
private static final List<String> fourCCs = new ArrayList<>();
private static final List<Codec> supportedCodecs = new ArrayList<>();
static {
// supported file extensions
extensions.add("mp4");
extensions.add("m4v");
extensions.add("mov");
// supported fourCC for H264 codec
fourCCs.add("avc1");
fourCCs.add("davc");
fourCCs.add("h264");
fourCCs.add("x264");
fourCCs.add("vssh");
supportedCodecs.add(Codec.codecByFourcc("avc1"));
supportedCodecs.add(Codec.codecByFourcc("davc"));
supportedCodecs.add(Codec.codecByFourcc("h264"));
supportedCodecs.add(Codec.codecByFourcc("x264"));
supportedCodecs.add(Codec.codecByFourcc("vssh"));
}
......@@ -96,9 +98,10 @@ public class MovieServiceImpl implements MovieService, ThumbnailSPI {
if(extensions.contains(suffix)) {
try(RandomAccessFile accessFile = new RandomAccessFile(file, "r");
FileChannel ch = accessFile.getChannel();
FileChannelWrapper in = new FileChannelWrapper(ch)) {
FileChannelWrapper in = new FileChannelWrapper(ch);
MP4Demuxer demuxer1 = MP4Demuxer.createMP4Demuxer(in)) {
MP4Demuxer demuxer1 = new MP4Demuxer(in);
org.jcodec.common.model.Size size = demuxer1.getMovie().getDisplaySize();
// Case 1: standard case, get dimension from movie
int w = size.getWidth();
......@@ -117,7 +120,7 @@ public class MovieServiceImpl implements MovieService, ThumbnailSPI {
// flag of the movie. Those mp4 guys are really
// secretive folks, did not find any documentation about
// this. Best guess.
org.jcodec.common.model.Size size2 = demuxer1.getVideoTrack().getBox().getCodedSize();
org.jcodec.common.model.Size size2 = demuxer1.getVideoTrack().getMeta().getVideoCodecMeta().getSize();
w = size2.getHeight();
h = size2.getWidth();
} catch(Exception e) {
......@@ -161,9 +164,9 @@ public class MovieServiceImpl implements MovieService, ThumbnailSPI {
if(extensions.contains(suffix)) {
try(RandomAccessFile accessFile = new RandomAccessFile(file, "r");
FileChannel ch = accessFile.getChannel();
FileChannelWrapper in = new FileChannelWrapper(ch)) {
MP4Demuxer demuxer1 = new MP4Demuxer(in);
FileChannelWrapper in = new FileChannelWrapper(ch);
MP4Demuxer demuxer1 = MP4Demuxer.createMP4Demuxer(in)) {
MovieBox movie = demuxer1.getMovie();
long duration = movie.getDuration();
int timescale = movie.getTimescale();
......@@ -196,10 +199,9 @@ public class MovieServiceImpl implements MovieService, ThumbnailSPI {
if(extensions.contains(suffix)) {
try(RandomAccessFile accessFile = new RandomAccessFile(file, "r");
FileChannel ch = accessFile.getChannel();
FileChannelWrapper in = new FileChannelWrapper(ch)) {
MP4Demuxer demuxer1 = new MP4Demuxer(in);
return demuxer1.getVideoTrack().getFrameCount();
FileChannelWrapper in = new FileChannelWrapper(ch);
MP4Demuxer demuxer1 = MP4Demuxer.createMP4Demuxer(in)) {
return demuxer1.getVideoTrack().getMeta().getTotalFrames();
} catch (Exception | AssertionError e) {
log.error("Cannot extract num. of frames of: " + media, e);
}
......@@ -226,12 +228,12 @@ public class MovieServiceImpl implements MovieService, ThumbnailSPI {
FileChannel ch = accessFile.getChannel();
FileChannelWrapper in = new FileChannelWrapper(ch)) {
MP4Demuxer demuxer1 = new MP4Demuxer(in);
String fourCC = demuxer1.getVideoTrack().getFourcc();
if (fourCCs.contains(fourCC.toLowerCase())) {
MP4Demuxer demuxer1 = MP4Demuxer.createMP4Demuxer(in);
Codec codec = demuxer1.getVideoTrack().getMeta().getCodec();
if (supportedCodecs.contains(codec)) {
return true;
}
log.info("Movie file::" + fileName + " has correct suffix::" + suffix + " but fourCC::" + fourCC + " not in our list of supported codecs.");
log.info("Movie file::" + fileName + " has correct suffix::" + suffix + " but fourCC::" + codec + " not in our list of supported codecs.");
} catch (Exception | Error e) {
// anticipated exception, is not an mp4 file
}
......@@ -251,7 +253,7 @@ public class MovieServiceImpl implements MovieService, ThumbnailSPI {
File baseFile = ((LocalFileImpl)file).getBasefile();
File scaledImage = ((LocalFileImpl)thumbnailFile).getBasefile();
BufferedImage frame = FrameGrab.getFrame(baseFile, 20);
BufferedImage frame = AWTUtil.toBufferedImage(FrameGrab.getFrameFromFile(baseFile, 20));
Size scaledSize = ImageHelperImpl.calcScaledSize(frame, maxWidth, maxHeight);
if(ImageHelperImpl.writeTo(frame, scaledImage, scaledSize, "jpeg")) {
size = new FinalSize(scaledSize.getWidth(), scaledSize.getHeight());
......
......@@ -31,8 +31,8 @@ import java.util.List;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.Logger;
import org.jcodec.common.IOUtils;
import org.olat.core.CoreSpringFactory;
import org.olat.core.gui.render.StringOutput;
import org.olat.core.logging.Tracing;
......
......@@ -28,9 +28,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.math.RoundingMode;
import java.nio.channels.FileChannel;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
......@@ -51,7 +49,9 @@ import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.logging.log4j.Logger;
import org.jcodec.api.FrameGrab;
import org.jcodec.common.FileChannelWrapper;
import org.jcodec.common.io.FileChannelWrapper;
import org.jcodec.common.io.NIOUtils;
import org.jcodec.scale.AWTUtil;
import org.olat.core.commons.services.image.Crop;
import org.olat.core.commons.services.image.ImageService;
import org.olat.core.commons.services.image.Size;
......@@ -280,19 +280,16 @@ public class VideoManagerImpl implements VideoManager {
public boolean getFrame(VFSLeaf video, int frameNumber, VFSLeaf frame) {
File videoFile = ((LocalFileImpl)video).getBasefile();
try (RandomAccessFile randomAccessFile = new RandomAccessFile(videoFile, "r")) {
FileChannel ch = randomAccessFile.getChannel();
FileChannelWrapper in = new FileChannelWrapper(ch);
FrameGrab frameGrab = new FrameGrab(in).seekToFrameSloppy(frameNumber);
try (FileChannelWrapper in = NIOUtils.readableChannel(videoFile)) {
FrameGrab frameGrab = FrameGrab.createFrameGrab(in).seekToFrameSloppy(frameNumber);
OutputStream frameOutputStream = frame.getOutputStream(false);
BufferedImage bufImg = frameGrab.getFrame();
BufferedImage bufImg = AWTUtil.toBufferedImage(frameGrab.getNativeFrame());
ImageIO.write(bufImg, "JPG", frameOutputStream);
// close everything to prevent resource leaks
frameOutputStream.close();
in.close();
ch.close();
return true;
} catch (Exception | AssertionError e) {
......@@ -307,14 +304,11 @@ public class VideoManagerImpl implements VideoManager {
BufferedImage bufImg = null;
boolean imgBlack = true;
int countBlack = 0;
try (RandomAccessFile randomAccessFile = new RandomAccessFile(videoFile, "r")) {
try (FileChannelWrapper in = NIOUtils.readableChannel(videoFile)) {
OutputStream frameOutputStream = frame.getOutputStream(false);
FileChannel ch = randomAccessFile.getChannel();
FileChannelWrapper in = new FileChannelWrapper(ch);
FrameGrab frameGrab = new FrameGrab(in).seekToFrameSloppy(frameNumber);
FrameGrab frameGrab = FrameGrab.createFrameGrab(in).seekToFrameSloppy(frameNumber);
bufImg = frameGrab.getFrame();
bufImg = AWTUtil.toBufferedImage(frameGrab.getNativeFrame());
int xmin = bufImg.getMinX();
int ymin = bufImg.getMinY();
......@@ -347,7 +341,6 @@ public class VideoManagerImpl implements VideoManager {
// close everything to prevent resource leaks
frameOutputStream.close();
in.close();
ch.close();
return imgBlack;
} catch (Exception | AssertionError e) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment