Search in sources :

Example 36 with WorkflowOperationException

use of org.opencastproject.workflow.api.WorkflowOperationException in project opencast by opencast.

the class NormalizeAudioWorkflowOperationHandler method normalize.

private WorkflowOperationResult normalize(MediaPackage src, WorkflowOperationInstance operation) throws SoxException, IOException, NotFoundException, MediaPackageException, WorkflowOperationException, EncoderException {
    MediaPackage mediaPackage = (MediaPackage) src.clone();
    // Check which tags have been configured
    String sourceTagsOption = StringUtils.trimToNull(operation.getConfiguration("source-tags"));
    String targetTagsOption = StringUtils.trimToNull(operation.getConfiguration("target-tags"));
    String sourceFlavorOption = StringUtils.trimToNull(operation.getConfiguration("source-flavor"));
    String sourceFlavorsOption = StringUtils.trimToNull(operation.getConfiguration("source-flavors"));
    String targetFlavorOption = StringUtils.trimToNull(operation.getConfiguration("target-flavor"));
    String targetDecibelString = StringUtils.trimToNull(operation.getConfiguration("target-decibel"));
    if (targetDecibelString == null)
        throw new IllegalArgumentException("target-decibel must be specified");
    boolean forceTranscode = BooleanUtils.toBoolean(operation.getConfiguration("force-transcode"));
    Float targetDecibel;
    try {
        targetDecibel = new Float(targetDecibelString);
    } catch (NumberFormatException e1) {
        throw new WorkflowOperationException("Unable to parse target-decibel " + targetDecibelString);
    }
    AbstractMediaPackageElementSelector<Track> elementSelector = new TrackSelector();
    // Make sure either one of tags or flavors are provided
    if (StringUtils.isBlank(sourceTagsOption) && StringUtils.isBlank(sourceFlavorOption) && StringUtils.isBlank(sourceFlavorsOption)) {
        logger.info("No source tags or flavors have been specified, not matching anything");
        return createResult(mediaPackage, Action.CONTINUE);
    }
    // Select the source flavors
    for (String flavor : asList(sourceFlavorsOption)) {
        try {
            elementSelector.addFlavor(MediaPackageElementFlavor.parseFlavor(flavor));
        } catch (IllegalArgumentException e) {
            throw new WorkflowOperationException("Source flavor '" + flavor + "' is malformed");
        }
    }
    // Support legacy "source-flavor" option
    if (StringUtils.isNotBlank(sourceFlavorOption)) {
        String flavor = StringUtils.trim(sourceFlavorOption);
        try {
            elementSelector.addFlavor(MediaPackageElementFlavor.parseFlavor(flavor));
        } catch (IllegalArgumentException e) {
            throw new WorkflowOperationException("Source flavor '" + flavor + "' is malformed");
        }
    }
    // Select the source tags
    for (String tag : asList(sourceTagsOption)) {
        elementSelector.addTag(tag);
    }
    // Target tags
    List<String> targetTags = asList(targetTagsOption);
    // Target flavor
    MediaPackageElementFlavor targetFlavor = null;
    if (StringUtils.isNotBlank(targetFlavorOption)) {
        try {
            targetFlavor = MediaPackageElementFlavor.parseFlavor(targetFlavorOption);
        } catch (IllegalArgumentException e) {
            throw new WorkflowOperationException("Target flavor '" + targetFlavorOption + "' is malformed");
        }
    }
    // Look for elements matching the tag
    Collection<Track> elements = elementSelector.select(mediaPackage, false);
    // Encode all tracks found
    long totalTimeInQueue = 0;
    List<URI> cleanupURIs = new ArrayList<URI>();
    Map<Job, Track> normalizeJobs = new HashMap<Job, Track>();
    try {
        for (Track track : elements) {
            TrackImpl audioTrack = (TrackImpl) track;
            // Skip video only mismatches
            if (!track.hasAudio()) {
                logger.info("Skipping audio normalization of '{}', since it contains no audio stream", track);
                continue;
            } else if (track.hasVideo() || forceTranscode) {
                audioTrack = (TrackImpl) extractAudioTrack(track);
                audioTrack.setAudio(((TrackImpl) track).getAudio());
                cleanupURIs.add(audioTrack.getURI());
            }
            // Analyze audio track
            if (audioTrack.getAudio().size() < 1 || audioTrack.getAudio().get(0).getRmsLevDb() == null) {
                logger.info("Audio track {} has no RMS Lev dB metadata, analyze it first", audioTrack);
                Job analyzeJob = soxService.analyze(audioTrack);
                if (!waitForStatus(analyzeJob).isSuccess())
                    throw new WorkflowOperationException("Unable to analyze the audio track " + audioTrack);
                audioTrack = (TrackImpl) MediaPackageElementParser.getFromXml(analyzeJob.getPayload());
                cleanupURIs.add(audioTrack.getURI());
            }
            normalizeJobs.put(soxService.normalize(audioTrack, targetDecibel), track);
        }
        if (normalizeJobs.isEmpty()) {
            logger.info("No matching tracks found");
            return createResult(mediaPackage, Action.CONTINUE);
        }
        // Wait for the jobs to return
        if (!waitForStatus(normalizeJobs.keySet().toArray(new Job[normalizeJobs.size()])).isSuccess())
            throw new WorkflowOperationException("One of the normalize jobs did not complete successfully");
        // Process the result
        for (Map.Entry<Job, Track> entry : normalizeJobs.entrySet()) {
            Job job = entry.getKey();
            TrackImpl origTrack = (TrackImpl) entry.getValue();
            // add this receipt's queue time to the total
            totalTimeInQueue += job.getQueueTime();
            if (job.getPayload().length() > 0) {
                TrackImpl normalizedAudioTrack = (TrackImpl) MediaPackageElementParser.getFromXml(job.getPayload());
                TrackImpl resultTrack = normalizedAudioTrack;
                if (origTrack.hasVideo() || forceTranscode) {
                    cleanupURIs.add(normalizedAudioTrack.getURI());
                    logger.info("Mux normalized audio track {} to video track {}", normalizedAudioTrack, origTrack);
                    Job muxAudioVideo = composerService.mux(origTrack, normalizedAudioTrack, SOX_AREPLACE_PROFILE);
                    if (!waitForStatus(muxAudioVideo).isSuccess())
                        throw new WorkflowOperationException("Muxing normalized audio track " + normalizedAudioTrack + " to video container " + origTrack + " failed");
                    resultTrack = (TrackImpl) MediaPackageElementParser.getFromXml(muxAudioVideo.getPayload());
                    // Set metadata on track
                    extendAudioStream(resultTrack, normalizedAudioTrack);
                }
                adjustFlavorAndTags(targetTags, targetFlavor, origTrack, resultTrack);
                mediaPackage.addDerived(resultTrack, origTrack);
                String fileName = getFileNameFromElements(origTrack, resultTrack);
                resultTrack.setURI(workspace.moveTo(resultTrack.getURI(), mediaPackage.getIdentifier().toString(), resultTrack.getIdentifier(), fileName));
            } else {
                logger.warn("Normalize audio job {} for track {} has no result!", job, origTrack);
            }
        }
    } finally {
        // Clean up temporary audio and video files from workspace
        for (URI uri : cleanupURIs) {
            workspace.delete(uri);
        }
    }
    WorkflowOperationResult result = createResult(mediaPackage, Action.CONTINUE, totalTimeInQueue);
    logger.debug("Normalize audio operation completed");
    return result;
}
Also used : HashMap(java.util.HashMap) TrackImpl(org.opencastproject.mediapackage.track.TrackImpl) TrackSelector(org.opencastproject.mediapackage.selector.TrackSelector) ArrayList(java.util.ArrayList) MediaPackageElementFlavor(org.opencastproject.mediapackage.MediaPackageElementFlavor) URI(java.net.URI) WorkflowOperationResult(org.opencastproject.workflow.api.WorkflowOperationResult) MediaPackage(org.opencastproject.mediapackage.MediaPackage) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) Job(org.opencastproject.job.api.Job) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap) Track(org.opencastproject.mediapackage.Track)

