--- /dev/null
+/**\r
+ * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in\r
+ * all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+package com.liferay.portlet.documentlibrary.util;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.ByteArrayInputStream;\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.InputStreamReader;\r
+import java.security.MessageDigest;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+\r
+\r
+import com.artofsolving.jodconverter.DefaultDocumentFormatRegistry;\r
+import com.artofsolving.jodconverter.DocumentConverter;\r
+import com.artofsolving.jodconverter.DocumentFormat;\r
+import com.artofsolving.jodconverter.DocumentFormatRegistry;\r
+import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;\r
+import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;\r
+import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;\r
+import com.artofsolving.jodconverter.openoffice.converter.StreamOpenOfficeDocumentConverter;\r
+import com.liferay.portal.kernel.configuration.Filter;\r
+import com.liferay.portal.kernel.exception.PortalException;\r
+import com.liferay.portal.kernel.exception.SystemException;\r
+import com.liferay.portal.kernel.log.Log;\r
+import com.liferay.portal.kernel.log.LogFactoryUtil;\r
+import com.liferay.portal.kernel.util.ArrayUtil;\r
+import com.liferay.portal.kernel.util.Base64;\r
+import com.liferay.portal.kernel.util.FileUtil;\r
+import com.liferay.portal.kernel.util.MimeTypesOverrideUtil;\r
+import com.liferay.portal.kernel.util.PropsKeys;\r
+import com.liferay.portal.kernel.util.SortedArrayList;\r
+import com.liferay.portal.kernel.util.StringBundler;\r
+import com.liferay.portal.kernel.util.StringPool;\r
+import com.liferay.portal.kernel.util.SystemProperties;\r
+import com.liferay.portal.kernel.util.Validator;\r
+import com.liferay.portal.model.CompanyConstants;\r
+import com.liferay.portal.service.CompanyLocalServiceUtil;\r
+import com.liferay.portal.util.PrefsPropsUtil;\r
+import com.liferay.portal.util.PropsUtil;\r
+import com.liferay.portal.util.PropsValues;\r
+import com.liferay.portlet.documentlibrary.conversion.util.ENTDocumentConversionService;\r
+import com.liferay.portlet.documentlibrary.conversion.util.ENTDocumentConversionServiceUtil;\r
+import com.liferay.portlet.documentlibrary.store.DLStoreUtil;\r
+import com.pentila.entSavoie.utils.ENTMainUtilsLocalServiceUtil;\r
+\r
+/**\r
+ * <a href="DocumentConversionUtil.java.html"><b><i>View Source</i></b></a>\r
+ *\r
+ * @author Bruno Farache\r
+ *\r
+ */\r
+public class ENTDocumentConversionUtil implements ENTDocumentConversionService {\r
+\r
+ static Map<String, String> convertState = new HashMap<String, String>();\r
+ static Map<String, Process> convertProcess = new HashMap<String, Process>();\r
+\r
+ public File convert(\r
+ String id, InputStream is, String sourceExtension,\r
+ String targetExtension)\r
+ throws IOException, SystemException {\r
+ Map<String, String> parameters = new HashMap<String, String>();\r
+ return this.convert(id, is, sourceExtension, targetExtension, parameters);\r
+ }\r
+\r
+ public File convert(\r
+ String id, InputStream is, String sourceExtension,\r
+ String targetExtension, Map<String, String> parameters)\r
+ throws IOException, SystemException {\r
+ return _instance._convert(id, is, sourceExtension, targetExtension, parameters);\r
+ }\r
+\r
+ public void disconnect() {\r
+ _instance._disconnect();\r
+ }\r
+\r
+ public static String[] getConversions(String extension) {\r
+ return _instance._getConversions(extension);\r
+ }\r
+\r
+ public static boolean isComparableVersion(String extension) {\r
+ boolean enabled = false;\r
+\r
+ String dotExtension = StringPool.PERIOD + extension;\r
+\r
+ for (int i = 0; i < _COMPARABLE_FILE_EXTENSIONS.length; i++) {\r
+ if (StringPool.STAR.equals(_COMPARABLE_FILE_EXTENSIONS[i]) ||\r
+ dotExtension.equals(_COMPARABLE_FILE_EXTENSIONS[i])) {\r
+\r
+ enabled = true;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (!enabled) {\r
+ return false;\r
+ }\r
+\r
+ if (extension.equals("css") || extension.equals("js") ||\r
+ extension.equals("htm") || extension.equals("html") ||\r
+ extension.equals("txt") || extension.equals("xml")) {\r
+\r
+ return true;\r
+ }\r
+\r
+ try {\r
+ if (isEnabled() && isConvertBeforeCompare(extension)) {\r
+ return true;\r
+ }\r
+ }\r
+ catch (Exception e) {\r
+ if (_log.isErrorEnabled()) {\r
+ _log.error(e, e);\r
+ }\r
+ }\r
+\r
+ return false;\r
+ }\r
+\r
+ public static boolean isConvertBeforeCompare(String extension) {\r
+ if (extension.equals("txt")) {\r
+ return false;\r
+ }\r
+\r
+ String[] conversions = getConversions(extension);\r
+\r
+ for (int i = 0; i < conversions.length; i++) {\r
+ if (conversions[i].equals("txt")) {\r
+ return true;\r
+ }\r
+ }\r
+\r
+ return false;\r
+ }\r
+\r
+ public static boolean isEnabled() {\r
+ try {\r
+ return PrefsPropsUtil.getBoolean(\r
+ PropsKeys.OPENOFFICE_SERVER_ENABLED,\r
+ PropsValues.OPENOFFICE_SERVER_ENABLED);\r
+ }\r
+ catch (Exception e) {\r
+ }\r
+\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Return target file as inputStream\r
+ * @param path\r
+ * @param companyId\r
+ * @param targetExtension\r
+ * @param fileName\r
+ * @return\r
+ * @throws PortalException\r
+ * @throws SystemException\r
+ * @throws IOException\r
+ */\r
+ public Map<String, Object> getFileAsInputStream(String path, long companyId, String targetExtension, String fileName) throws PortalException, SystemException, IOException {\r
+ Map<String, Object> result = new HashMap<String, Object>();\r
+\r
+ // Dans cette methode is n'est pas ferné car on doit le faire dans la methode qui appelle, generalement getFile par un strut\r
+ InputStream is = null;\r
+ InputStream convertedIS = null;\r
+ InputStream isToConvert = null;\r
+\r
+ try {\r
+ int contentLength = (int) DLStoreUtil.getFileSize(companyId, CompanyConstants.SYSTEM, path);\r
+ \r
+ if (Validator.isNotNull(targetExtension)) {\r
+ InputStream isForId = DLStoreUtil.getFileAsStream(\r
+ companyId, CompanyConstants.SYSTEM, path); \r
+ String idSecure = ENTDocumentConversionServiceUtil.getFileChecksum(isForId);\r
+ isForId.close();\r
+\r
+ isToConvert = DLStoreUtil.getFileAsStream(\r
+ companyId, CompanyConstants.SYSTEM, path);\r
+ \r
+ String sourceExtension = FileUtil.getExtension(fileName);\r
+ try{\r
+ File file = ENTDocumentConversionServiceUtil.convert(\r
+ idSecure, isToConvert, sourceExtension, targetExtension);\r
+ convertedIS = new FileInputStream(file);\r
+ contentLength = (int) file.length();\r
+\r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append(fileName);\r
+ sb.append(StringPool.PERIOD);\r
+ sb.append(targetExtension);\r
+ fileName = sb.toString();\r
+\r
+ is = convertedIS;\r
+\r
+ } catch (Exception e){\r
+ File f = new File(ENTMainUtilsLocalServiceUtil.getFileErrorFlv(companyId));\r
+ fileName = "error.txt";\r
+ is = new FileInputStream(f);\r
+ contentLength = (int) f.length();\r
+ }\r
+\r
+ isToConvert.close();\r
+\r
+ }\r
+ else {\r
+ is = DLStoreUtil.getFileAsStream(\r
+ companyId, CompanyConstants.SYSTEM, path);\r
+ }\r
+\r
+ String contentType = MimeTypesOverrideUtil.getContentType(fileName);\r
+\r
+\r
+ result.put("contentType", contentType);\r
+ result.put("contentLength", contentLength);\r
+ result.put("fileName", fileName);\r
+ result.put("stream", is);\r
+\r
+ return result;\r
+ }\r
+ catch(Exception exc) {\r
+ if (isToConvert!=null) {\r
+ isToConvert.close();\r
+ }\r
+\r
+\r
+ File f = null;\r
+ f = new File(ENTMainUtilsLocalServiceUtil.getFileErrorFlv(companyId));\r
+ fileName = "error.txt";\r
+ is = new FileInputStream(f);\r
+\r
+ result.put("contentType", MimeTypesOverrideUtil.getContentType(fileName));\r
+ result.put("contentLength", (int) f.length());\r
+ result.put("fileName", fileName);\r
+ result.put("stream", is);\r
+\r
+ return result;\r
+\r
+ }\r
+ }\r
+\r
+\r
+ public String getFileChecksum(InputStream is) {\r
+\r
+ try {\r
+\r
+ MessageDigest md = MessageDigest.getInstance("MD5");\r
+ byte[] dataBytes = new byte[1024];\r
+\r
+ int nread = 0; \r
+\r
+ while ((nread = is.read(dataBytes)) != -1) {\r
+ md.update(dataBytes, 0, nread);\r
+ };\r
+\r
+ byte[] mdbytes = md.digest();\r
+\r
+ //convert the byte to hex format\r
+ StringBuffer sb = new StringBuffer("");\r
+ for (int i = 0; i < mdbytes.length; i++) {\r
+ sb.append(Integer.toString((mdbytes[i] & 0xFF), 16).substring(1));\r
+ }\r
+\r
+ return sb.toString();\r
+ } catch (Exception e) {\r
+ _log.error(e);\r
+ return null;\r
+ }\r
+\r
+ }\r
+\r
+ public String getTempFileId(String id, double version) {\r
+ StringBuilder sb = new StringBuilder();\r
+\r
+ sb.append(id);\r
+ sb.append(StringPool.PERIOD);\r
+ sb.append(version);\r
+\r
+ return sb.toString();\r
+ }\r
+\r
+ private ENTDocumentConversionUtil() {\r
+ _conversionsMap.put("svg", _DRAWING_CONVERSIONS);\r
+ _conversionsMap.put("swf", _DRAWING_CONVERSIONS);\r
+\r
+ _conversionsMap.put("odp", _PRESENTATION_CONVERSIONS);\r
+ _conversionsMap.put("ppt", _PRESENTATION_CONVERSIONS);\r
+ _conversionsMap.put("sxi", _PRESENTATION_CONVERSIONS);\r
+ _conversionsMap.put("pptx", _PRESENTATION_CONVERSIONS);\r
+\r
+ _conversionsMap.put("csv", _SPREADSHEET_CONVERSIONS);\r
+ _conversionsMap.put("ods", _SPREADSHEET_CONVERSIONS);\r
+ _conversionsMap.put("sxc", _SPREADSHEET_CONVERSIONS);\r
+ _conversionsMap.put("tsv", _SPREADSHEET_CONVERSIONS);\r
+ _conversionsMap.put("xls", _SPREADSHEET_CONVERSIONS);\r
+ _conversionsMap.put("xlsx", _SPREADSHEET_CONVERSIONS);\r
+\r
+ _conversionsMap.put("doc", _TEXT_CONVERSIONS);\r
+ _conversionsMap.put("htm", _TEXT_CONVERSIONS);\r
+ _conversionsMap.put("html", _TEXT_CONVERSIONS);\r
+ _conversionsMap.put("odt", _TEXT_CONVERSIONS);\r
+ _conversionsMap.put("rtf", _TEXT_CONVERSIONS);\r
+ _conversionsMap.put("sxw", _TEXT_CONVERSIONS);\r
+ _conversionsMap.put("txt", _TEXT_CONVERSIONS);\r
+ _conversionsMap.put("wpd", _TEXT_CONVERSIONS);\r
+ _conversionsMap.put("docx", _TEXT_CONVERSIONS);\r
+ }\r
+\r
+ /**\r
+ * Get conversion process state from file key\r
+ * @param key\r
+ * @return\r
+ */\r
+ public String getConvertState(String key){\r
+ \r
+ if(convertState.containsKey(key)){\r
+ int duration = 1;\r
+ if(convertState.containsKey(key+"duration")) {\r
+ duration = Integer.parseInt(convertState.get(key+"duration"));\r
+ }\r
+ String state = convertState.get(key);\r
+ \r
+ if (state.contains("time")) {\r
+ int currentTime = 0;\r
+ //time=00:00:53.77 We take the hour, minute and seconds values\r
+ Pattern pattern = Pattern.compile("time=(.*?)[.]");\r
+ Matcher matcher = pattern.matcher(state);\r
+ if (matcher.find())\r
+ {\r
+ // Get value in seconds\r
+ String currentTimeStr = matcher.group(1);\r
+ \r
+ String[] timeValues = currentTimeStr.split(":");\r
+ if (timeValues.length == 3) {\r
+ currentTime = Integer.parseInt(timeValues[0]) * 3600 + Integer.parseInt(timeValues[1]) * 60 + Integer.parseInt(timeValues[2]);\r
+ }\r
+ }\r
+ if (currentTime != 0) {\r
+ state = String.valueOf(currentTime*100/duration);\r
+ }\r
+ }\r
+ if(state.equals("done") || state.equals("error")){\r
+ convertState.remove(key);\r
+ }\r
+ return state;\r
+ }\r
+ return "0";\r
+ }\r
+\r
+ /**\r
+ * Stop conversion process with the given key\r
+ * @param key\r
+ */\r
+ public void killConvertProcess(String key){ \r
+ if(convertProcess.containsKey(key)){\r
+ convertProcess.get(key).destroy();\r
+ convertProcess.remove(key);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Convert the source file in input stream to a new file with the targetExtension type\r
+ * @param id\r
+ * @param is\r
+ * @param sourceExtension\r
+ * @param targetExtension\r
+ * @param parameters\r
+ * @return\r
+ * @throws IOException\r
+ * @throws SystemException\r
+ */\r
+ private File _convert(\r
+ String id, InputStream is, String sourceExtension,\r
+ String targetExtension, Map<String, String> parameters)\r
+ throws IOException, SystemException {\r
+ \r
+ _log.warn("BEGIN CONVERSION METHOD : Convert from " + sourceExtension + " to " + targetExtension);\r
+ if (id == null) {\r
+ return null;\r
+ }\r
+\r
+ if (!PrefsPropsUtil.getBoolean(\r
+ PropsKeys.OPENOFFICE_SERVER_ENABLED,\r
+ PropsValues.OPENOFFICE_SERVER_ENABLED)) {\r
+ return null;\r
+ }\r
+ \r
+ String fileName = getFileName(id, targetExtension);\r
+ File fileResult = new File(fileName);\r
+ boolean forceConversion = !parameters.isEmpty();\r
+ \r
+ // If the file is in cache then don't convert it again\r
+ if (fileResult.exists() && !forceConversion) {\r
+ _log.warn("File already converted, directly return file in cache");\r
+ convertState.put(id, "done");\r
+ return fileResult;\r
+ }\r
+\r
+ if (targetExtension.equals("mp4") || targetExtension.equals("mp3")) {\r
+ // Start media conversion\r
+ fileResult = startMediaConversion(fileResult, is, id, sourceExtension, targetExtension, fileName, parameters);\r
+ }\r
+ else if (targetExtension.equals("pdf")) {\r
+ // Run OpenOffice conversion\r
+ return runOpenOfficeConversion(fileResult, is, sourceExtension, targetExtension);\r
+ }\r
+\r
+ // Process has ended without being killed\r
+ if(convertProcess.containsKey(id)){\r
+ convertProcess.remove(id);\r
+\r
+ // Check if the conversion has ended correctly (the new file is created)\r
+ if(fileResult.exists()){\r
+ _log.warn("Conversion process successfully done");\r
+ convertState.put(id, "done");\r
+ return fileResult;\r
+ } else {\r
+ _log.error("Conversion process failed");\r
+ convertState.put(id, "error");\r
+ return null;\r
+ }\r
+ }\r
+ else {\r
+ return null;\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Build complete temp filename from id and extension\r
+ * @param id ID from the file\r
+ * @param extension file type\r
+ * @return the temp file name\r
+ */\r
+ private String getFileName(String id, String extension) {\r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append(SystemProperties.get(SystemProperties.TMP_DIR));\r
+ sb.append("/liferay/document_conversion/");\r
+ sb.append(id);\r
+ sb.append(StringPool.PERIOD);\r
+ sb.append(extension);\r
+ return sb.toString();\r
+ }\r
+ \r
+ /**\r
+ * Find infos concerning video or audio file before conversion\r
+ * @param filePath the source file path\r
+ */\r
+ private void getMediaFileInfos(String filePath, String id) {\r
+ String [] cmdProbe = new String("ffprobe " + filePath).split(" ");\r
+ try {\r
+ final Process p = Runtime.getRuntime().exec(cmdProbe);\r
+ convertProcess.put(id+"getInfos", p);\r
+ new Thread() {\r
+ public void run() {\r
+ try {\r
+ BufferedReader reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));\r
+ String line = "";\r
+ try {\r
+ while((line = reader.readLine()) != null) {\r
+ if (line.contains("Duration")) {\r
+ //Duration: 01:38:16.28, We take the hour, minute and seconds values\r
+ Pattern pattern = Pattern.compile("Duration: (.*?)[.]");\r
+ Matcher matcher = pattern.matcher(line);\r
+ if (matcher.find())\r
+ {\r
+ // Get value in seconds\r
+ String durationStr = matcher.group(1);\r
+ \r
+ String[] timeValues = durationStr.split(":");\r
+ if (timeValues.length == 3) {\r
+ mediaDuration = Integer.parseInt(timeValues[0]) * 3600 + Integer.parseInt(timeValues[1]) * 60 + Integer.parseInt(timeValues[2]);\r
+ }\r
+ }\r
+ }\r
+ if (line.contains("Video: h264") && line.contains("kb/s")) {\r
+ isH264 = true;\r
+ }\r
+ }\r
+ } finally {\r
+ reader.close();\r
+ }\r
+ } catch(IOException ioe) {\r
+ _log.error(ioe);\r
+ }\r
+ }\r
+ }.start();\r
+ p.waitFor();\r
+ }catch(Exception e) {\r
+ _log.error(e);\r
+ } \r
+ }\r
+ \r
+\r
+ /**\r
+ * Run document conversion to PDF\r
+ * @param fileResult\r
+ * @param is\r
+ * @param sourceExtension\r
+ * @param targetExtension\r
+ * @return\r
+ */\r
+ private File runOpenOfficeConversion(File fileResult, InputStream is, String sourceExtension, String targetExtension) {\r
+ // conversion OPENOFFICE\r
+ _log.debug("OpenOffice conversion");\r
+ DocumentFormatRegistry registry =\r
+ new DefaultDocumentFormatRegistry();\r
+\r
+ DocumentConverter converter;\r
+ try {\r
+ converter = _getConverter(registry);\r
+ }\r
+ catch(SystemException e) {\r
+ _log.error(e);\r
+ return new File(fileResult.getPath());\r
+ }\r
+ \r
+ if (sourceExtension.equals("docx")) {\r
+ sourceExtension = "doc";\r
+ }\r
+ if (sourceExtension.equals("xlsx")) {\r
+ sourceExtension = "xls";\r
+ }\r
+ if (sourceExtension.equals("pptx")) {\r
+ sourceExtension = "ppt";\r
+ }\r
+ \r
+ try {\r
+ DocumentFormat inputFormat = registry.getFormatByFileExtension(\r
+ sourceExtension);\r
+\r
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();\r
+\r
+ DocumentFormat outputFormat = registry.getFormatByFileExtension(\r
+ targetExtension);\r
+\r
+ converter.convert(is, inputFormat, baos, outputFormat);\r
+ FileUtil.write(fileResult, baos.toByteArray());\r
+ baos.close();\r
+ }\r
+ catch(IOException e) {\r
+ _log.error(e);\r
+ return new File(fileResult.getPath());\r
+ }\r
+ \r
+ // retour direct apres conversion office\r
+ return fileResult;\r
+ }\r
+ \r
+ /**\r
+ * Launch media conversion which will init the needed parameters\r
+ * @param fileResult\r
+ * @param is\r
+ * @param id\r
+ * @param sourceExtension\r
+ * @param targetExtension\r
+ * @param fileName\r
+ * @param parameters\r
+ * @return\r
+ */\r
+ private File startMediaConversion(File fileResult, InputStream is, String id, String sourceExtension, \r
+ String targetExtension, String fileName, Map<String, String> parameters) {\r
+ String command = "";\r
+ String extraConversionOption = "";\r
+ \r
+ String fileSourceName = getFileName(id, sourceExtension);\r
+ File fileSourceTmp = new File(fileSourceName);\r
+ \r
+ // Write temp source file\r
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();\r
+ int nRead;\r
+ byte[] data = new byte[16384];\r
+\r
+ try {\r
+ while ((nRead = is.read(data, 0, data.length)) != -1) {\r
+ buffer.write(data, 0, nRead);\r
+ }\r
+ buffer.flush();\r
+ FileUtil.write(fileSourceTmp, buffer.toByteArray());\r
+ }\r
+ catch (IOException e) {\r
+ _log.error(e);\r
+ return new File(fileResult.getPath());\r
+ }\r
+ \r
+ isH264 = false;\r
+ getMediaFileInfos(fileSourceTmp.getPath(), id);\r
+ \r
+ if(targetExtension.equals("mp3")){\r
+ command = "ffmpeg -i " + fileSourceTmp.getPath() + " -movflags +faststart " + fileName;\r
+ }\r
+ else if(targetExtension.equals("mp4")) {\r
+ /* If we have more args -> need a command update\r
+ String sampleRate = parameters.containsKey("sampleRate") ? parameters.get("sampleRate") : "22050";\r
+ String avSync = parameters.containsKey("avSync") ? parameters.get("avSync") : "-mc 0";\r
+ String frameRate = parameters.containsKey("frameRate") ? parameters.get("frameRate") : ""; // frameRate doit contenir "-ofps 25" par exemple\r
+ String bitrateAudio = parameters.containsKey("bitrateAudio") ? parameters.get("bitrateAudio") : "56";\r
+ String bitrateVideo = parameters.containsKey("bitrateVideo") ? parameters.get("bitrateVideo") : "250"; // frameRate doit contenir "-ofps 25" par exemple\r
+\r
+ String videoSize = parameters.containsKey("videoSize") ? parameters.get("videoSize") : "360x240";\r
+ String[] size = videoSize.split("x");\r
+ String videoWidth = size[0];\r
+ String videoHeight = size[1];\r
+ String videoScale = "-vf scale=";\r
+ boolean keepAspect = Boolean.getBoolean(parameters.containsKey("keepAspect") ? parameters.get("keepAspect") : "true");\r
+ if (keepAspect) {\r
+ videoScale += videoWidth + ":-2,expand=:" + videoHeight + ":::,crop=" + videoWidth + ":" + videoHeight + ",harddup";\r
+ }\r
+ else {\r
+ videoScale += videoWidth + ":" + videoHeight + ",harddup";\r
+ }\r
+ */\r
+\r
+ //-movflags +faststart thanks to this option the video will start before file is entirely loaded\r
+ if (isH264) { \r
+ //If we can detect if video encoding is h264 use copy only to optimize (using ffprobe ?) :\r
+ command = "ffmpeg -i " + fileSourceTmp.getPath() + " -vcodec copy -acodec copy -movflags +faststart " + fileName;\r
+ }\r
+ else {\r
+ command = "ffmpeg -i " + fileSourceTmp.getPath() + " -c:v libx264 -preset ultrafast -c:a aac -movflags +faststart " + fileName; \r
+ }\r
+ }\r
+\r
+ //_log.warn("Command used : " + command);\r
+ fileResult = runMediaConversion(command, fileResult, fileName, id);\r
+ \r
+ // Delete the temp source file created\r
+ if (FileUtil.exists(fileSourceTmp)) {\r
+ FileUtil.delete(fileSourceTmp);\r
+ }\r
+ \r
+ return fileResult;\r
+ }\r
+ \r
+ /**\r
+ * Run media conversion process that's describe in command parameter.\r
+ * Return the converted file\r
+ * @param command\r
+ * @param fileResult\r
+ * @param fileName\r
+ * @param id\r
+ * @return\r
+ */\r
+ private File runMediaConversion(String command, File fileResult, String fileName, String id) {\r
+ _log.warn("Media conversion");\r
+ final String secureId = id;\r
+ String [] cmd = command.split(" ");\r
+ \r
+ try {\r
+ final Process p = Runtime.getRuntime().exec(cmd);\r
+ convertProcess.put(secureId, p);\r
+ convertState.put(secureId+"duration", String.valueOf(mediaDuration));\r
+ // Write convert process state informations\r
+ new Thread() {\r
+ public void run() {\r
+ try {\r
+ BufferedReader reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));\r
+ String line = "";\r
+ try {\r
+ while((line = reader.readLine()) != null) {\r
+ convertState.put(secureId, line);\r
+ _log.debug(line);\r
+ }\r
+ } finally {\r
+ reader.close();\r
+ }\r
+ } catch(IOException ioe) {\r
+ _log.error(ioe);\r
+ }\r
+ }\r
+ }.start();\r
+ // Waiting for the process to end\r
+ p.waitFor();\r
+ fileResult = new File(fileName);\r
+\r
+ }catch(Exception e) {\r
+ _log.error(e);\r
+ }\r
+ return fileResult;\r
+ }\r
+\r
+ private void _disconnect() {\r
+ if (_connection != null) {\r
+ _connection.disconnect();\r
+ }\r
+ }\r
+\r
+ private String _fixExtension(String extension) {\r
+ if (extension.equals("htm")) {\r
+ extension = "html";\r
+ }\r
+\r
+ return extension;\r
+ }\r
+\r
+ private String[] _getConversions(String extension) {\r
+ extension = _fixExtension(extension);\r
+\r
+ String[] conversions = _conversionsMap.get(extension);\r
+\r
+ if (conversions == null) {\r
+ conversions = _DEFAULT_CONVERSIONS;\r
+ }\r
+ else {\r
+ if (ArrayUtil.contains(conversions, extension)) {\r
+ List<String> conversionsList = new ArrayList<String>();\r
+\r
+ for (int i = 0; i < conversions.length; i++) {\r
+ String conversion = conversions[i];\r
+\r
+ if (!conversion.equals(extension)) {\r
+ conversionsList.add(conversion);\r
+ }\r
+ }\r
+\r
+ conversions = conversionsList.toArray(\r
+ new String[conversionsList.size()]);\r
+ }\r
+ }\r
+\r
+ return conversions;\r
+ }\r
+\r
+ private DocumentConverter _getConverter(DocumentFormatRegistry registry)\r
+ throws SystemException {\r
+\r
+ if ((_connection == null) || (_converter == null)) {\r
+ String host = PrefsPropsUtil.getString(\r
+ PropsKeys.OPENOFFICE_SERVER_HOST);\r
+ int port = PrefsPropsUtil.getInteger(\r
+ PropsKeys.OPENOFFICE_SERVER_PORT,\r
+ PropsValues.OPENOFFICE_SERVER_PORT);\r
+ //_log.warn("host : " + host + " - port : " + port);\r
+\r
+ if (_isRemoteOpenOfficeHost(host)) {\r
+ _connection = new SocketOpenOfficeConnection(host, port);\r
+ _converter = new StreamOpenOfficeDocumentConverter(_connection);\r
+ }\r
+ else {\r
+ _connection = new SocketOpenOfficeConnection(port);\r
+ _converter = new OpenOfficeDocumentConverter(_connection);\r
+ }\r
+ }\r
+\r
+ return _converter;\r
+ }\r
+\r
+ private boolean _isRemoteOpenOfficeHost(String host) {\r
+ if (Validator.isNotNull(host) && !host.equals(_LOCALHOST_IP) &&\r
+ !host.startsWith(_LOCALHOST)) {\r
+\r
+ return true;\r
+ }\r
+ else {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ private void _populateConversionsMap(String documentFamily) {\r
+ Filter filter = new Filter(documentFamily);\r
+\r
+ DocumentFormatRegistry documentFormatRegistry =\r
+ new DefaultDocumentFormatRegistry();\r
+\r
+ String[] sourceExtensions = PropsUtil.getArray(\r
+ PropsKeys.OPENOFFICE_CONVERSION_SOURCE_EXTENSIONS, filter);\r
+ String[] targetExtensions = PropsUtil.getArray(\r
+ PropsKeys.OPENOFFICE_CONVERSION_TARGET_EXTENSIONS, filter);\r
+\r
+ for (String sourceExtension : sourceExtensions) {\r
+ List<String> conversions = new SortedArrayList<String>();\r
+\r
+ DocumentFormat sourceDocumentFormat =\r
+ documentFormatRegistry.getFormatByFileExtension(\r
+ sourceExtension);\r
+\r
+ if (sourceDocumentFormat == null) {\r
+ if (_log.isWarnEnabled()) {\r
+ _log.warn("Invalid source extension " + sourceExtension);\r
+ }\r
+\r
+ continue;\r
+ }\r
+\r
+ for (String targetExtension : targetExtensions) {\r
+ DocumentFormat targetDocumentFormat =\r
+ documentFormatRegistry.getFormatByFileExtension(\r
+ targetExtension);\r
+\r
+ if (targetDocumentFormat == null) {\r
+ if (_log.isWarnEnabled()) {\r
+ _log.warn(\r
+ "Invalid target extension " + targetDocumentFormat);\r
+ }\r
+\r
+ continue;\r
+ }\r
+\r
+ if (sourceDocumentFormat.isExportableTo(targetDocumentFormat)) {\r
+ conversions.add(targetExtension);\r
+ }\r
+ }\r
+\r
+ if (conversions.isEmpty()) {\r
+ if (_log.isInfoEnabled()) {\r
+ _log.info(\r
+ "There are no conversions supported from " +\r
+ sourceExtension);\r
+ }\r
+ }\r
+ else {\r
+ if (_log.isInfoEnabled()) {\r
+ _log.info(\r
+ "Conversions supported from " + sourceExtension +\r
+ " to " + conversions);\r
+ }\r
+\r
+ _conversionsMap.put(\r
+ sourceExtension,\r
+ conversions.toArray(new String[conversions.size()]));\r
+ }\r
+ }\r
+ }\r
+\r
+ private void _validateExtension(String extension) throws SystemException {\r
+ if (extension.contains(StringPool.SLASH) ||\r
+ extension.contains(StringPool.BACK_SLASH) ||\r
+ extension.contains(File.pathSeparator)) {\r
+\r
+ throw new SystemException("Invalid extension: " + extension);\r
+ }\r
+ }\r
+\r
+ private static final String[] _DEFAULT_CONVERSIONS = new String[0];\r
+\r
+ private static final String[] _DRAWING_CONVERSIONS = new String[] {"odg"};\r
+\r
+ private static final String[] _COMPARABLE_FILE_EXTENSIONS =\r
+ PropsValues.DL_COMPARABLE_FILE_EXTENSIONS;\r
+\r
+ private static final String _LOCALHOST = "localhost";\r
+\r
+ private static final String _LOCALHOST_IP = "127.0.0.1";\r
+\r
+ private static final String[] _PRESENTATION_CONVERSIONS = new String[] {\r
+ "odp", "pdf", "ppt", "sxi","pptx"\r
+ };\r
+\r
+ private static final String[] _SPREADSHEET_CONVERSIONS = new String[] {\r
+ "csv", "ods", "pdf", "sxc", "tsv", "xls","xlsx"\r
+ };\r
+\r
+ private static final String[] _TEXT_CONVERSIONS = new String[] {\r
+ "doc", "odt", "pdf", "rtf", "sxw", "txt","docx"\r
+ };\r
+\r
+ private static Log _log = LogFactoryUtil.getLog(\r
+ ENTDocumentConversionUtil.class);\r
+\r
+ private static ENTDocumentConversionUtil _instance =\r
+ new ENTDocumentConversionUtil();\r
+\r
+ private Map<String, String[]> _conversionsMap =\r
+ new HashMap<String, String[]>();\r
+ private OpenOfficeConnection _connection;\r
+ private DocumentConverter _converter;\r
+ \r
+ // If video has the right encoding we can handle faster conversion\r
+ private boolean isH264 = false;\r
+ \r
+ // Media duration on seconds (Use for the progress bar)\r
+ private int mediaDuration = 0;\r
+\r
+}
\ No newline at end of file