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

OO-4330: write more metadata of videos during import

parent e8a2c9c8
No related branches found
No related tags found
No related merge requests found
......@@ -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
}
......
......@@ -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
......
......@@ -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) {
......
......@@ -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;
......
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