Example 37 with WorkflowOperationException

use of org.opencastproject.workflow.api.WorkflowOperationException in project opencast by opencast.

the class AnimateWorkflowOperationHandler method start.

/**
 * {@inheritDoc}
 *
 * @see
 * org.opencastproject.workflow.api.WorkflowOperationHandler#start(org.opencastproject.workflow.api.WorkflowInstance,
 * org.opencastproject.job.api.JobContext)
 */
@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;
    // Check required options
    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);
    }
    // Get optional options
    String targetTagsProperty = StringUtils.trimToNull(operation.getConfiguration(TARGET_TAGS_PROPERTY));
    // Check if we have custom command line options
    String cmd = operation.getConfiguration(COMMANDLINE_ARGUMENTS_PROPERTY);
    if (StringUtils.isNotEmpty(cmd)) {
        arguments = Arrays.asList(StringUtils.split(cmd));
    } else {
        // set default encoding
        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));
    }
    // put animated clip into media package
    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());
        // add track to media package
        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);
}
Also used : InputStream(java.io.InputStream) TrackImpl(org.opencastproject.mediapackage.track.TrackImpl) IOException(java.io.IOException) URI(java.net.URI) MediaPackageElementFlavor(org.opencastproject.mediapackage.MediaPackageElementFlavor) AnimateServiceException(org.opencastproject.animate.api.AnimateServiceException) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) IOException(java.io.IOException) WorkflowOperationInstance(org.opencastproject.workflow.api.WorkflowOperationInstance) AnimateServiceException(org.opencastproject.animate.api.AnimateServiceException) MediaPackage(org.opencastproject.mediapackage.MediaPackage) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) Job(org.opencastproject.job.api.Job) File(java.io.File)

