Search in sources :

Example 16 with TrackSelector

use of org.opencastproject.mediapackage.selector.TrackSelector in project opencast by opencast.

the class ComposeWorkflowOperationHandler method encode.

/**
 * Encode tracks from MediaPackage using profiles stored in properties and updates current MediaPackage.
 *
 * @param src
 *          The source media package
 * @param operation
 *          the current workflow operation
 * @return the operation result containing the updated media package
 * @throws EncoderException
 *           if encoding fails
 * @throws WorkflowOperationException
 *           if errors occur during processing
 * @throws IOException
 *           if the workspace operations fail
 * @throws NotFoundException
 *           if the workspace doesn't contain the requested file
 */
private WorkflowOperationResult encode(MediaPackage src, WorkflowOperationInstance operation) throws EncoderException, IOException, NotFoundException, MediaPackageException, WorkflowOperationException {
    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"));
    boolean tagsAndFlavorsOption = Boolean.parseBoolean(StringUtils.trimToNull(operation.getConfiguration("tags-and-flavors")));
    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);
    }
    // Find the encoding profile
    String profilesOption = StringUtils.trimToNull(operation.getConfiguration("encoding-profiles"));
    List<EncodingProfile> profiles = new ArrayList<EncodingProfile>();
    for (String profileName : asList(profilesOption)) {
        EncodingProfile profile = composerService.getProfile(profileName);
        if (profile == null)
            throw new WorkflowOperationException("Encoding profile '" + profileName + "' was not found");
        profiles.add(profile);
    }
    // Support legacy "encoding-profile" option
    String profileOption = StringUtils.trimToNull(operation.getConfiguration("encoding-profile"));
    if (StringUtils.isNotBlank(profileOption)) {
        String profileId = StringUtils.trim(profileOption);
        EncodingProfile profile = composerService.getProfile(profileId);
        if (profile == null)
            throw new WorkflowOperationException("Encoding profile '" + profileId + "' was not found");
        profiles.add(profile);
    }
    // Make sure there is at least one profile
    if (profiles.isEmpty())
        throw new WorkflowOperationException("No encoding profile was specified");
    // Audio / Video only?
    String audioOnlyConfig = StringUtils.trimToNull(operation.getConfiguration("audio-only"));
    String videoOnlyConfig = StringUtils.trimToNull(operation.getConfiguration("video-only"));
    boolean audioOnly = audioOnlyConfig != null && Boolean.parseBoolean(audioOnlyConfig);
    boolean videoOnly = videoOnlyConfig != null && Boolean.parseBoolean(videoOnlyConfig);
    // 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, tagsAndFlavorsOption);
    String processOnlyOneConfig = StringUtils.trimToNull(operation.getConfiguration("process-first-match-only"));
    boolean processOnlyOne = processOnlyOneConfig != null && Boolean.parseBoolean(processOnlyOneConfig);
    // Encode all tracks found
    long totalTimeInQueue = 0;
    Map<Job, JobInformation> encodingJobs = new HashMap<Job, JobInformation>();
    for (Track track : elements) {
        // Skip audio/video only mismatches
        if (audioOnly && track.hasVideo()) {
            logger.info("Skipping encoding of '{}', since it contains a video stream", track);
            continue;
        } else if (videoOnly && track.hasAudio()) {
            logger.info("Skipping encoding of '{}', since it containsa an audio stream", track);
            continue;
        }
        // Encode the track with all profiles
        for (EncodingProfile profile : profiles) {
            // Check if the track supports the output type of the profile
            MediaType outputType = profile.getOutputType();
            if (outputType.equals(MediaType.Audio) && !track.hasAudio()) {
                logger.info("Skipping encoding of '{}', since it lacks an audio stream", track);
                continue;
            } else if (outputType.equals(MediaType.Visual) && !track.hasVideo()) {
                logger.info("Skipping encoding of '{}', since it lacks a video stream", track);
                continue;
            }
            logger.info("Encoding track {} using encoding profile '{}'", track, profile);
            // Start encoding and wait for the result
            encodingJobs.put(composerService.encode(track, profile.getIdentifier()), new JobInformation(track, profile));
            if (processOnlyOne)
                break;
        }
    }
    if (encodingJobs.isEmpty()) {
        logger.info("No matching tracks found");
        return createResult(mediaPackage, Action.CONTINUE);
    }
    // Wait for the jobs to return
    if (!waitForStatus(encodingJobs.keySet().toArray(new Job[encodingJobs.size()])).isSuccess()) {
        throw new WorkflowOperationException("One of the encoding jobs did not complete successfully");
    }
    // Process the result
    for (Map.Entry<Job, JobInformation> entry : encodingJobs.entrySet()) {
        Job job = entry.getKey();
        Track track = entry.getValue().getTrack();
        // add this receipt's queue time to the total
        totalTimeInQueue += job.getQueueTime();
        // it is allowed for compose jobs to return an empty payload. See the EncodeEngine interface
        if (job.getPayload().length() > 0) {
            Track composedTrack = (Track) MediaPackageElementParser.getFromXml(job.getPayload());
            // Adjust the target tags
            for (String tag : targetTags) {
                logger.trace("Tagging composed track with '{}'", tag);
                composedTrack.addTag(tag);
            }
            // Adjust the target flavor. Make sure to account for partial updates
            if (targetFlavor != null) {
                String flavorType = targetFlavor.getType();
                String flavorSubtype = targetFlavor.getSubtype();
                if ("*".equals(flavorType))
                    flavorType = track.getFlavor().getType();
                if ("*".equals(flavorSubtype))
                    flavorSubtype = track.getFlavor().getSubtype();
                composedTrack.setFlavor(new MediaPackageElementFlavor(flavorType, flavorSubtype));
                logger.debug("Composed track has flavor '{}'", composedTrack.getFlavor());
            }
            // store new tracks to mediaPackage
            mediaPackage.addDerived(composedTrack, track);
            String fileName = getFileNameFromElements(track, composedTrack);
            composedTrack.setURI(workspace.moveTo(composedTrack.getURI(), mediaPackage.getIdentifier().toString(), composedTrack.getIdentifier(), fileName));
        }
    }
    WorkflowOperationResult result = createResult(mediaPackage, Action.CONTINUE, totalTimeInQueue);
    logger.debug("Compose operation completed");
    return result;
}
Also used : HashMap(java.util.HashMap) TrackSelector(org.opencastproject.mediapackage.selector.TrackSelector) ArrayList(java.util.ArrayList) EncodingProfile(org.opencastproject.composer.api.EncodingProfile) MediaPackageElementFlavor(org.opencastproject.mediapackage.MediaPackageElementFlavor) WorkflowOperationResult(org.opencastproject.workflow.api.WorkflowOperationResult) MediaPackage(org.opencastproject.mediapackage.MediaPackage) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) MediaType(org.opencastproject.composer.api.EncodingProfile.MediaType) 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 17 with TrackSelector

