AnimateWorkflowOperationHandler extends AbstractWorkflowOperationHandler { @Override public WorkflowOperationResult start(WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException { MediaPackage mediaPackage = workflowInstance.getMediaPackage(); logger.info("Start animate workflow operation for media package {}", mediaPackage); WorkflowOperationInstance operation = workflowInstance.getCurrentOperation(); List<String> arguments; final File animationFile = new File(StringUtils.trimToEmpty(operation.getConfiguration(ANIMATION_FILE_PROPERTY))); if (!animationFile.isFile()) { throw new WorkflowOperationException(String.format("Animation file `%s` does not exist", animationFile)); } URI animation = animationFile.toURI(); final MediaPackageElementFlavor targetFlavor; try { targetFlavor = MediaPackageElementFlavor.parseFlavor(StringUtils.trimToNull( operation.getConfiguration(TARGET_FLAVOR_PROPERTY))); } catch (IllegalArgumentException e) { throw new WorkflowOperationException("Invalid target flavor", e); } String targetTagsProperty = StringUtils.trimToNull(operation.getConfiguration(TARGET_TAGS_PROPERTY)); String cmd = operation.getConfiguration(COMMANDLINE_ARGUMENTS_PROPERTY); if (StringUtils.isNotEmpty(cmd)) { arguments = Arrays.asList(StringUtils.split(cmd)); } else { arguments = new ArrayList<>(); arguments.add("-t"); arguments.add("ffmpeg"); arguments.add("--video-codec"); arguments.add("libx264-lossless"); arguments.add("--video-bitrate"); arguments.add("10000"); addArgumentIfExists(operation, arguments, WIDTH_PROPERTY, "-w"); addArgumentIfExists(operation, arguments, HEIGHT_PROPERTY, "-h"); addArgumentIfExists(operation, arguments, FPS_PROPERTY, "--fps"); } final Map<String, String> metadata = getMetadata(mediaPackage); Job job; try { job = animateService.animate(animation, metadata, arguments); } catch (AnimateServiceException e) { throw new WorkflowOperationException(String.format("Rendering animation from '%s' in media package '%s' failed", animation, mediaPackage), e); } if (!waitForStatus(job).isSuccess()) { throw new WorkflowOperationException(String.format("Animate job for media package '%s' failed", mediaPackage)); } try { URI output = new URI(job.getPayload()); String id = UUID.randomUUID().toString(); InputStream in = workspace.read(output); URI uri = workspace.put(mediaPackage.getIdentifier().toString(), id, FilenameUtils.getName(output.getPath()), in); TrackImpl track = new TrackImpl(); track.setIdentifier(id); track.setFlavor(targetFlavor); track.setURI(uri); Job inspection = mediaInspectionService.enrich(track, true); if (!waitForStatus(inspection).isSuccess()) { throw new AnimateServiceException(String.format("Animating %s failed", animation)); } track = (TrackImpl) MediaPackageElementParser.getFromXml(inspection.getPayload()); for (String tag : asList(targetTagsProperty)) { track.addTag(tag); } mediaPackage.add(track); workspace.delete(output); } catch (Exception e) { throw new WorkflowOperationException("Error handling animation service output", e); } try { workspace.cleanup(mediaPackage.getIdentifier()); } catch (IOException e) { throw new WorkflowOperationException(e); } logger.info("Animate workflow operation for media package {} completed", mediaPackage); return createResult(mediaPackage, WorkflowOperationResult.Action.CONTINUE); }  @Override @Activate void activate(ComponentContext cc); @Override WorkflowOperationResult start(WorkflowInstance workflowInstance, JobContext context); @Reference void setAnimateService(AnimateService animateService); @Reference void setMediaInspectionService(MediaInspectionService mediaInspectionService); @Reference void setWorkspace(Workspace workspace);  }
@Test public void testStart() throws Exception { EasyMock.expect(instance.getConfiguration("animation-file")).andReturn(file.getAbsolutePath()).anyTimes(); EasyMock.expect(instance.getConfiguration("fps")).andReturn("24").anyTimes(); EasyMock.replay(instance); Assert.assertTrue(handler.start(workflow, null).allowsContinue()); }
@Test public void testNoAnimation() { EasyMock.replay(instance); try { handler.start(workflow, null); } catch (WorkflowOperationException e) { return; } Assert.fail(); }
@Test public void testCustomCmdArgs() throws Exception { EasyMock.expect(instance.getConfiguration("animation-file")).andReturn(file.getAbsolutePath()).anyTimes(); EasyMock.expect(instance.getConfiguration("cmd-args")).andReturn("-t ffmpeg -w 160 -h 90").anyTimes(); EasyMock.replay(instance); Assert.assertTrue(handler.start(workflow, null).allowsContinue()); }