Example 38 with WorkflowOperationException

use of org.opencastproject.workflow.api.WorkflowOperationException in project opencast by opencast.

the class ThemeWorkflowOperationHandler method start.

/**
 * {@inheritDoc}
 *
 * @see org.opencastproject.workflow.api.WorkflowOperationHandler#start(org.opencastproject.workflow.api.WorkflowInstance,
 *      JobContext)
 */
@Override
public WorkflowOperationResult start(final WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
    logger.debug("Running theme workflow operation on workflow {}", workflowInstance.getId());
    final MediaPackageElementFlavor bumperFlavor = getOptConfig(workflowInstance, BUMPER_FLAVOR).map(toMediaPackageElementFlavor).getOr(new MediaPackageElementFlavor("branding", "bumper"));
    final MediaPackageElementFlavor trailerFlavor = getOptConfig(workflowInstance, TRAILER_FLAVOR).map(toMediaPackageElementFlavor).getOr(new MediaPackageElementFlavor("branding", "trailer"));
    final MediaPackageElementFlavor titleSlideFlavor = getOptConfig(workflowInstance, TITLE_SLIDE_FLAVOR).map(toMediaPackageElementFlavor).getOr(new MediaPackageElementFlavor("branding", "title-slide"));
    final MediaPackageElementFlavor licenseSlideFlavor = getOptConfig(workflowInstance, LICENSE_SLIDE_FLAVOR).map(toMediaPackageElementFlavor).getOr(new MediaPackageElementFlavor("branding", "license-slide"));
    final MediaPackageElementFlavor watermarkFlavor = getOptConfig(workflowInstance, WATERMARK_FLAVOR).map(toMediaPackageElementFlavor).getOr(new MediaPackageElementFlavor("branding", "watermark"));
    final List<String> bumperTags = asList(workflowInstance.getConfiguration(BUMPER_TAGS));
    final List<String> trailerTags = asList(workflowInstance.getConfiguration(TRAILER_TAGS));
    final List<String> titleSlideTags = asList(workflowInstance.getConfiguration(TITLE_SLIDE_TAGS));
    final List<String> licenseSlideTags = asList(workflowInstance.getConfiguration(LICENSE_SLIDE_TAGS));
    final List<String> watermarkTags = asList(workflowInstance.getConfiguration(WATERMARK_TAGS));
    Opt<String> layoutStringOpt = getOptConfig(workflowInstance, WATERMARK_LAYOUT);
    Opt<String> watermarkLayoutVariable = getOptConfig(workflowInstance, WATERMARK_LAYOUT_VARIABLE);
    List<String> layoutList = new ArrayList<>(Stream.$(layoutStringOpt).bind(Strings.split(";")).toList());
    try {
        MediaPackage mediaPackage = workflowInstance.getMediaPackage();
        String series = mediaPackage.getSeries();
        if (series == null) {
            logger.info("Skipping theme workflow operation, no series assigned to mediapackage {}", mediaPackage.getIdentifier());
            return createResult(Action.SKIP);
        }
        Long themeId;
        try {
            themeId = Long.parseLong(seriesService.getSeriesProperty(series, THEME_PROPERTY_NAME));
        } catch (NotFoundException e) {
            logger.info("Skipping theme workflow operation, no theme assigned to series {} on mediapackage {}.", series, mediaPackage.getIdentifier());
            return createResult(Action.SKIP);
        } catch (UnauthorizedException e) {
            logger.warn("Skipping theme workflow operation, user not authorized to perform operation: {}", ExceptionUtils.getStackTrace(e));
            return createResult(Action.SKIP);
        }
        Theme theme;
        try {
            theme = themesServiceDatabase.getTheme(themeId);
        } catch (NotFoundException e) {
            logger.warn("Skipping theme workflow operation, no theme with id {} found.", themeId);
            return createResult(Action.SKIP);
        }
        logger.info("Applying theme {} to mediapackage {}", themeId, mediaPackage.getIdentifier());
        /* Make theme settings available to workflow instance */
        workflowInstance.setConfiguration(THEME_ACTIVE, Boolean.toString(theme.isBumperActive() || theme.isTrailerActive() || theme.isTitleSlideActive() || theme.isWatermarkActive()));
        workflowInstance.setConfiguration(THEME_BUMPER_ACTIVE, Boolean.toString(theme.isBumperActive()));
        workflowInstance.setConfiguration(THEME_TRAILER_ACTIVE, Boolean.toString(theme.isTrailerActive()));
        workflowInstance.setConfiguration(THEME_TITLE_SLIDE_ACTIVE, Boolean.toString(theme.isTitleSlideActive()));
        workflowInstance.setConfiguration(THEME_TITLE_SLIDE_UPLOADED, Boolean.toString(StringUtils.isNotBlank(theme.getTitleSlideBackground())));
        workflowInstance.setConfiguration(THEME_WATERMARK_ACTIVE, Boolean.toString(theme.isWatermarkActive()));
        if (theme.isBumperActive() && StringUtils.isNotBlank(theme.getBumperFile())) {
            try (InputStream bumper = staticFileService.getFile(theme.getBumperFile())) {
                addElement(mediaPackage, bumperFlavor, bumperTags, bumper, staticFileService.getFileName(theme.getBumperFile()), Type.Track);
            } catch (NotFoundException e) {
                logger.warn("Bumper file {} not found in static file service, skip applying it", theme.getBumperFile());
            }
        }
        if (theme.isTrailerActive() && StringUtils.isNotBlank(theme.getTrailerFile())) {
            try (InputStream trailer = staticFileService.getFile(theme.getTrailerFile())) {
                addElement(mediaPackage, trailerFlavor, trailerTags, trailer, staticFileService.getFileName(theme.getTrailerFile()), Type.Track);
            } catch (NotFoundException e) {
                logger.warn("Trailer file {} not found in static file service, skip applying it", theme.getTrailerFile());
            }
        }
        if (theme.isTitleSlideActive()) {
            if (StringUtils.isNotBlank(theme.getTitleSlideBackground())) {
                try (InputStream titleSlideBackground = staticFileService.getFile(theme.getTitleSlideBackground())) {
                    addElement(mediaPackage, titleSlideFlavor, titleSlideTags, titleSlideBackground, staticFileService.getFileName(theme.getTitleSlideBackground()), Type.Attachment);
                } catch (NotFoundException e) {
                    logger.warn("Title slide file {} not found in static file service, skip applying it", theme.getTitleSlideBackground());
                }
            }
        // TODO add the title slide metadata to the workflow properties to be used by the cover-image WOH
        // String titleSlideMetadata = theme.getTitleSlideMetadata();
        }
        if (theme.isLicenseSlideActive()) {
            if (StringUtils.isNotBlank(theme.getLicenseSlideBackground())) {
                try (InputStream licenseSlideBackground = staticFileService.getFile(theme.getLicenseSlideBackground())) {
                    addElement(mediaPackage, licenseSlideFlavor, licenseSlideTags, licenseSlideBackground, staticFileService.getFileName(theme.getLicenseSlideBackground()), Type.Attachment);
                } catch (NotFoundException e) {
                    logger.warn("License slide file {} not found in static file service, skip applying it", theme.getLicenseSlideBackground());
                }
            } else {
            // TODO define what to do here (maybe extract image as background)
            }
        // TODO add the license slide description to the workflow properties to be used by the cover-image WOH
        // String licenseSlideDescription = theme.getLicenseSlideDescription();
        }
        if (theme.isWatermarkActive() && StringUtils.isNotBlank(theme.getWatermarkFile())) {
            try (InputStream watermark = staticFileService.getFile(theme.getWatermarkFile())) {
                addElement(mediaPackage, watermarkFlavor, watermarkTags, watermark, staticFileService.getFileName(theme.getWatermarkFile()), Type.Attachment);
            } catch (NotFoundException e) {
                logger.warn("Watermark file {} not found in static file service, skip applying it", theme.getWatermarkFile());
            }
            if (layoutStringOpt.isNone() || watermarkLayoutVariable.isNone())
                throw new WorkflowOperationException(format("Configuration key '%s' or '%s' is either missing or empty", WATERMARK_LAYOUT, WATERMARK_LAYOUT_VARIABLE));
            AbsolutePositionLayoutSpec watermarkLayout = parseLayout(theme.getWatermarkPosition());
            layoutList.set(layoutList.size() - 1, Serializer.json(watermarkLayout).toJson());
            layoutStringOpt = Opt.some(Stream.$(layoutList).mkString(";"));
        }
        if (watermarkLayoutVariable.isSome() && layoutStringOpt.isSome())
            workflowInstance.setConfiguration(watermarkLayoutVariable.get(), layoutStringOpt.get());
        return createResult(mediaPackage, Action.CONTINUE);
    } catch (SeriesException | ThemesServiceDatabaseException | IllegalStateException | IllegalArgumentException | IOException e) {
        throw new WorkflowOperationException(e);
    }
}
Also used : InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) NotFoundException(org.opencastproject.util.NotFoundException) SeriesException(org.opencastproject.series.api.SeriesException) IOException(java.io.IOException) MediaPackageElementFlavor(org.opencastproject.mediapackage.MediaPackageElementFlavor) ThemesServiceDatabaseException(org.opencastproject.themes.persistence.ThemesServiceDatabaseException) MediaPackage(org.opencastproject.mediapackage.MediaPackage) UnauthorizedException(org.opencastproject.security.api.UnauthorizedException) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) Theme(org.opencastproject.themes.Theme) AbsolutePositionLayoutSpec(org.opencastproject.composer.layout.AbsolutePositionLayoutSpec)

