001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl-2.1.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Thomas Roger <troger@nuxeo.com> 016 */ 017 018package org.nuxeo.ecm.platform.video.convert; 019 020import static org.nuxeo.ecm.platform.video.convert.Constants.INPUT_FILE_PATH_PARAMETER; 021import static org.nuxeo.ecm.platform.video.convert.Constants.OUTPUT_FILE_NAME_PARAMETER; 022import static org.nuxeo.ecm.platform.video.convert.Constants.OUTPUT_FILE_PATH_PARAMETER; 023 024import java.io.File; 025import java.io.IOException; 026import java.io.Serializable; 027import java.util.ArrayList; 028import java.util.HashMap; 029import java.util.List; 030import java.util.Map; 031import java.util.UUID; 032 033import org.apache.commons.io.FilenameUtils; 034import org.nuxeo.common.utils.Path; 035import org.nuxeo.ecm.core.api.Blob; 036import org.nuxeo.ecm.core.api.Blobs; 037import org.nuxeo.ecm.core.api.blobholder.BlobHolder; 038import org.nuxeo.ecm.core.api.blobholder.SimpleBlobHolderWithProperties; 039import org.nuxeo.ecm.core.convert.api.ConversionException; 040import org.nuxeo.ecm.platform.commandline.executor.api.CmdParameters; 041import org.nuxeo.ecm.platform.convert.plugins.CommandLineBasedConverter; 042import org.nuxeo.ecm.platform.video.VideoInfo; 043import org.nuxeo.runtime.api.Framework; 044 045/** 046 * Base class for converters doing video conversions. 047 * 048 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a> 049 * @since 5.5 050 */ 051public abstract class BaseVideoConversionConverter extends CommandLineBasedConverter { 052 053 @Override 054 protected Map<String, Blob> getCmdBlobParameters(BlobHolder blobHolder, 055 Map<String, Serializable> stringSerializableMap) throws ConversionException { 056 Map<String, Blob> cmdBlobParams = new HashMap<String, Blob>(); 057 cmdBlobParams.put(INPUT_FILE_PATH_PARAMETER, blobHolder.getBlob()); 058 return cmdBlobParams; 059 } 060 061 @Override 062 protected Map<String, String> getCmdStringParameters(BlobHolder blobHolder, Map<String, Serializable> parameters) 063 throws ConversionException { 064 Map<String, String> cmdStringParams = new HashMap<String, String>(); 065 066 String baseDir = getTmpDirectory(parameters); 067 Path tmpPath = new Path(baseDir).append(getTmpDirectoryPrefix() + "_" + UUID.randomUUID()); 068 069 File outDir = new File(tmpPath.toString()); 070 boolean dirCreated = outDir.mkdir(); 071 if (!dirCreated) { 072 throw new ConversionException("Unable to create tmp dir for transformer output: " + outDir); 073 } 074 075 File outFile; 076 try { 077 outFile = File.createTempFile("videoConversion", getVideoExtension(), outDir); 078 } catch (IOException e) { 079 throw new ConversionException("Unable to get Blob for holder", e); 080 } 081 // delete the file as we need only the path for ffmpeg 082 outFile.delete(); 083 Framework.trackFile(outFile, this); 084 cmdStringParams.put(OUTPUT_FILE_PATH_PARAMETER, outFile.getAbsolutePath()); 085 String baseName = FilenameUtils.getBaseName(blobHolder.getBlob().getFilename()); 086 cmdStringParams.put(OUTPUT_FILE_NAME_PARAMETER, baseName + getVideoExtension()); 087 088 VideoInfo videoInfo = (VideoInfo) parameters.get("videoInfo"); 089 if (videoInfo == null) { 090 return cmdStringParams; 091 } 092 093 long width = videoInfo.getWidth(); 094 long height = videoInfo.getHeight(); 095 long newHeight = (Long) parameters.get("height"); 096 097 long newWidth = width * newHeight / height; 098 if (newWidth % 2 != 0) { 099 newWidth += 1; 100 } 101 102 cmdStringParams.put("width", String.valueOf(newWidth)); 103 cmdStringParams.put("height", String.valueOf(newHeight)); 104 return cmdStringParams; 105 } 106 107 @Override 108 protected BlobHolder buildResult(List<String> cmdOutput, CmdParameters cmdParameters) throws ConversionException { 109 String outputPath = cmdParameters.getParameter(OUTPUT_FILE_PATH_PARAMETER); 110 File outputFile = new File(outputPath); 111 List<Blob> blobs = new ArrayList<Blob>(); 112 String outFileName = cmdParameters.getParameter(OUTPUT_FILE_NAME_PARAMETER); 113 if (outFileName == null) { 114 outFileName = outputFile.getName(); 115 } else { 116 outFileName = unquoteValue(outFileName); 117 } 118 119 try { 120 Blob blob = Blobs.createBlob(outputFile, getVideoMimeType(), null, outFileName); 121 blobs.add(blob); 122 } catch (IOException e) { 123 throw new ConversionException("Cannot create blob", e); 124 } 125 126 Map<String, Serializable> properties = new HashMap<String, Serializable>(); 127 properties.put("cmdOutput", (Serializable) cmdOutput); 128 return new SimpleBlobHolderWithProperties(blobs, properties); 129 } 130 131 /** 132 * @since 5.6 133 */ 134 protected String unquoteValue(String value) { 135 if (value.startsWith("\"") && value.endsWith("\"")) { 136 return value.substring(1, value.length() - 1); 137 } 138 return value; 139 } 140 141 /** 142 * Returns the video mime type to use for this converter. 143 */ 144 protected abstract String getVideoMimeType(); 145 146 /** 147 * Returns the video extension, always prefixed by '.'. 148 */ 149 protected abstract String getVideoExtension(); 150 151 /** 152 * Returns the temporary directory prefix to use for this converter. 153 */ 154 protected abstract String getTmpDirectoryPrefix(); 155 156}