use of org.opencastproject.mediapackage.selector.TrackSelector in project opencast by opencast.

the class TimelinePreviewsWorkflowOperationHandler 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 timeline previews workflow operation for mediapackage {}", mediaPackage.getIdentifier().compact());
    String sourceFlavorProperty = StringUtils.trimToNull(workflowInstance.getCurrentOperation().getConfiguration(SOURCE_FLAVOR_PROPERTY));
    String sourceTagsProperty = StringUtils.trimToNull(workflowInstance.getCurrentOperation().getConfiguration(SOURCE_TAGS_PROPERTY));
    if (StringUtils.isEmpty(sourceFlavorProperty) && StringUtils.isEmpty(sourceTagsProperty)) {
        throw new WorkflowOperationException(String.format("Required property %s or %s not set", SOURCE_FLAVOR_PROPERTY, SOURCE_TAGS_PROPERTY));
    }
    String targetFlavorProperty = StringUtils.trimToNull(workflowInstance.getCurrentOperation().getConfiguration(TARGET_FLAVOR_PROPERTY));
    if (targetFlavorProperty == null) {
        throw new WorkflowOperationException(String.format("Required property %s not set", TARGET_FLAVOR_PROPERTY));
    }
    String targetTagsProperty = StringUtils.trimToNull(workflowInstance.getCurrentOperation().getConfiguration(TARGET_TAGS_PROPERTY));
    String imageSizeArg = StringUtils.trimToNull(workflowInstance.getCurrentOperation().getConfiguration(IMAGE_SIZE_PROPERTY));
    int imageSize;
    if (imageSizeArg != null) {
        try {
            imageSize = Integer.parseInt(imageSizeArg);
        } catch (NumberFormatException e) {
            imageSize = DEFAULT_IMAGE_SIZE;
            logger.info("No valid integer given for property {}, using default value: {}", IMAGE_SIZE_PROPERTY, DEFAULT_IMAGE_SIZE);
        }
    } else {
        imageSize = DEFAULT_IMAGE_SIZE;
        logger.info("Property {} not set, using default value: {}", IMAGE_SIZE_PROPERTY, DEFAULT_IMAGE_SIZE);
    }
    TrackSelector trackSelector = new TrackSelector();
    for (String flavor : asList(sourceFlavorProperty)) {
        trackSelector.addFlavor(flavor);
    }
    for (String tag : asList(sourceTagsProperty)) {
        trackSelector.addTag(tag);
    }
    Collection<Track> sourceTracks = trackSelector.select(mediaPackage, false);
    if (sourceTracks.isEmpty()) {
        logger.info("No tracks found in mediapackage {} with specified {} {}", mediaPackage.getIdentifier().compact(), SOURCE_FLAVOR_PROPERTY, sourceFlavorProperty);
        createResult(mediaPackage, WorkflowOperationResult.Action.SKIP);
    }
    List<Job> timelinepreviewsJobs = new ArrayList<Job>(sourceTracks.size());
    for (Track sourceTrack : sourceTracks) {
        try {
            // generate timeline preview images
            logger.info("Create timeline previews job for track '{}' in mediapackage '{}'", sourceTrack.getIdentifier(), mediaPackage.getIdentifier().compact());
            Job timelinepreviewsJob = timelinePreviewsService.createTimelinePreviewImages(sourceTrack, imageSize);
            timelinepreviewsJobs.add(timelinepreviewsJob);
        } catch (MediaPackageException | TimelinePreviewsException ex) {
            logger.error("Creating timeline previews job for track '{}' in media package '{}' failed with error {}", sourceTrack.getIdentifier(), mediaPackage.getIdentifier().compact(), ex.getMessage());
        }
    }
    logger.info("Wait for timeline previews jobs for media package {}", mediaPackage.getIdentifier().compact());
    if (!waitForStatus(timelinepreviewsJobs.toArray(new Job[timelinepreviewsJobs.size()])).isSuccess()) {
        cleanupWorkspace(timelinepreviewsJobs);
        throw new WorkflowOperationException(String.format("Timeline previews jobs for media package '%s' have not completed successfully", mediaPackage.getIdentifier().compact()));
    }
    try {
        // copy timeline previews attachments into workspace and add them to the media package
        for (Job job : timelinepreviewsJobs) {
            String jobPayload = job.getPayload();
            if (StringUtils.isNotEmpty(jobPayload)) {
                MediaPackageElement timelinePreviewsMpe = null;
                File timelinePreviewsFile = null;
                try {
                    timelinePreviewsMpe = MediaPackageElementParser.getFromXml(jobPayload);
                    timelinePreviewsFile = workspace.get(timelinePreviewsMpe.getURI());
                } catch (MediaPackageException ex) {
                    // unexpected job payload
                    throw new WorkflowOperationException("Can't parse timeline previews attachment from job " + job.getId());
                } catch (NotFoundException ex) {
                    throw new WorkflowOperationException("Timeline preview images file '" + timelinePreviewsMpe.getURI() + "' not found", ex);
                } catch (IOException ex) {
                    throw new WorkflowOperationException("Can't get workflow image file '" + timelinePreviewsMpe.getURI() + "' from workspace");
                }
                FileInputStream timelinePreviewsInputStream = null;
                logger.info("Put timeline preview images file {} from media package {} to the media package work space", timelinePreviewsMpe.getURI(), mediaPackage.getIdentifier().compact());
                try {
                    timelinePreviewsInputStream = new FileInputStream(timelinePreviewsFile);
                    String fileName = FilenameUtils.getName(timelinePreviewsMpe.getURI().getPath());
                    URI timelinePreviewsWfrUri = workspace.put(mediaPackage.getIdentifier().compact(), timelinePreviewsMpe.getIdentifier(), fileName, timelinePreviewsInputStream);
                    timelinePreviewsMpe.setURI(timelinePreviewsWfrUri);
                } catch (FileNotFoundException ex) {
                    throw new WorkflowOperationException("Timeline preview images file " + timelinePreviewsFile.getPath() + " not found", ex);
                } catch (IOException ex) {
                    throw new WorkflowOperationException("Can't read just created timeline preview images file " + timelinePreviewsFile.getPath(), ex);
                } catch (IllegalArgumentException ex) {
                    throw new WorkflowOperationException(ex);
                } finally {
                    IoSupport.closeQuietly(timelinePreviewsInputStream);
                }
                // set the timeline previews attachment flavor and add it to the mediapackage
                MediaPackageElementFlavor targetFlavor = MediaPackageElementFlavor.parseFlavor(targetFlavorProperty);
                if ("*".equals(targetFlavor.getType())) {
                    targetFlavor = new MediaPackageElementFlavor(timelinePreviewsMpe.getFlavor().getType(), targetFlavor.getSubtype());
                }
                if ("*".equals(targetFlavor.getSubtype())) {
                    targetFlavor = new MediaPackageElementFlavor(targetFlavor.getType(), timelinePreviewsMpe.getFlavor().getSubtype());
                }
                timelinePreviewsMpe.setFlavor(targetFlavor);
                if (!StringUtils.isEmpty(targetTagsProperty)) {
                    for (String tag : asList(targetTagsProperty)) {
                        timelinePreviewsMpe.addTag(tag);
                    }
                }
                mediaPackage.add(timelinePreviewsMpe);
            }
        }
    } finally {
        cleanupWorkspace(timelinepreviewsJobs);
    }
    logger.info("Timeline previews workflow operation for mediapackage {} completed", mediaPackage.getIdentifier().compact());
    return createResult(mediaPackage, WorkflowOperationResult.Action.CONTINUE);
}
Also used : TimelinePreviewsException(org.opencastproject.timelinepreviews.api.TimelinePreviewsException) MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) TrackSelector(org.opencastproject.mediapackage.selector.TrackSelector) ArrayList(java.util.ArrayList) FileNotFoundException(java.io.FileNotFoundException) NotFoundException(org.opencastproject.util.NotFoundException) FileNotFoundException(java.io.FileNotFoundException) IOException(java.io.IOException) URI(java.net.URI) MediaPackageElementFlavor(org.opencastproject.mediapackage.MediaPackageElementFlavor) FileInputStream(java.io.FileInputStream) MediaPackageElement(org.opencastproject.mediapackage.MediaPackageElement) MediaPackage(org.opencastproject.mediapackage.MediaPackage) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) Job(org.opencastproject.job.api.Job) File(java.io.File) Track(org.opencastproject.mediapackage.Track)