Example 39 with WorkflowOperationException

use of org.opencastproject.workflow.api.WorkflowOperationException in project opencast by opencast.

the class TextAnalysisWorkflowOperationHandler method start.

/**
 * {@inheritDoc}
 *
 * @see org.opencastproject.workflow.api.WorkflowOperationHandler#start(org.opencastproject.workflow.api.WorkflowInstance,
 *      JobContext)
 */
@Override
public WorkflowOperationResult start(WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
    logger.debug("Running segments preview workflow operation on {}", workflowInstance);
    // Check if there is an mpeg-7 catalog containing video segments
    MediaPackage src = (MediaPackage) workflowInstance.getMediaPackage().clone();
    Catalog[] segmentCatalogs = src.getCatalogs(MediaPackageElements.SEGMENTS);
    if (segmentCatalogs.length == 0) {
        logger.info("Media package {} does not contain segment information", src);
        return createResult(Action.CONTINUE);
    }
    try {
        return extractVideoText(src, workflowInstance.getCurrentOperation());
    } catch (Exception e) {
        throw new WorkflowOperationException(e);
    }
}
Also used : MediaPackage(org.opencastproject.mediapackage.MediaPackage) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) Catalog(org.opencastproject.mediapackage.Catalog) Mpeg7Catalog(org.opencastproject.metadata.mpeg7.Mpeg7Catalog) ConfigurationException(org.osgi.service.cm.ConfigurationException) ServiceRegistryException(org.opencastproject.serviceregistry.api.ServiceRegistryException) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) TextAnalyzerException(org.opencastproject.textanalyzer.api.TextAnalyzerException) MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) NotFoundException(org.opencastproject.util.NotFoundException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) EncoderException(org.opencastproject.composer.api.EncoderException)

