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 36d51ec0fc8ac142f606a2bc09ba977bfad230c2..6d85c13da70a3f62b8064bb009b02a131b3821da 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 @@ -31,6 +31,7 @@ import java.util.List; import org.apache.logging.log4j.Logger; import org.jcodec.api.FrameGrab; import org.jcodec.common.Codec; +import org.jcodec.common.VideoCodecMeta; import org.jcodec.common.io.FileChannelWrapper; import org.jcodec.containers.mp4.boxes.MovieBox; import org.jcodec.containers.mp4.demuxer.MP4Demuxer; @@ -120,11 +121,12 @@ 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().getMeta().getVideoCodecMeta().getSize(); + VideoCodecMeta meta = demuxer1.getVideoTrack().getMeta().getVideoCodecMeta(); + org.jcodec.common.model.Size size2 = meta.getSize(); w = size2.getHeight(); - h = size2.getWidth(); + h = size2.getWidth(); } catch(Exception e) { - log.debug("can not get size from box " + e.getMessage()); + log.debug("can not get size from box {}", e.getMessage()); } } return new Size(w, h, false); @@ -226,14 +228,13 @@ 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 = MP4Demuxer.createMP4Demuxer(in); + FileChannelWrapper in = new FileChannelWrapper(ch); + 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::" + codec + " not in our list of supported codecs."); + log.info("Movie file:: {} has correct suffix:: {} but fourCC:: {} not in our list of supported codecs.", fileName, suffix, codec); } catch (Exception | Error e) { // anticipated exception, is not an mp4 file } diff --git a/src/main/java/org/olat/modules/video/VideoManager.java b/src/main/java/org/olat/modules/video/VideoManager.java index d353d5e6d0ef367b94c5b0f62cb0e7edb449cc55..40278a8eab445807180c44ff005904b108c037ac 100644 --- a/src/main/java/org/olat/modules/video/VideoManager.java +++ b/src/main/java/org/olat/modules/video/VideoManager.java @@ -249,7 +249,7 @@ public interface VideoManager { * The repository entry that represents the video in the repository * @param masterVideo The video file to be added to the repository. Must be an mp4 file. */ - public boolean importFromMasterFile(RepositoryEntry repoEntry, VFSLeaf masterVideo); + public VideoMeta importFromMasterFile(RepositoryEntry repoEntry, VFSLeaf masterVideo); /** * Import the given export archive to the resource on disk @@ -260,7 +260,7 @@ public interface VideoManager { * The archive to be added to the repository. The archive must be * created by the video export feature. */ - public boolean importFromExportArchive(RepositoryEntry repoEntry, VFSLeaf exportArchive); + public VideoMeta importFromExportArchive(RepositoryEntry repoEntry, VFSLeaf exportArchive); /** * Update video transcoding diff --git a/src/main/java/org/olat/modules/video/manager/VideoManagerImpl.java b/src/main/java/org/olat/modules/video/manager/VideoManagerImpl.java index 1f16191ee10a485a5188fb5aeef24fed979fadf2..401a79e554007ce89710248e3d2e75ea9fbfa2f2 100644 --- a/src/main/java/org/olat/modules/video/manager/VideoManagerImpl.java +++ b/src/main/java/org/olat/modules/video/manager/VideoManagerImpl.java @@ -52,6 +52,7 @@ import org.jcodec.api.FrameGrab; import org.jcodec.common.io.FileChannelWrapper; import org.jcodec.common.io.NIOUtils; import org.jcodec.scale.AWTUtil; +import org.olat.core.commons.persistence.DB; import org.olat.core.commons.services.image.Crop; import org.olat.core.commons.services.image.ImageService; import org.olat.core.commons.services.image.Size; @@ -134,6 +135,8 @@ public class VideoManagerImpl implements VideoManager { private final JobKey videoJobKey = new JobKey("videoTranscodingJobDetail", Scheduler.DEFAULT_GROUP); + @Autowired + private DB dbInstance; @Autowired private MovieService movieService; @Autowired @@ -658,7 +661,7 @@ public class VideoManagerImpl implements VideoManager { } @Override - public boolean importFromMasterFile(RepositoryEntry repoEntry, VFSLeaf masterVideo) { + public VideoMeta importFromMasterFile(RepositoryEntry repoEntry, VFSLeaf masterVideo) { OLATResource videoResource = repoEntry.getOlatResource(); // 1) copy master video to final destination with standard name @@ -681,8 +684,66 @@ public class VideoManagerImpl implements VideoManager { if (posterImage != null) { repositoryManager.setImage(posterImage, repoEntry); } - - return true; + + VideoMeta meta = null; + if(targetFile != null) { + createVideoMetadata(repoEntry, targetFile.getSize(), targetFile.getName()); + dbInstance.commit(); + meta = updateVideoMetadata(videoResource, targetFile); + } + return meta; + } + + @Override + public VideoMeta importFromExportArchive(RepositoryEntry repoEntry, VFSLeaf exportArchive) { + OLATResource videoResource = repoEntry.getOlatResource(); + // 1) unzip archive + VFSContainer baseContainer= FileResourceManager.getInstance().getFileResourceRootImpl(videoResource); + ZipUtil.unzip(exportArchive, baseContainer); + exportArchive.delete(); + + // 2) update metadata from the repo entry export + VideoMeta meta = null; + LocalFolderImpl repoentryContainer = (LocalFolderImpl) baseContainer.resolve(DIRNAME_REPOENTRY); + if (repoentryContainer != null) { + // repo metadata + RepositoryEntryImportExport importExport = new RepositoryEntryImportExport(repoentryContainer.getBasefile()); + importExport.setRepoEntryPropertiesFromImport(repoEntry); + // video metadata + VFSItem videoMetaFile = repoentryContainer.resolve(FILENAME_VIDEO_METADATA_XML); + if(videoMetaFile instanceof VFSLeaf) { + VideoMeta videoMeta = VideoMetaXStream.fromXml((VFSLeaf)videoMetaFile); + meta = videoMetadataDao.copyVideoMetadata(repoEntry, videoMeta); + } + // now delete the import folder, not used anymore + repoentryContainer.delete(); + } + + // 3) Set poster image for repo entry + VFSContainer masterContainer = getMasterContainer(videoResource); + VFSLeaf posterImage = (VFSLeaf)masterContainer.resolve(FILENAME_POSTER_JPG); + if (posterImage != null) { + repositoryManager.setImage(posterImage, repoEntry); + } + + dbInstance.commit(); + + VFSLeaf videoFile = getMasterVideoFile(videoResource); + if(videoFile != null) { + if(meta == null) { + meta = createVideoMetadata(repoEntry, videoFile.getSize(), videoFile.getName()); + dbInstance.commit(); + } else if(meta.getVideoFormat() == null) { + meta = checkUnkownVideoFormat(meta); + dbInstance.commit(); + } + + // check if these are default settings + if(meta != null && meta.getWidth() == 800 && meta.getHeight() == 600) { + meta = updateVideoMetadata(videoResource, videoFile); + } + } + return meta; } @Override @@ -738,7 +799,7 @@ public class VideoManagerImpl implements VideoManager { @Override public VideoMeta checkUnkownVideoFormat(VideoMeta meta) { - if(meta == null || meta.getVideoResource() == null || StringHelper.containsNonWhitespace(meta.getUrl())) return null; + if(meta == null || meta.getVideoResource() == null || StringHelper.containsNonWhitespace(meta.getUrl())) return meta; VFSLeaf video = getMasterVideoFile(meta.getVideoResource()); if(video != null) { @@ -843,39 +904,7 @@ public class VideoManagerImpl implements VideoManager { } } - @Override - public boolean importFromExportArchive(RepositoryEntry repoEntry, VFSLeaf exportArchive) { - OLATResource videoResource = repoEntry.getOlatResource(); - // 1) unzip archive - VFSContainer baseContainer= FileResourceManager.getInstance().getFileResourceRootImpl(videoResource); - ZipUtil.unzip(exportArchive, baseContainer); - exportArchive.delete(); - - // 2) update metadata from the repo entry export - LocalFolderImpl repoentryContainer = (LocalFolderImpl) baseContainer.resolve(DIRNAME_REPOENTRY); - if (repoentryContainer != null) { - // repo metadata - RepositoryEntryImportExport importExport = new RepositoryEntryImportExport(repoentryContainer.getBasefile()); - importExport.setRepoEntryPropertiesFromImport(repoEntry); - // video metadata - VFSItem videoMetaFile = repoentryContainer.resolve(FILENAME_VIDEO_METADATA_XML); - if(videoMetaFile instanceof VFSLeaf) { - VideoMeta videoMeta = VideoMetaXStream.fromXml((VFSLeaf)videoMetaFile); - videoMetadataDao.copyVideoMetadata(repoEntry, videoMeta); - } - // now delete the import folder, not used anymore - repoentryContainer.delete(); - } - - // 3) Set poster image for repo entry - VFSContainer masterContainer = getMasterContainer(videoResource); - VFSLeaf posterImage = (VFSLeaf)masterContainer.resolve(FILENAME_POSTER_JPG); - if (posterImage != null) { - repositoryManager.setImage(posterImage, repoEntry); - } - return true; - } @Override public VideoTranscoding updateVideoTranscoding(VideoTranscoding videoTranscoding) { diff --git a/src/main/java/org/olat/repository/handlers/VideoHandler.java b/src/main/java/org/olat/repository/handlers/VideoHandler.java index f627e55aafac08cacaabcf9877a395ba613cc4e2..8b69955ce4431627933abbebabd861a42d0f0e36 100644 --- a/src/main/java/org/olat/repository/handlers/VideoHandler.java +++ b/src/main/java/org/olat/repository/handlers/VideoHandler.java @@ -157,26 +157,19 @@ public class VideoHandler extends FileHandler { } fileName = fileName.toLowerCase(); VFSLeaf importFile = new LocalFileImpl(file); - long filesize = importFile.getSize(); + VideoMeta videoMeta = null; if (fileName.endsWith(".mp4") || fileName.endsWith(".mov") || fileName.endsWith(".m4v")) { // 2a) import video from raw mp4 master video file - videoManager.importFromMasterFile(repoEntry, importFile); - + videoMeta = videoManager.importFromMasterFile(repoEntry, importFile); } else if (fileName.endsWith(".zip")) { // 2b) import video from archive from another OpenOLAT instance - dbInstance.commit(); - videoManager.importFromExportArchive(repoEntry, importFile); - dbInstance.commit(); - } - // 3) Persist Meta data - VideoMeta videoMeta = videoManager.getVideoMetadata(resource); - if(videoMeta == null) { - videoMeta =videoManager.createVideoMetadata(repoEntry, filesize, fileName); + videoMeta = videoManager.importFromExportArchive(repoEntry, importFile); } dbInstance.commit(); + // 4) start transcoding process if enabled - if(!StringHelper.containsNonWhitespace(videoMeta.getUrl())) { + if(videoMeta != null && !StringHelper.containsNonWhitespace(videoMeta.getUrl())) { videoManager.startTranscodingProcessIfEnabled(resource); } return repoEntry;