Example 18 with TrackSelector

use of org.opencastproject.mediapackage.selector.TrackSelector in project opencast by opencast.

the class StartTranscriptionOperationHandler 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();
    String skipOption = StringUtils.trimToNull(operation.getConfiguration(SKIP_IF_FLAVOR_EXISTS));
    if (skipOption != null) {
        MediaPackageElement[] mpes = mediaPackage.getElementsByFlavor(MediaPackageElementFlavor.parseFlavor(skipOption));
        if (mpes != null && mpes.length > 0) {
            logger.info("Start transcription operation will be skipped because flavor {} already exists in the media package", skipOption);
            return createResult(Action.SKIP);
        }
    }
    logger.debug("Start transcription for mediapackage {} started", mediaPackage);
    // Check which tags have been configured
    String sourceTagOption = StringUtils.trimToNull(operation.getConfiguration(SOURCE_TAG));
    String sourceFlavorOption = StringUtils.trimToNull(operation.getConfiguration(SOURCE_FLAVOR));
    AbstractMediaPackageElementSelector<Track> elementSelector = new TrackSelector();
    // Make sure either one of tags or flavors are provided
    if (StringUtils.isBlank(sourceTagOption) && StringUtils.isBlank(sourceFlavorOption))
        throw new WorkflowOperationException("No source tag or flavor have been specified!");
    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");
        }
    }
    if (sourceTagOption != null)
        elementSelector.addTag(sourceTagOption);
    Collection<Track> elements = elementSelector.select(mediaPackage, false);
    Job job = null;
    for (Track track : elements) {
        if (track.hasVideo()) {
            logger.info("Skipping track {} since it contains a video stream", track);
            continue;
        }
        try {
            job = service.startTranscription(mediaPackage.getIdentifier().compact(), track);
            // Only one job per media package
            break;
        } catch (TranscriptionServiceException e) {
            throw new WorkflowOperationException(e);
        }
    }
    if (job == null) {
        logger.info("No matching tracks found");
        return createResult(mediaPackage, Action.CONTINUE);
    }
    // Wait for the jobs to return
    if (!waitForStatus(job).isSuccess()) {
        throw new WorkflowOperationException("Transcription job did not complete successfully");
    }
    // Return OK means that the ibm watson job was created, but not finished yet
    logger.debug("External transcription job for mediapackage {} was created", mediaPackage);
    // Results are empty, we should get a callback when transcription is done
    return createResult(Action.CONTINUE);
}
Also used : TrackSelector(org.opencastproject.mediapackage.selector.TrackSelector) 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) TranscriptionServiceException(org.opencastproject.transcription.api.TranscriptionServiceException) Track(org.opencastproject.mediapackage.Track)

