/** * Internal helper to fork a process with handbrake and read the values from the process * * @param videoTranscoding * @return true: all ok; false: an error happend along the way */ private boolean forkTranscodingProcess(VideoTranscoding videoTranscoding) { OLATResource video = videoTranscoding.getVideoResource(); VideoModule videoModule = CoreSpringFactory.getImpl(VideoModule.class); VideoManager videoManager = CoreSpringFactory.getImpl(VideoManager.class); File masterFile = videoManager.getVideoFile(video); File transcodingFolder = ((LocalFolderImpl) videoManager.getTranscodingContainer(video)).getBasefile(); File transcodedFile = new File( transcodingFolder, Integer.toString(videoTranscoding.getResolution()) + masterFile.getName()); // mark this as beeing transcoded by this local transcoder videoTranscoding.setTranscoder(VideoTranscoding.TRANSCODER_LOCAL); videoTranscoding = videoManager.updateVideoTranscoding(videoTranscoding); ArrayList<String> cmd = new ArrayList<>(); String tasksetConfig = videoModule.getTranscodingTasksetConfig(); if (tasksetConfig != null && !"Mac OS X".equals(System.getProperty("os.name"))) { cmd.add("taskset"); cmd.add("-c"); cmd.add(tasksetConfig); } cmd.add("HandBrakeCLI"); cmd.add("-i"); cmd.add(masterFile.getAbsolutePath()); cmd.add("-o"); cmd.add(transcodedFile.getAbsolutePath()); cmd.add("--optimize"); cmd.add("--preset"); cmd.add("Normal"); cmd.add("--height"); cmd.add(Integer.toString(videoTranscoding.getResolution())); cmd.add("--deinterlace"); cmd.add("--crop"); cmd.add("0:0:0:0"); Process process = null; try { if (log.isDebug()) { log.debug(cmd.toString()); } ProcessBuilder builder = new ProcessBuilder(cmd); process = builder.start(); return updateVideoTranscodingFromProcessOutput(process, videoTranscoding, transcodedFile); } catch (IOException e) { log.error("Could not spawn convert sub process", e); return false; } finally { if (process != null) { process.destroy(); process = null; } } }
/** * Implementation of job execution * * @param context * @return * @throws JobExecutionException */ private boolean doExecute(JobExecutionContext context) throws JobExecutionException { VideoModule videoModule = CoreSpringFactory.getImpl(VideoModule.class); if (!videoModule.isTranscodingLocal()) { log.debug("Skipping execution of video transcoding job, local transcoding disabled"); return false; } // Find first one to work with VideoManager videoManager = CoreSpringFactory.getImpl(VideoManager.class); List<VideoTranscoding> videoTranscodings = videoManager.getVideoTranscodingsPendingAndInProgress(); VideoTranscoding videoTranscoding = null; for (VideoTranscoding videoTrans : videoTranscodings) { String transcoder = videoTrans.getTranscoder(); if (transcoder == null) { log.info( "Start transcoding video with resolution::" + videoTrans.getResolution() + " for video resource::" + videoTrans.getVideoResource().getResourceableId()); videoTrans.setTranscoder(VideoTranscoding.TRANSCODER_LOCAL); videoTranscoding = videoManager.updateVideoTranscoding(videoTrans); break; } else if (transcoder.equals(VideoTranscoding.TRANSCODER_LOCAL)) { log.info( "Continue with transcoding video with resolution::" + videoTrans.getResolution() + " for video resource::" + videoTrans.getVideoResource().getResourceableId()); videoTranscoding = videoTrans; break; } } if (videoTranscoding == null) { log.debug( "Skipping execution of video transcoding job, no pending video transcoding found in database"); return false; } // Ready transcode, forke process now boolean success = forkTranscodingProcess(videoTranscoding); // Transcoding done, call execution again until no more videos to be // processed. If an error happend, don't continue to not get into a loop if (success) { success = doExecute(context); } return success; }
private void generateStatusOfTranscodings() { // FIXME:FK fetch using one single SQL query availableTranscodings = new HashMap<>(); availableTranscodings.put(240, new HashSet<OLATResource>()); availableTranscodings.put(360, new HashSet<OLATResource>()); availableTranscodings.put(480, new HashSet<OLATResource>()); availableTranscodings.put(720, new HashSet<OLATResource>()); availableTranscodings.put(1080, new HashSet<OLATResource>()); availableTranscodings.put(2160, new HashSet<OLATResource>()); // determine resource type of interest List<String> types = new ArrayList<>(); types.add("FileResource.VIDEO"); // retrieve all resources of type video olatresources = olatresourceManager.findResourceByTypes(types); // go through all video resources for (OLATResource videoResource : olatresources) { // retrieve all transcodings for each video resource List<VideoTranscoding> transcodings = videoManager.getVideoTranscodings(videoResource); // map resource IDs to resolution for (VideoTranscoding videoTranscoding : transcodings) { if (videoTranscoding != null) { Set<OLATResource> oneResolution = availableTranscodings.get(videoTranscoding.getResolution()); if (oneResolution != null) { oneResolution.add(videoTranscoding.getVideoResource()); } } } } }
// go through all and delete selection private void queueDeleteTranscoding(TranscodingRow source) { for (OLATResource videoResource : olatresources) { if (availableTranscodings.get(source.getResolution()).contains(videoResource)) { List<VideoTranscoding> videoTranscodings = videoManager.getVideoTranscodings(videoResource); for (VideoTranscoding videoTranscoding : videoTranscodings) { if (videoTranscoding.getResolution() == source.getResolution()) { videoManager.deleteVideoTranscoding(videoTranscoding); } } } } }