/** Shut down the transformer plugin */ @Override public void shutdown() throws PluginException { // Shutdown the database if (stats != null) { try { stats.shutdown(); } catch (Exception ex) { log.error("Error shutting down database: ", ex); throw new PluginException(ex); } } }
/** * Convert audio/video to required output(s) * * @param sourceFile : The file to be converted * @param render : Configuration to use during the render * @param info : Parsed metadata about the source * @return File containing converted media * @throws TransformerException if the conversion failed */ private File convert(File sourceFile, JsonConfigHelper render, FfmpegInfo info) throws TransformerException { // Statistics variables long startTime, timeSpent; String resolution; // One list for all settings, the other is a subset for statistics List<String> statParams = new ArrayList<String>(); List<String> params = new ArrayList<String>(); // Prepare the output location String outputName = render.get("name"); if (outputName == null) { return null; } File outputFile = new File(outputDir, outputName); if (outputFile.exists()) { FileUtils.deleteQuietly(outputFile); } log.info("Converting '{}': '{}'", sourceFile.getName(), outputFile.getName()); // Get metadata ready JsonConfigHelper renderMetadata = new JsonConfigHelper(); String key = jsonKey(outputName); String formatString = render.get("formatMetadata"); if (formatString != null) { renderMetadata.set("format", formatString); } String codecString = render.get("codecMetadata"); if (codecString != null) { renderMetadata.set("codec", codecString); } try { // ************* // 1) Input file // ************* params.add("-i"); params.add(sourceFile.getAbsolutePath()); // Overwrite output file if it exists params.add("-y"); // ************* // 2) Configurable options // ************* String optionStr = render.get("options", ""); List<String> options = split(optionStr, " "); // Replace the offset placeholder now that we know the duration long start = 0; for (int i = 0; i < options.size(); i++) { String option = options.get(i); // For stats, use placeholder.. random data messes with hashing statParams.add(option); // If it even exists that is... if (option.equalsIgnoreCase("[[OFFSET]]")) { start = (long) (Math.random() * info.getDuration() * 0.25); option = Long.toString(start); } // Store the parameter for usage params.add(option); } // ************* // 3) Video resolution / padding // ************* String audioStr = render.get("audioOnly"); boolean audio = Boolean.parseBoolean(audioStr); // Non-audio files need some resolution work if (!audio) { List<String> dimensions = getPaddedParams(render, info, renderMetadata, statParams); if (dimensions == null || dimensions.isEmpty()) { addError(key, "Error calculating dimensions"); return null; } // Merge resultion parameters into standard parameters params.addAll(dimensions); } // Statistics String width = renderMetadata.get("width"); String height = renderMetadata.get("height"); if (width == null || height == null) { // Audio... or an error resolution = "0x0"; } else { resolution = width + "x" + height; } // ************* // 4) Output options // ************* optionStr = render.get("output", ""); options = split(optionStr, " "); // Merge option parameters into standard parameters if (!options.isEmpty()) { params.addAll(options); statParams.addAll(options); } params.add(outputFile.getAbsolutePath()); // ************* // 5) All done. Perform the transcoding // ************* startTime = new Date().getTime(); String stderr = ffmpeg.transform(params, outputDir); timeSpent = (new Date().getTime()) - startTime; renderMetadata.set("timeSpent", String.valueOf(timeSpent)); renderMetadata.set("debugOutput", stderr); if (outputFile.exists()) { long fileSize = outputFile.length(); if (fileSize == 0) { throw new TransformerException("File conversion failed!\n=====\n" + stderr); } else { renderMetadata.set("size", String.valueOf(fileSize)); } } else { throw new TransformerException("File conversion failed!\n=====\n" + stderr); } // log.debug("FFMPEG Output:\n=====\n\\/\\/\\/\\/\n{}/\\/\\/\\/\\\n=====\n", // stderr); } catch (IOException ioe) { addError(key, "Failed to convert!", ioe); throw new TransformerException(ioe); } // On a multi-pass encoding we may be asked to // throw away the video from some passes. if (outputFile.getName().contains("nullFile")) { return null; } else { // For anything else, record metadata metadata.put(key, renderMetadata); // And statistics if (stats != null) { Map<String, String> data = new HashMap(); data.put("oid", oid); data.put("datetime", String.valueOf(startTime)); data.put("timespent", String.valueOf(timeSpent)); data.put("renderString", StringUtils.join(statParams, " ")); data.put("mediaduration", String.valueOf(info.getDuration())); data.put("inresolution", info.getWidth() + "x" + info.getHeight()); data.put("outresolution", resolution); data.put("insize", String.valueOf(sourceFile.length())); data.put("outsize", String.valueOf(outputFile.length())); data.put("infile", sourceFile.getName()); data.put("outfile", outputFile.getName()); try { stats.storeTranscoding(data); } catch (Exception ex) { log.error("Error storing statistics: ", ex); } } } return outputFile; }