Example 19 with TrackSelector

use of org.opencastproject.mediapackage.selector.TrackSelector in project opencast by opencast.

the class SilenceDetectionWorkflowOperationHandler method start.

@Override
public WorkflowOperationResult start(WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
    MediaPackage mp = workflowInstance.getMediaPackage();
    logger.debug("Start silence detection workflow operation for mediapackage {}", mp.getIdentifier().compact());
    String sourceFlavors = StringUtils.trimToNull(workflowInstance.getCurrentOperation().getConfiguration(SOURCE_FLAVORS_PROPERTY));
    String sourceFlavor = StringUtils.trimToNull(workflowInstance.getCurrentOperation().getConfiguration(SOURCE_FLAVOR_PROPERTY));
    String smilFlavorSubType = StringUtils.trimToNull(workflowInstance.getCurrentOperation().getConfiguration(SMIL_FLAVOR_SUBTYPE_PROPERTY));
    String smilTargetFlavorString = StringUtils.trimToNull(workflowInstance.getCurrentOperation().getConfiguration(SMIL_TARGET_FLAVOR_PROPERTY));
    MediaPackageElementFlavor smilTargetFlavor = null;
    if (smilTargetFlavorString != null)
        smilTargetFlavor = MediaPackageElementFlavor.parseFlavor(smilTargetFlavorString);
    if (sourceFlavor == null && sourceFlavors == null) {
        throw new WorkflowOperationException(String.format("No %s or %s have been specified", SOURCE_FLAVOR_PROPERTY, SOURCE_FLAVORS_PROPERTY));
    }
    if (smilFlavorSubType == null && smilTargetFlavor == null) {
        throw new WorkflowOperationException(String.format("No %s or %s have been specified", SMIL_FLAVOR_SUBTYPE_PROPERTY, SMIL_TARGET_FLAVOR_PROPERTY));
    }
    if (sourceFlavors != null && smilTargetFlavor != null) {
        throw new WorkflowOperationException(String.format("Can't use %s and %s together", SOURCE_FLAVORS_PROPERTY, SMIL_TARGET_FLAVOR_PROPERTY));
    }
    final String finalSourceFlavors;
    if (smilTargetFlavor != null) {
        finalSourceFlavors = sourceFlavor;
    } else {
        finalSourceFlavors = sourceFlavors;
    }
    String referenceTracksFlavor = StringUtils.trimToNull(workflowInstance.getCurrentOperation().getConfiguration(REFERENCE_TRACKS_FLAVOR_PROPERTY));
    if (referenceTracksFlavor == null)
        referenceTracksFlavor = finalSourceFlavors;
    TrackSelector trackSelector = new TrackSelector();
    for (String flavor : asList(finalSourceFlavors)) {
        trackSelector.addFlavor(flavor);
    }
    Collection<Track> sourceTracks = trackSelector.select(mp, false);
    if (sourceTracks.isEmpty()) {
        logger.info("No source tracks found, skip silence detection");
        return createResult(mp, Action.SKIP);
    }
    trackSelector = new TrackSelector();
    for (String flavor : asList(referenceTracksFlavor)) {
        trackSelector.addFlavor(flavor);
    }
    Collection<Track> referenceTracks = trackSelector.select(mp, false);
    if (referenceTracks.isEmpty()) {
        // REFERENCE_TRACKS_FLAVOR_PROPERTY was set to wrong value
        throw new WorkflowOperationException(String.format("No tracks found filtered by flavor(s) '%s'", referenceTracksFlavor));
    }
    MediaPackageElementBuilder mpeBuilder = MediaPackageElementBuilderFactory.newInstance().newElementBuilder();
    for (Track sourceTrack : sourceTracks) {
        // Skip over track with no audio stream
        if (!sourceTrack.hasAudio()) {
            logger.info("Skipping silence detection of track {} since it has no audio", sourceTrack);
            continue;
        }
        logger.info("Executing silence detection on track {}", sourceTrack.getIdentifier());
        try {
            Job detectionJob = detetionService.detect(sourceTrack, referenceTracks.toArray(new Track[referenceTracks.size()]));
            if (!waitForStatus(detectionJob).isSuccess()) {
                throw new WorkflowOperationException("Silence Detection failed");
            }
            Smil smil = smilService.fromXml(detectionJob.getPayload()).getSmil();
            InputStream is = null;
            try {
                is = IOUtils.toInputStream(smil.toXML(), "UTF-8");
                URI smilURI = workspace.put(mp.getIdentifier().compact(), smil.getId(), TARGET_FILE_NAME, is);
                MediaPackageElementFlavor smilFlavor = smilTargetFlavor;
                if (smilFlavor == null)
                    smilFlavor = new MediaPackageElementFlavor(sourceTrack.getFlavor().getType(), smilFlavorSubType);
                Catalog catalog = (Catalog) mpeBuilder.elementFromURI(smilURI, MediaPackageElement.Type.Catalog, smilFlavor);
                catalog.setIdentifier(smil.getId());
                mp.add(catalog);
            } catch (Exception ex) {
                throw new WorkflowOperationException(String.format("Failed to put smil into workspace. Silence detection for track %s failed", sourceTrack.getIdentifier()), ex);
            } finally {
                IOUtils.closeQuietly(is);
            }
            logger.info("Finished silence detection on track {}", sourceTrack.getIdentifier());
        } catch (SilenceDetectionFailedException ex) {
            throw new WorkflowOperationException(String.format("Failed to create silence detection job for track %s", sourceTrack.getIdentifier()));
        } catch (SmilException ex) {
            throw new WorkflowOperationException(String.format("Failed to get smil from silence detection job for track %s", sourceTrack.getIdentifier()));
        }
    }
    logger.debug("Finished silence detection workflow operation for mediapackage {}", mp.getIdentifier().compact());
    return createResult(mp, Action.CONTINUE);
}
Also used : SilenceDetectionFailedException(org.opencastproject.silencedetection.api.SilenceDetectionFailedException) InputStream(java.io.InputStream) TrackSelector(org.opencastproject.mediapackage.selector.TrackSelector) MediaPackageElementFlavor(org.opencastproject.mediapackage.MediaPackageElementFlavor) URI(java.net.URI) Catalog(org.opencastproject.mediapackage.Catalog) SmilException(org.opencastproject.smil.api.SmilException) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) SilenceDetectionFailedException(org.opencastproject.silencedetection.api.SilenceDetectionFailedException) MediaPackageElementBuilder(org.opencastproject.mediapackage.MediaPackageElementBuilder) MediaPackage(org.opencastproject.mediapackage.MediaPackage) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) Smil(org.opencastproject.smil.entity.api.Smil) SmilException(org.opencastproject.smil.api.SmilException) Job(org.opencastproject.job.api.Job) Track(org.opencastproject.mediapackage.Track)

