Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
de.mklinger.qetcher.liferay.client.impl.VideoProcessorImpl Maven / Gradle / Ivy
/*
* Copyright 2013-present mklinger GmbH - http://www.mklinger.de
*
* All rights reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of mklinger GmbH and its suppliers, if any.
* The intellectual and technical concepts contained herein are
* proprietary to mklinger GmbH and its suppliers and are protected
* by trade secret or copyright law. Dissemination of this
* information or reproduction of this material is strictly forbidden
* unless prior written permission is obtained from mklinger GmbH.
*/
package de.mklinger.qetcher.liferay.client.impl;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.liferay.portal.kernel.image.ImageBag;
import com.liferay.portal.kernel.image.ImageToolUtil;
import com.liferay.portal.kernel.lar.PortletDataContext;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.DestinationNames;
import com.liferay.portal.kernel.repository.model.FileEntry;
import com.liferay.portal.kernel.repository.model.FileVersion;
import com.liferay.portal.kernel.util.FileUtil;
import com.liferay.portal.kernel.util.StreamUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.xml.Element;
import com.liferay.portal.repository.liferayrepository.model.LiferayFileVersion;
import com.liferay.portal.util.PropsValues;
import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
import com.liferay.portlet.documentlibrary.util.DLUtil;
import com.liferay.portlet.documentlibrary.util.VideoProcessor;
import de.mklinger.qetcher.liferay.client.impl.mediatype.MediaTypesService;
/**
* @author Marc Klinger - mklinger[at]mklinger[dot]de
*/
public class VideoProcessorImpl extends MediaRegistryProcessor implements VideoProcessor {
// private static final String PARAM_PRESET_HTML5VIDEO = "preset-html5video";
private static final Logger LOG = LoggerFactory.getLogger(VideoProcessorImpl.class);
public VideoProcessorImpl() {
super("video");
}
private void _generateVideoQetcher(final FileVersion fileVersion, final File srcFile, final File destFile, final String containerType) throws Exception {
if (hasPreview(fileVersion, containerType)) {
return;
}
final String sourceExtension = getExtension(fileVersion);
if (sourceExtension == null) {
return;
}
try (FileInputStream in = new FileInputStream(srcFile)) {
try (FileOutputStream out = new FileOutputStream(destFile)) {
if (sourceExtension.equals(containerType)) {
LOG.info("Using original file as preview for type {}", sourceExtension);
IOUtils.copy(in, out);
} else {
LOG.debug("Generating video preview from {} to {}", sourceExtension, containerType);
QetcherLiferayServiceUtil.convert(in, out, sourceExtension, containerType, getVideoTargetParameters(containerType), getReferer(fileVersion));
LOG.debug("Generating video preview done.");
}
}
}
addFileToStore(
fileVersion.getCompanyId(), PREVIEW_PATH,
getPreviewFilePath(fileVersion, containerType), destFile);
}
private Map getVideoTargetParameters(final String containerType) {
// if ("ogv".equals(containerType) || "mp4".equals(containerType) || "webm".equals(containerType)) {
// // use preset PARAM_PRESET_HTML5VIDEO
// LOG.info("Using HTML5 video presets");
// return Collections.singletonMap(PARAM_PRESET_HTML5VIDEO, String.valueOf(true));
// }
return null;
}
private void _generateThumbnailQetcher(final FileVersion fileVersion, final File file, final int height, final int width) throws Exception {
final String tempFileId = DLUtil.getTempFileId(fileVersion.getFileEntryId(), fileVersion.getVersion());
final File thumbnailTempFile = getThumbnailTempFile(tempFileId);
try {
final String sourceExtension = getExtension(fileVersion);
if (sourceExtension == null) {
return;
}
LOG.debug("Generating video thumbnail from {} to {}", sourceExtension, THUMBNAIL_TYPE);
// TODO PropsValues.DL_FILE_ENTRY_THUMBNAIL_VIDEO_FRAME_PERCENTAGE
try (FileInputStream in = new FileInputStream(file)) {
try (FileOutputStream out = new FileOutputStream(thumbnailTempFile)) {
QetcherLiferayServiceUtil.convert(in, out, sourceExtension, THUMBNAIL_TYPE, null, getReferer(fileVersion));
}
}
LOG.debug("Generating video thumbnail done.");
storeThumbnailImages(fileVersion, thumbnailTempFile);
} finally {
FileUtil.delete(thumbnailTempFile);
}
}
private String getReferer(final FileVersion fileVersion) {
return "companyId=" + fileVersion.getCompanyId() + ",fileEntryId=" + fileVersion.getFileEntryId();
}
private String getExtension(final FileVersion fileVersion) {
final String mimeTypeString = fileVersion.getMimeType();
LOG.debug("Original source file mime type: {}", mimeTypeString);
LOG.debug("Original source file extension: {}", fileVersion.getExtension());
final String sourceExtension = MediaTypesService.getInstance().getFileExtensionByMimeType(mimeTypeString)
.orElse(fileVersion.getExtension());
if (sourceExtension == null || sourceExtension.isEmpty()) {
LOG.warn("Could not determine source file extension for file entry {}", fileVersion.getFileEntryId());
return null;
}
return sourceExtension;
}
// ---------
@Override
public void afterPropertiesSet() {
FileUtil.mkdirs(PREVIEW_TMP_PATH);
FileUtil.mkdirs(THUMBNAIL_TMP_PATH);
}
@Override
public void generateVideo(final FileVersion sourceFileVersion, final FileVersion destinationFileVersion) throws Exception {
_generateVideo(sourceFileVersion, destinationFileVersion);
}
@Override
public InputStream getPreviewAsStream(final FileVersion fileVersion, final String type) throws Exception {
return doGetPreviewAsStream(fileVersion, type);
}
@Override
public long getPreviewFileSize(final FileVersion fileVersion, final String type) throws Exception {
return doGetPreviewFileSize(fileVersion, type);
}
@Override
public InputStream getThumbnailAsStream(final FileVersion fileVersion, final int index) throws Exception {
return doGetThumbnailAsStream(fileVersion, index);
}
@Override
public long getThumbnailFileSize(final FileVersion fileVersion, final int index) throws Exception {
return doGetThumbnailFileSize(fileVersion, index);
}
@Override
public Set getVideoMimeTypes() {
return getSupportedSourceMimeTypes();
}
@Override
public boolean hasVideo(final FileVersion fileVersion) {
boolean hasVideo = false;
try {
hasVideo = _hasVideo(fileVersion);
if (!hasVideo && isSupported(fileVersion)) {
_queueGeneration(null, fileVersion);
}
}
catch (final Exception e) {
_log.error(e, e);
}
return hasVideo;
}
@Override
public boolean isSupported(final String mimeType) {
if (Validator.isNull(mimeType)) {
return false;
}
return getVideoMimeTypes().contains(mimeType);
}
@Override
public boolean isVideoSupported(final FileVersion fileVersion) {
return isSupported(fileVersion);
}
@Override
public boolean isVideoSupported(final String mimeType) {
return isSupported(mimeType);
}
@Override
public void trigger(final FileVersion sourceFileVersion, final FileVersion destinationFileVersion) {
super.trigger(sourceFileVersion, destinationFileVersion);
_queueGeneration(sourceFileVersion, destinationFileVersion);
}
@Override
protected void doExportGeneratedFiles(final PortletDataContext portletDataContext, final FileEntry fileEntry, final Element fileEntryElement) throws Exception {
exportThumbnails(portletDataContext, fileEntry, fileEntryElement, "video");
exportPreviews(portletDataContext, fileEntry, fileEntryElement);
}
@Override
protected void doImportGeneratedFiles(final PortletDataContext portletDataContext, final FileEntry fileEntry, final FileEntry importedFileEntry, final Element fileEntryElement) throws Exception {
importThumbnails(portletDataContext, fileEntry, importedFileEntry, fileEntryElement, "video");
importPreviews(portletDataContext, fileEntry, importedFileEntry, fileEntryElement);
}
protected void exportPreviews(final PortletDataContext portletDataContext, final FileEntry fileEntry, final Element fileEntryElement) throws Exception {
final FileVersion fileVersion = fileEntry.getFileVersion();
if (!isSupported(fileVersion) || !hasPreviews(fileVersion)) {
return;
}
if (!portletDataContext.isPerformDirectBinaryImport()) {
for (final String previewType : _PREVIEW_TYPES) {
exportPreview(portletDataContext, fileEntry, fileEntryElement, "video", previewType);
}
}
}
@Override
protected List getFileVersionIds() {
return _fileVersionIds;
}
@Override
protected String getPreviewType(final FileVersion fileVersion) {
return _PREVIEW_TYPES[0];
}
@Override
protected String[] getPreviewTypes() {
return _PREVIEW_TYPES;
}
@Override
protected String getThumbnailType(final FileVersion fileVersion) {
return THUMBNAIL_TYPE;
}
protected void importPreviews(final PortletDataContext portletDataContext, final FileEntry fileEntry, final FileEntry importedFileEntry, final Element fileEntryElement) throws Exception {
for (final String previewType : _PREVIEW_TYPES) {
importPreview(portletDataContext, fileEntry, importedFileEntry, fileEntryElement, "video", previewType);
}
}
@Override
protected void storeThumbnailImages(final FileVersion fileVersion, final File file) throws Exception {
if (!hasThumbnail(fileVersion, THUMBNAIL_INDEX_DEFAULT)) {
addFileToStore(
fileVersion.getCompanyId(), THUMBNAIL_PATH,
getThumbnailFilePath(fileVersion, THUMBNAIL_INDEX_DEFAULT),
file);
}
if (isThumbnailEnabled(THUMBNAIL_INDEX_CUSTOM_1) || isThumbnailEnabled(THUMBNAIL_INDEX_CUSTOM_2)) {
final ImageBag imageBag = ImageToolUtil.read(file);
final RenderedImage renderedImage = imageBag.getRenderedImage();
storeThumbnailImage(fileVersion, renderedImage, THUMBNAIL_INDEX_CUSTOM_1);
storeThumbnailImage(fileVersion, renderedImage, THUMBNAIL_INDEX_CUSTOM_2);
}
}
private void _generateVideo(final FileVersion sourceFileVersion, final FileVersion destinationFileVersion) throws Exception {
if (_hasVideo(destinationFileVersion)) {
return;
}
InputStream inputStream = null;
File videoTempFile = null;
try {
if (sourceFileVersion != null) {
copy(sourceFileVersion, destinationFileVersion);
return;
}
File file = null;
if (!hasPreviews(destinationFileVersion) || !hasThumbnails(destinationFileVersion)) {
if (destinationFileVersion instanceof LiferayFileVersion) {
try {
final LiferayFileVersion liferayFileVersion = (LiferayFileVersion)destinationFileVersion;
file = liferayFileVersion.getFile(false);
} catch (final UnsupportedOperationException uoe) {
}
}
if (file == null) {
inputStream = destinationFileVersion.getContentStream(false);
videoTempFile = FileUtil.createTempFile(destinationFileVersion.getExtension());
FileUtil.write(videoTempFile, inputStream);
file = videoTempFile;
}
}
if (!hasPreviews(destinationFileVersion)) {
final String tempFileId = DLUtil.getTempFileId(
destinationFileVersion.getFileEntryId(),
destinationFileVersion.getVersion());
for (final String previewType : _PREVIEW_TYPES) {
final File previewTempFile = getPreviewTempFile(tempFileId, previewType);
try {
_generateVideoQetcher(destinationFileVersion, file, previewTempFile, previewType);
} catch (final Exception e) {
_log.error(e, e);
} finally {
FileUtil.delete(previewTempFile);
}
}
}
if (!hasThumbnails(destinationFileVersion)) {
try {
_generateThumbnailQetcher(
destinationFileVersion, file,
PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_HEIGHT,
PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_WIDTH);
}
catch (final Exception e) {
_log.error(e, e);
}
}
} catch (final NoSuchFileEntryException nsfee) {
} finally {
StreamUtil.cleanUp(inputStream);
_fileVersionIds.remove(destinationFileVersion.getFileVersionId());
FileUtil.delete(videoTempFile);
}
}
private boolean _hasVideo(final FileVersion fileVersion) throws Exception {
if (!isSupported(fileVersion)) {
return false;
}
return hasPreviews(fileVersion) && hasThumbnails(fileVersion);
}
private void _queueGeneration(final FileVersion sourceFileVersion, final FileVersion destinationFileVersion) {
if (_fileVersionIds.contains(destinationFileVersion.getFileVersionId()) || !isSupported(destinationFileVersion)) {
return;
}
_fileVersionIds.add(destinationFileVersion.getFileVersionId());
sendGenerationMessage(
DestinationNames.DOCUMENT_LIBRARY_VIDEO_PROCESSOR,
sourceFileVersion, destinationFileVersion);
}
private static final String[] _PREVIEW_TYPES = PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_CONTAINERS;
private static Log _log = LogFactoryUtil.getLog(VideoProcessorImpl.class);
private final List _fileVersionIds = new Vector<>();
}