Example 40 with WorkflowOperationException

use of org.opencastproject.workflow.api.WorkflowOperationException in project opencast by opencast.

the class AttachTranscriptionOperationHandler method start.

/**
 * {@inheritDoc}
 *
 * @see org.opencastproject.workflow.api.WorkflowOperationHandler#start(org.opencastproject.workflow.api.WorkflowInstance,
 *      JobContext)
 */
@Override
public WorkflowOperationResult start(final WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
    MediaPackage mediaPackage = workflowInstance.getMediaPackage();
    WorkflowOperationInstance operation = workflowInstance.getCurrentOperation();
    logger.debug("Attach transcription for mediapackage {} started", mediaPackage);
    // Get job id.
    String jobId = StringUtils.trimToNull(operation.getConfiguration(TRANSCRIPTION_JOB_ID));
    if (jobId == null)
        throw new WorkflowOperationException(TRANSCRIPTION_JOB_ID + " missing");
    // Check which tags/flavors have been configured
    String targetTagOption = StringUtils.trimToNull(operation.getConfiguration(TARGET_TAG));
    String targetFlavorOption = StringUtils.trimToNull(operation.getConfiguration(TARGET_FLAVOR));
    String captionFormatOption = StringUtils.trimToNull(operation.getConfiguration(TARGET_CAPTION_FORMAT));
    // Target flavor is mandatory if target-caption-format was NOT informed and no conversion is done
    if (targetFlavorOption == null && captionFormatOption == null)
        throw new WorkflowOperationException(TARGET_FLAVOR + " missing");
    // Target flavor is optional if target-caption-format was informed because the default flavor
    // will be "captions/<format>". If informed, will override the default.
    MediaPackageElementFlavor flavor = null;
    if (targetFlavorOption != null)
        flavor = MediaPackageElementFlavor.parseFlavor(targetFlavorOption);
    try {
        // Get transcription file from the service
        MediaPackageElement original = service.getGeneratedTranscription(mediaPackage.getIdentifier().compact(), jobId);
        MediaPackageElement transcription = original;
        // If caption format passed, convert to desired format
        if (captionFormatOption != null) {
            Job job = captionService.convert(transcription, "ibm-watson", captionFormatOption, service.getLanguage());
            if (!waitForStatus(job).isSuccess()) {
                throw new WorkflowOperationException("Transcription format conversion job did not complete successfully");
            }
            transcription = MediaPackageElementParser.getFromXml(job.getPayload());
        }
        // Set the target flavor if informed
        if (flavor != null)
            transcription.setFlavor(flavor);
        // Add tags
        if (targetTagOption != null) {
            for (String tag : asList(targetTagOption)) {
                if (StringUtils.trimToNull(tag) != null)
                    transcription.addTag(tag);
            }
        }
        // Add to media package
        mediaPackage.add(transcription);
        String uri = transcription.getURI().toString();
        String ext = uri.substring(uri.lastIndexOf("."));
        transcription.setURI(workspace.moveTo(transcription.getURI(), mediaPackage.getIdentifier().toString(), transcription.getIdentifier(), "captions." + ext));
    } catch (Exception e) {
        throw new WorkflowOperationException(e);
    }
    return createResult(mediaPackage, Action.CONTINUE);
}
Also used : WorkflowOperationInstance(org.opencastproject.workflow.api.WorkflowOperationInstance) MediaPackageElement(org.opencastproject.mediapackage.MediaPackageElement) MediaPackage(org.opencastproject.mediapackage.MediaPackage) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) Job(org.opencastproject.job.api.Job) MediaPackageElementFlavor(org.opencastproject.mediapackage.MediaPackageElementFlavor) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException)

