From 415f1774ac8c8fa371e39895aae5ddfad5efaeac Mon Sep 17 00:00:00 2001 From: gnaegi <none@none> Date: Thu, 19 May 2016 14:55:30 +0200 Subject: [PATCH] OO-725 make sure only supported video files are recognized as video resources --- .../commons/services/video/MovieService.java | 8 ++++ .../services/video/MovieServiceImpl.java | 47 +++++++++++++++++-- .../fileresource/types/VideoFileResource.java | 14 ++++-- 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/olat/core/commons/services/video/MovieService.java b/src/main/java/org/olat/core/commons/services/video/MovieService.java index b22d0a5c943..88169d176eb 100644 --- a/src/main/java/org/olat/core/commons/services/video/MovieService.java +++ b/src/main/java/org/olat/core/commons/services/video/MovieService.java @@ -49,4 +49,12 @@ public interface MovieService { */ public long getDuration(VFSLeaf media, String suffix); + /** + * Checks if a file is really an mp4 file we can handle + * @param media + * @param fileName + * @return + */ + public boolean isMP4(VFSLeaf media, String fileName); + } diff --git a/src/main/java/org/olat/core/commons/services/video/MovieServiceImpl.java b/src/main/java/org/olat/core/commons/services/video/MovieServiceImpl.java index ee7d9034486..521fa596a53 100644 --- a/src/main/java/org/olat/core/commons/services/video/MovieServiceImpl.java +++ b/src/main/java/org/olat/core/commons/services/video/MovieServiceImpl.java @@ -40,6 +40,7 @@ import org.olat.core.commons.services.thumbnail.ThumbnailSPI; import org.olat.core.commons.services.video.spi.FLVParser; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.olat.core.util.FileUtils; import org.olat.core.util.WorkThreadInformations; import org.olat.core.util.vfs.LocalFileImpl; import org.olat.core.util.vfs.VFSLeaf; @@ -58,12 +59,22 @@ public class MovieServiceImpl implements MovieService, ThumbnailSPI { private static final OLog log = Tracing.createLoggerFor(MovieServiceImpl.class); private static final List<String> extensions = new ArrayList<>(); + private static final List<String> fourCCs = new ArrayList<>(); static { + // supported file extensions extensions.add("mp4"); - extensions.add("mov"); 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"); } + + @Override public List<String> getExtensions() { return extensions; @@ -82,7 +93,7 @@ public class MovieServiceImpl implements MovieService, ThumbnailSPI { return null; } - if(suffix.equals("mp4") || suffix.equals("m4v")) { + if(extensions.contains(suffix)) { try(RandomAccessFile accessFile = new RandomAccessFile(file, "r")) { FileChannel ch = accessFile.getChannel(); FileChannelWrapper in = new FileChannelWrapper(ch); @@ -124,7 +135,7 @@ public class MovieServiceImpl implements MovieService, ThumbnailSPI { return -1; } - if(suffix.equals("mp4") || suffix.equals("m4v")) { + if(extensions.contains(suffix)) { try(RandomAccessFile accessFile = new RandomAccessFile(file, "r")) { FileChannel ch = accessFile.getChannel(); FileChannelWrapper in = new FileChannelWrapper(ch); @@ -145,6 +156,36 @@ public class MovieServiceImpl implements MovieService, ThumbnailSPI { return -1; } + @Override + public boolean isMP4(VFSLeaf media, String fileName) { + File file = null; + if(media instanceof VFSCPNamedItem) { + media = ((VFSCPNamedItem)media).getDelegate(); + } + if(media instanceof LocalFileImpl) { + file = ((LocalFileImpl)media).getBasefile(); + } + if(file == null) { + return false; + } + String suffix = FileUtils.getFileSuffix(fileName); + 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); + String fourCC = demuxer1.getVideoTrack().getFourcc(); + if (fourCCs.contains(fourCC)) { + return true; + } + log.info("Movie file::" + fileName + " has correct suffix::" + suffix + " but fourCC::" + fourCC + " not in our list of supported codecs."); + } catch (Exception | Error e) { + // anticipated exception, is not an mp4 file + } + } + return false; + } + @Override public FinalSize generateThumbnail(VFSLeaf file, VFSLeaf thumbnailFile, int maxWidth, int maxHeight, boolean fill) diff --git a/src/main/java/org/olat/fileresource/types/VideoFileResource.java b/src/main/java/org/olat/fileresource/types/VideoFileResource.java index d763f4132ff..6d43a14cc50 100644 --- a/src/main/java/org/olat/fileresource/types/VideoFileResource.java +++ b/src/main/java/org/olat/fileresource/types/VideoFileResource.java @@ -20,8 +20,12 @@ package org.olat.fileresource.types; import java.io.File; +import java.util.Date; import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.video.MovieService; +import org.olat.core.util.Formatter; +import org.olat.core.util.vfs.LocalFileImpl; import org.olat.modules.video.VideoManager; import org.olat.modules.video.VideoModule; @@ -35,6 +39,7 @@ public class VideoFileResource extends FileResource { private static VideoModule videomodule = CoreSpringFactory.getImpl(VideoModule.class); private static VideoManager videoManager = CoreSpringFactory.getImpl(VideoManager.class); + private static MovieService movieService = CoreSpringFactory.getImpl(MovieService.class); /** * Movie file resource identifier. @@ -57,11 +62,12 @@ public class VideoFileResource extends FileResource { if (!videomodule.isEnabled()) { return; } - fileName = fileName.toLowerCase(); - if (fileName.endsWith(".mp4")|| fileName.endsWith(".mov")) { - // accept raw mp4 files - // accept also mov files as iOS saves mp4 movis as mov + // accept raw mp4 files + // accept also mov files as iOS saves mp4 movis as mov, but check if the file can be parsed as mp4 file + boolean isMP4 = movieService.isMP4(new LocalFileImpl(file), fileName); + if (isMP4) { eval.setValid(true); + eval.setDisplayname(fileName + " - " + Formatter.formatShortDateFilesystem(new Date())); } else if (fileName.endsWith(".zip")) { // check if zip contains an exported video resource videoManager.validateVideoExportArchive(file, eval); -- GitLab