Example 20 with TrackSelector

use of org.opencastproject.mediapackage.selector.TrackSelector in project opencast by opencast.

the class VideoEditorWorkflowOperationHandlerTest method testEditorOperationInteractiveSkip.

@Test
public void testEditorOperationInteractiveSkip() throws WorkflowOperationException {
    WorkflowInstanceImpl workflowInstance = getWorkflowInstance(mp, getDefaultConfiguration(false));
    WorkflowOperationResult result = videoEditorWorkflowOperationHandler.start(workflowInstance, null);
    Assert.assertNotNull("VideoEditor workflow operation returns null but should be an instantiated WorkflowOperationResult", result);
    // mediapackage should contain new derived track with flavor given by "target-flavor-subtype" configuration
    WorkflowOperationInstance worflowOperationInstance = workflowInstance.getCurrentOperation();
    String targetFlavorSubtypeProperty = worflowOperationInstance.getConfiguration("target-flavor-subtype");
    String skippedFlavorsProperty = worflowOperationInstance.getConfiguration("skipped-flavors");
    TrackSelector trackSelector = new TrackSelector();
    trackSelector.addFlavor(skippedFlavorsProperty);
    Collection<Track> skippedTracks = trackSelector.select(result.getMediaPackage(), false);
    Assert.assertTrue("Mediapackage does not contain any tracks matching flavor " + skippedFlavorsProperty, skippedTracks != null && !skippedTracks.isEmpty());
    for (Track skippedTrack : skippedTracks) {
        MediaPackageElementFlavor derivedTrackFlavor = MediaPackageElementFlavor.flavor(skippedTrack.getFlavor().getType(), targetFlavorSubtypeProperty);
        MediaPackageElement[] derivedElements = result.getMediaPackage().getDerived(skippedTrack, derivedTrackFlavor);
        Assert.assertTrue("Media package should contain track with flavor " + derivedTrackFlavor.toString(), derivedElements != null && derivedElements.length > 0);
    }
}
Also used : WorkflowInstanceImpl(org.opencastproject.workflow.api.WorkflowInstanceImpl) WorkflowOperationInstance(org.opencastproject.workflow.api.WorkflowOperationInstance) MediaPackageElement(org.opencastproject.mediapackage.MediaPackageElement) TrackSelector(org.opencastproject.mediapackage.selector.TrackSelector) MediaPackageElementFlavor(org.opencastproject.mediapackage.MediaPackageElementFlavor) WorkflowOperationResult(org.opencastproject.workflow.api.WorkflowOperationResult) Track(org.opencastproject.mediapackage.Track) Test(org.junit.Test)

Aggregations

TrackSelector (org.opencastproject.mediapackage.selector.TrackSelector)25 Track (org.opencastproject.mediapackage.Track)17 MediaPackageElementFlavor (org.opencastproject.mediapackage.MediaPackageElementFlavor)16 WorkflowOperationException (org.opencastproject.workflow.api.WorkflowOperationException)15 MediaPackage (org.opencastproject.mediapackage.MediaPackage)12 Job (org.opencastproject.job.api.Job)11 Test (org.junit.Test)9 WorkflowOperationResult (org.opencastproject.workflow.api.WorkflowOperationResult)9 URI (java.net.URI)8 WorkflowOperationInstance (org.opencastproject.workflow.api.WorkflowOperationInstance)8 ArrayList (java.util.ArrayList)7 MediaPackageElement (org.opencastproject.mediapackage.MediaPackageElement)7 HashMap (java.util.HashMap)6 MediaPackageException (org.opencastproject.mediapackage.MediaPackageException)5 IOException (java.io.IOException)4 Map (java.util.Map)4 SortedMap (java.util.SortedMap)4 TreeMap (java.util.TreeMap)4 EncodingProfile (org.opencastproject.composer.api.EncodingProfile)4 NotFoundException (org.opencastproject.util.NotFoundException)4