Aggregations

WorkflowOperationException (org.opencastproject.workflow.api.WorkflowOperationException)103 MediaPackage (org.opencastproject.mediapackage.MediaPackage)57 Job (org.opencastproject.job.api.Job)47 Track (org.opencastproject.mediapackage.Track)34 IOException (java.io.IOException)31 URI (java.net.URI)28 ArrayList (java.util.ArrayList)28 MediaPackageElementFlavor (org.opencastproject.mediapackage.MediaPackageElementFlavor)28 WorkflowOperationInstance (org.opencastproject.workflow.api.WorkflowOperationInstance)28 MediaPackageElement (org.opencastproject.mediapackage.MediaPackageElement)27 MediaPackageException (org.opencastproject.mediapackage.MediaPackageException)27 NotFoundException (org.opencastproject.util.NotFoundException)27 WorkflowOperationResult (org.opencastproject.workflow.api.WorkflowOperationResult)18 HashMap (java.util.HashMap)17 File (java.io.File)16 InputStream (java.io.InputStream)15 Attachment (org.opencastproject.mediapackage.Attachment)15 TrackSelector (org.opencastproject.mediapackage.selector.TrackSelector)15 ServiceRegistryException (org.opencastproject.serviceregistry.api.ServiceRegistryException)13 HashSet (java.util.HashSet)12