Search in sources :

Example 6 with MediaPackageException

use of org.opencastproject.mediapackage.MediaPackageException in project opencast by opencast.

the class InspectWorkflowOperationHandler 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 {
    MediaPackage mediaPackage = (MediaPackage) workflowInstance.getMediaPackage().clone();
    // Inspect the tracks
    long totalTimeInQueue = 0;
    WorkflowOperationInstance operation = workflowInstance.getCurrentOperation();
    boolean rewrite = "true".equalsIgnoreCase(operation.getConfiguration(OPT_OVERWRITE));
    boolean acceptNoMedia = "true".equalsIgnoreCase(operation.getConfiguration(OPT_ACCEPT_NO_MEDIA));
    final Map<String, String> options = new HashMap<String, String>();
    if ("true".equalsIgnoreCase(operation.getConfiguration(OPT_ACCURATE_FRAME_COUNT))) {
        logger.info("Using accurate frame count for inspection media package {}", mediaPackage);
        options.put(MediaInspectionOptions.OPTION_ACCURATE_FRAME_COUNT, Boolean.TRUE.toString());
    }
    // Test if there are tracks in the mediapackage
    if (mediaPackage.getTracks().length == 0) {
        logger.warn("Recording {} contains no media", mediaPackage);
        if (!acceptNoMedia)
            throw new WorkflowOperationException("Mediapackage " + mediaPackage + " contains no media");
    }
    for (Track track : mediaPackage.getTracks()) {
        logger.info("Inspecting track '{}' of {}", track.getIdentifier(), mediaPackage);
        Job inspectJob = null;
        Track inspectedTrack;
        if (track != null && track.getURI() != null && (track.getURI().toString().endsWith(".vtt") || track.getURI().toString().endsWith(".srt"))) {
            inspectedTrack = (Track) track.clone();
            inspectedTrack.setMimeType(MimeType.mimeType("text", "vtt"));
            logger.info("Track '{}' of {} contains captions", track.getIdentifier(), mediaPackage);
        } else {
            try {
                inspectJob = inspectionService.enrich(track, rewrite, options);
                if (!waitForStatus(inspectJob).isSuccess()) {
                    throw new WorkflowOperationException("Track " + track + " could not be inspected");
                }
            } catch (MediaInspectionException e) {
                throw new WorkflowOperationException("Error inspecting media package", e);
            } catch (MediaPackageException e) {
                throw new WorkflowOperationException("Error parsing media package", e);
            }
            // add this receipt's queue and execution times to the total
            long timeInQueue = inspectJob.getQueueTime() == null ? 0 : inspectJob.getQueueTime();
            totalTimeInQueue += timeInQueue;
            try {
                inspectedTrack = (Track) MediaPackageElementParser.getFromXml(inspectJob.getPayload());
            } catch (MediaPackageException e) {
                throw new WorkflowOperationException("Unable to parse track from job " + inspectJob.getId(), e);
            }
            if (inspectedTrack == null)
                throw new WorkflowOperationException("Track " + track + " could not be inspected");
            if (inspectedTrack.getStreams().length == 0)
                throw new WorkflowOperationException(format("Track %s does not contain any streams", track));
        }
        // Replace the original track with the inspected one
        try {
            mediaPackage.remove(track);
            mediaPackage.add(inspectedTrack);
        } catch (UnsupportedElementException e) {
            logger.error("Error adding {} to media package", inspectedTrack, e);
        }
    }
    // Update dublin core with metadata
    try {
        updateDublinCore(mediaPackage);
    } catch (Exception e) {
        logger.warn("Unable to update dublin core data: {}", e.getMessage(), e);
        throw new WorkflowOperationException(e.getMessage());
    }
    return createResult(mediaPackage, Action.CONTINUE, totalTimeInQueue);
}
Also used : MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) HashMap(java.util.HashMap) UnsupportedElementException(org.opencastproject.mediapackage.UnsupportedElementException) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) MediaInspectionException(org.opencastproject.inspection.api.MediaInspectionException) NotFoundException(org.opencastproject.util.NotFoundException) IOException(java.io.IOException) MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) MediaInspectionException(org.opencastproject.inspection.api.MediaInspectionException) WorkflowOperationInstance(org.opencastproject.workflow.api.WorkflowOperationInstance) UnsupportedElementException(org.opencastproject.mediapackage.UnsupportedElementException) MediaPackage(org.opencastproject.mediapackage.MediaPackage) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) Job(org.opencastproject.job.api.Job) Track(org.opencastproject.mediapackage.Track)

Example 7 with MediaPackageException

use of org.opencastproject.mediapackage.MediaPackageException in project opencast by opencast.

the class IndexServiceImpl method createEvent.

@Override
public String createEvent(EventHttpServletRequest eventHttpServletRequest) throws ParseException, IOException, MediaPackageException, IngestException, NotFoundException, SchedulerException, UnauthorizedException {
    // Preconditions
    if (eventHttpServletRequest.getAcl().isNone()) {
        throw new IllegalArgumentException("No access control list available to create new event.");
    }
    if (eventHttpServletRequest.getMediaPackage().isNone()) {
        throw new IllegalArgumentException("No mediapackage available to create new event.");
    }
    if (eventHttpServletRequest.getMetadataList().isNone()) {
        throw new IllegalArgumentException("No metadata list available to create new event.");
    }
    if (eventHttpServletRequest.getProcessing().isNone()) {
        throw new IllegalArgumentException("No processing metadata available to create new event.");
    }
    if (eventHttpServletRequest.getSource().isNone()) {
        throw new IllegalArgumentException("No source field metadata available to create new event.");
    }
    // Get Workflow
    String workflowTemplate = (String) eventHttpServletRequest.getProcessing().get().get("workflow");
    if (workflowTemplate == null)
        throw new IllegalArgumentException("No workflow template in metadata");
    // Get Type of Source
    SourceType type = getSourceType(eventHttpServletRequest.getSource().get());
    MetadataCollection eventMetadata = eventHttpServletRequest.getMetadataList().get().getMetadataByAdapter(eventCatalogUIAdapter).get();
    JSONObject sourceMetadata = (JSONObject) eventHttpServletRequest.getSource().get().get("metadata");
    if (sourceMetadata != null && (type.equals(SourceType.SCHEDULE_SINGLE) || type.equals(SourceType.SCHEDULE_MULTIPLE))) {
        try {
            MetadataField<?> current = eventMetadata.getOutputFields().get("location");
            eventMetadata.updateStringField(current, (String) sourceMetadata.get("device"));
        } catch (Exception e) {
            logger.warn("Unable to parse device {}", sourceMetadata.get("device"));
            throw new IllegalArgumentException("Unable to parse device");
        }
    }
    Date currentStartDate = null;
    MetadataField<?> starttime = eventMetadata.getOutputFields().get(DublinCore.PROPERTY_TEMPORAL.getLocalName());
    if (starttime != null && starttime.isUpdated() && starttime.getValue().isSome()) {
        DCMIPeriod period = EncodingSchemeUtils.decodeMandatoryPeriod((DublinCoreValue) starttime.getValue().get());
        currentStartDate = period.getStart();
    }
    MetadataField<?> created = eventMetadata.getOutputFields().get(DublinCore.PROPERTY_CREATED.getLocalName());
    if (created == null || !created.isUpdated() || created.getValue().isNone()) {
        eventMetadata.removeField(created);
        MetadataField<String> newCreated = MetadataUtils.copyMetadataField(created);
        if (currentStartDate != null) {
            newCreated.setValue(EncodingSchemeUtils.encodeDate(currentStartDate, Precision.Second).getValue());
        } else {
            newCreated.setValue(EncodingSchemeUtils.encodeDate(new Date(), Precision.Second).getValue());
        }
        eventMetadata.addField(newCreated);
    }
    // Get presenter usernames for use as technical presenters
    Set<String> presenterUsernames = new HashSet<>();
    Opt<Set<String>> technicalPresenters = updatePresenters(eventMetadata);
    if (technicalPresenters.isSome()) {
        presenterUsernames = technicalPresenters.get();
    }
    eventHttpServletRequest.getMetadataList().get().add(eventCatalogUIAdapter, eventMetadata);
    updateMediaPackageMetadata(eventHttpServletRequest.getMediaPackage().get(), eventHttpServletRequest.getMetadataList().get());
    DublinCoreCatalog dc = getDublinCoreCatalog(eventHttpServletRequest);
    String captureAgentId = null;
    TimeZone tz = null;
    org.joda.time.DateTime start = null;
    org.joda.time.DateTime end = null;
    long duration = 0L;
    Properties caProperties = new Properties();
    RRule rRule = null;
    if (sourceMetadata != null && (type.equals(SourceType.SCHEDULE_SINGLE) || type.equals(SourceType.SCHEDULE_MULTIPLE))) {
        Properties configuration;
        try {
            captureAgentId = (String) sourceMetadata.get("device");
            configuration = captureAgentStateService.getAgentConfiguration((String) sourceMetadata.get("device"));
        } catch (Exception e) {
            logger.warn("Unable to parse device {}: because: {}", sourceMetadata.get("device"), getStackTrace(e));
            throw new IllegalArgumentException("Unable to parse device");
        }
        String durationString = (String) sourceMetadata.get("duration");
        if (StringUtils.isBlank(durationString))
            throw new IllegalArgumentException("No duration in source metadata");
        // Create timezone based on CA's reported TZ.
        String agentTimeZone = configuration.getProperty("capture.device.timezone");
        if (StringUtils.isNotBlank(agentTimeZone)) {
            tz = TimeZone.getTimeZone(agentTimeZone);
            dc.set(DublinCores.OC_PROPERTY_AGENT_TIMEZONE, tz.getID());
        } else {
            // No timezone was present, assume the serve's local timezone.
            tz = TimeZone.getDefault();
            logger.debug("The field 'capture.device.timezone' has not been set in the agent configuration. The default server timezone will be used.");
        }
        org.joda.time.DateTime now = new org.joda.time.DateTime(DateTimeZone.UTC);
        start = now.withMillis(DateTimeSupport.fromUTC((String) sourceMetadata.get("start")));
        end = now.withMillis(DateTimeSupport.fromUTC((String) sourceMetadata.get("end")));
        duration = Long.parseLong(durationString);
        DublinCoreValue period = EncodingSchemeUtils.encodePeriod(new DCMIPeriod(start.toDate(), start.plus(duration).toDate()), Precision.Second);
        String inputs = (String) sourceMetadata.get("inputs");
        caProperties.putAll(configuration);
        dc.set(DublinCore.PROPERTY_TEMPORAL, period);
        caProperties.put(CaptureParameters.CAPTURE_DEVICE_NAMES, inputs);
    }
    if (type.equals(SourceType.SCHEDULE_MULTIPLE)) {
        rRule = new RRule((String) sourceMetadata.get("rrule"));
    }
    Map<String, String> configuration = new HashMap<>();
    if (eventHttpServletRequest.getProcessing().get().get("configuration") != null) {
        configuration = new HashMap<>((JSONObject) eventHttpServletRequest.getProcessing().get().get("configuration"));
    }
    for (Entry<String, String> entry : configuration.entrySet()) {
        caProperties.put(WORKFLOW_CONFIG_PREFIX.concat(entry.getKey()), entry.getValue());
    }
    caProperties.put(CaptureParameters.INGEST_WORKFLOW_DEFINITION, workflowTemplate);
    eventHttpServletRequest.setMediaPackage(authorizationService.setAcl(eventHttpServletRequest.getMediaPackage().get(), AclScope.Episode, eventHttpServletRequest.getAcl().get()).getA());
    MediaPackage mediaPackage;
    switch(type) {
        case UPLOAD:
        case UPLOAD_LATER:
            eventHttpServletRequest.setMediaPackage(updateDublincCoreCatalog(eventHttpServletRequest.getMediaPackage().get(), dc));
            configuration.put("workflowDefinitionId", workflowTemplate);
            WorkflowInstance ingest = ingestService.ingest(eventHttpServletRequest.getMediaPackage().get(), workflowTemplate, configuration);
            return eventHttpServletRequest.getMediaPackage().get().getIdentifier().compact();
        case SCHEDULE_SINGLE:
            mediaPackage = updateDublincCoreCatalog(eventHttpServletRequest.getMediaPackage().get(), dc);
            eventHttpServletRequest.setMediaPackage(mediaPackage);
            try {
                schedulerService.addEvent(start.toDate(), start.plus(duration).toDate(), captureAgentId, presenterUsernames, mediaPackage, configuration, (Map) caProperties, Opt.<Boolean>none(), Opt.<String>none(), SchedulerService.ORIGIN);
            } finally {
                for (MediaPackageElement mediaPackageElement : mediaPackage.getElements()) {
                    try {
                        workspace.delete(mediaPackage.getIdentifier().toString(), mediaPackageElement.getIdentifier());
                    } catch (NotFoundException | IOException e) {
                        logger.warn("Failed to delete media package element", e);
                    }
                }
            }
            return mediaPackage.getIdentifier().compact();
        case SCHEDULE_MULTIPLE:
            List<Period> periods = schedulerService.calculatePeriods(rRule, start.toDate(), end.toDate(), duration, tz);
            Map<String, Period> scheduled = new LinkedHashMap<>();
            scheduled = schedulerService.addMultipleEvents(rRule, start.toDate(), end.toDate(), duration, tz, captureAgentId, presenterUsernames, eventHttpServletRequest.getMediaPackage().get(), configuration, (Map) caProperties, Opt.none(), Opt.none(), SchedulerService.ORIGIN);
            return StringUtils.join(scheduled.keySet(), ",");
        default:
            logger.warn("Unknown source type {}", type);
            throw new IllegalArgumentException("Unknown source type");
    }
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) WorkflowSet(org.opencastproject.workflow.api.WorkflowSet) RRule(net.fortuna.ical4j.model.property.RRule) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) NotFoundException(org.opencastproject.util.NotFoundException) Properties(java.util.Properties) WorkflowInstance(org.opencastproject.workflow.api.WorkflowInstance) LinkedHashMap(java.util.LinkedHashMap) MediaPackageElement(org.opencastproject.mediapackage.MediaPackageElement) MetadataCollection(org.opencastproject.metadata.dublincore.MetadataCollection) HashSet(java.util.HashSet) DublinCoreValue(org.opencastproject.metadata.dublincore.DublinCoreValue) DCMIPeriod(org.opencastproject.metadata.dublincore.DCMIPeriod) Period(net.fortuna.ical4j.model.Period) DCMIPeriod(org.opencastproject.metadata.dublincore.DCMIPeriod) IOException(java.io.IOException) SchedulerException(org.opencastproject.scheduler.api.SchedulerException) IngestException(org.opencastproject.ingest.api.IngestException) WebApplicationException(javax.ws.rs.WebApplicationException) MetadataParsingException(org.opencastproject.metadata.dublincore.MetadataParsingException) EventCommentException(org.opencastproject.event.comment.EventCommentException) IOException(java.io.IOException) JSONException(org.codehaus.jettison.json.JSONException) SearchIndexException(org.opencastproject.matterhorn.search.SearchIndexException) ParseException(java.text.ParseException) SeriesException(org.opencastproject.series.api.SeriesException) WorkflowException(org.opencastproject.workflow.api.WorkflowException) MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) IndexServiceException(org.opencastproject.index.service.exception.IndexServiceException) UnauthorizedException(org.opencastproject.security.api.UnauthorizedException) NotFoundException(org.opencastproject.util.NotFoundException) WorkflowDatabaseException(org.opencastproject.workflow.api.WorkflowDatabaseException) AssetManagerException(org.opencastproject.assetmanager.api.AssetManagerException) Date(java.util.Date) DateTimeZone(org.joda.time.DateTimeZone) TimeZone(java.util.TimeZone) JSONObject(org.json.simple.JSONObject) MediaPackage(org.opencastproject.mediapackage.MediaPackage) DublinCoreCatalog(org.opencastproject.metadata.dublincore.DublinCoreCatalog) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap)

Example 8 with MediaPackageException

use of org.opencastproject.mediapackage.MediaPackageException in project opencast by opencast.

the class PartialImportWorkflowOperationHandler method concat.

private WorkflowOperationResult concat(MediaPackage src, WorkflowOperationInstance operation, List<MediaPackageElement> elementsToClean) throws EncoderException, IOException, NotFoundException, MediaPackageException, WorkflowOperationException, ServiceRegistryException {
    final MediaPackage mediaPackage = (MediaPackage) src.clone();
    final Long operationId = operation.getId();
    // 
    // read config options
    final Opt<String> presenterFlavor = getOptConfig(operation, SOURCE_PRESENTER_FLAVOR);
    final Opt<String> presentationFlavor = getOptConfig(operation, SOURCE_PRESENTATION_FLAVOR);
    final String smilFlavor = getConfig(operation, SOURCE_SMIL_FLAVOR);
    final String concatEncodingProfile = getConfig(operation, CONCAT_ENCODING_PROFILE);
    final Opt<String> concatOutputFramerate = getOptConfig(operation, CONCAT_OUTPUT_FRAMERATE);
    final String trimEncodingProfile = getConfig(operation, TRIM_ENCODING_PROFILE);
    final MediaPackageElementFlavor targetPresenterFlavor = parseTargetFlavor(getConfig(operation, TARGET_PRESENTER_FLAVOR), "presenter");
    final MediaPackageElementFlavor targetPresentationFlavor = parseTargetFlavor(getConfig(operation, TARGET_PRESENTATION_FLAVOR), "presentation");
    final Opt<EncodingProfile> forceProfile = getForceEncodingProfile(operation);
    final boolean forceEncoding = BooleanUtils.toBoolean(getOptConfig(operation, FORCE_ENCODING).getOr("false"));
    final boolean forceDivisible = BooleanUtils.toBoolean(getOptConfig(operation, ENFORCE_DIVISIBLE_BY_TWO).getOr("false"));
    final List<String> requiredExtensions = getRequiredExtensions(operation);
    // Skip the worklow if no presenter and presentation flavor has been configured
    if (presenterFlavor.isNone() && presentationFlavor.isNone()) {
        logger.warn("No presenter and presentation flavor has been set.");
        return createResult(mediaPackage, Action.SKIP);
    }
    final EncodingProfile concatProfile = composerService.getProfile(concatEncodingProfile);
    if (concatProfile == null) {
        throw new WorkflowOperationException("Concat encoding profile '" + concatEncodingProfile + "' was not found");
    }
    float outputFramerate = -1.0f;
    if (concatOutputFramerate.isSome()) {
        if (NumberUtils.isNumber(concatOutputFramerate.get())) {
            logger.info("Using concat output framerate");
            outputFramerate = NumberUtils.toFloat(concatOutputFramerate.get());
        } else {
            throw new WorkflowOperationException("Unable to parse concat output frame rate!");
        }
    }
    final EncodingProfile trimProfile = composerService.getProfile(trimEncodingProfile);
    if (trimProfile == null) {
        throw new WorkflowOperationException("Trim encoding profile '" + trimEncodingProfile + "' was not found");
    }
    // 
    // get tracks
    final TrackSelector presenterTrackSelector = mkTrackSelector(presenterFlavor);
    final TrackSelector presentationTrackSelector = mkTrackSelector(presentationFlavor);
    final List<Track> originalTracks = new ArrayList<Track>();
    final List<Track> presenterTracks = new ArrayList<Track>();
    final List<Track> presentationTracks = new ArrayList<Track>();
    // Collecting presenter tracks
    for (Track t : presenterTrackSelector.select(mediaPackage, false)) {
        logger.info("Found partial presenter track {}", t);
        originalTracks.add(t);
        presenterTracks.add(t);
    }
    // Collecting presentation tracks
    for (Track t : presentationTrackSelector.select(mediaPackage, false)) {
        logger.info("Found partial presentation track {}", t);
        originalTracks.add(t);
        presentationTracks.add(t);
    }
    // flavor_type -> job
    final Map<String, Job> jobs = new HashMap<String, Job>();
    // get SMIL catalog
    final SMILDocument smilDocument = getSmilDocumentFromMediaPackage(mediaPackage, smilFlavor);
    final SMILParElement parallel = (SMILParElement) smilDocument.getBody().getChildNodes().item(0);
    final NodeList sequences = parallel.getTimeChildren();
    final float trackDurationInSeconds = parallel.getDur();
    final long trackDurationInMs = Math.round(trackDurationInSeconds * 1000f);
    for (int i = 0; i < sequences.getLength(); i++) {
        final SMILElement item = (SMILElement) sequences.item(i);
        for (final String mediaType : new String[] { NODE_TYPE_AUDIO, NODE_TYPE_VIDEO }) {
            final List<Track> tracks = new ArrayList<Track>();
            final VCell<String> sourceType = VCell.cell(EMPTY_VALUE);
            final long position = processChildren(0, tracks, item.getChildNodes(), originalTracks, sourceType, mediaType, elementsToClean, operationId);
            if (tracks.isEmpty()) {
                logger.debug("The tracks list was empty.");
                continue;
            }
            final Track lastTrack = tracks.get(tracks.size() - 1);
            if (position < trackDurationInMs) {
                final double extendingTime = (trackDurationInMs - position) / 1000d;
                if (extendingTime > 0) {
                    if (!lastTrack.hasVideo()) {
                        logger.info("Extending {} audio track end by {} seconds with silent audio", sourceType.get(), extendingTime);
                        tracks.add(getSilentAudio(extendingTime, elementsToClean, operationId));
                    } else {
                        logger.info("Extending {} track end with last image frame by {} seconds", sourceType.get(), extendingTime);
                        Attachment tempLastImageFrame = extractLastImageFrame(lastTrack, elementsToClean);
                        tracks.add(createVideoFromImage(tempLastImageFrame, extendingTime, elementsToClean));
                    }
                }
            }
            if (tracks.size() < 2) {
                logger.debug("There were less than 2 tracks, copying track...");
                if (sourceType.get().startsWith(PRESENTER_KEY)) {
                    createCopyOfTrack(mediaPackage, tracks.get(0), targetPresenterFlavor);
                } else if (sourceType.get().startsWith(PRESENTATION_KEY)) {
                    createCopyOfTrack(mediaPackage, tracks.get(0), targetPresentationFlavor);
                } else {
                    logger.warn("Can't handle unkown source type '{}' for unprocessed track", sourceType.get());
                }
                continue;
            }
            for (final Track t : tracks) {
                if (!t.hasVideo() && !t.hasAudio()) {
                    logger.error("No audio or video stream available in the track with flavor {}! {}", t.getFlavor(), t);
                    throw new WorkflowOperationException("No audio or video stream available in the track " + t.toString());
                }
            }
            if (sourceType.get().startsWith(PRESENTER_KEY)) {
                logger.info("Concatenating {} track", PRESENTER_KEY);
                jobs.put(sourceType.get(), startConcatJob(concatProfile, tracks, outputFramerate, forceDivisible));
            } else if (sourceType.get().startsWith(PRESENTATION_KEY)) {
                logger.info("Concatenating {} track", PRESENTATION_KEY);
                jobs.put(sourceType.get(), startConcatJob(concatProfile, tracks, outputFramerate, forceDivisible));
            } else {
                logger.warn("Can't handle unknown source type '{}'!", sourceType.get());
            }
        }
    }
    // Wait for the jobs to return
    if (jobs.size() > 0) {
        if (!JobUtil.waitForJobs(serviceRegistry, jobs.values()).isSuccess()) {
            throw new WorkflowOperationException("One of the concat jobs did not complete successfully");
        }
    } else {
        logger.info("No concatenating needed for presenter and presentation tracks, took partial source elements");
    }
    // All the jobs have passed, let's update the media package
    long queueTime = 0L;
    MediaPackageElementFlavor adjustedTargetPresenterFlavor = targetPresenterFlavor;
    MediaPackageElementFlavor adjustedTargetPresentationFlavor = targetPresentationFlavor;
    for (final Entry<String, Job> job : jobs.entrySet()) {
        final Opt<Job> concatJob = JobUtil.update(serviceRegistry, job.getValue());
        if (concatJob.isSome()) {
            final String concatPayload = concatJob.get().getPayload();
            if (concatPayload != null) {
                final Track concatTrack;
                try {
                    concatTrack = (Track) MediaPackageElementParser.getFromXml(concatPayload);
                } catch (MediaPackageException e) {
                    throw new WorkflowOperationException(e);
                }
                final String fileName;
                // Adjust the target flavor.
                if (job.getKey().startsWith(PRESENTER_KEY)) {
                    if (!concatTrack.hasVideo()) {
                        fileName = PRESENTER_KEY.concat(FLAVOR_AUDIO_SUFFIX);
                        adjustedTargetPresenterFlavor = deriveAudioFlavor(targetPresenterFlavor);
                    } else {
                        fileName = PRESENTER_KEY;
                        adjustedTargetPresenterFlavor = targetPresenterFlavor;
                    }
                    concatTrack.setFlavor(adjustedTargetPresenterFlavor);
                } else if (job.getKey().startsWith(PRESENTATION_KEY)) {
                    if (!concatTrack.hasVideo()) {
                        fileName = PRESENTATION_KEY.concat(FLAVOR_AUDIO_SUFFIX);
                        adjustedTargetPresentationFlavor = deriveAudioFlavor(targetPresentationFlavor);
                    } else {
                        fileName = PRESENTATION_KEY;
                        adjustedTargetPresentationFlavor = targetPresentationFlavor;
                    }
                    concatTrack.setFlavor(adjustedTargetPresentationFlavor);
                } else {
                    fileName = UNKNOWN_KEY;
                }
                concatTrack.setURI(workspace.moveTo(concatTrack.getURI(), mediaPackage.getIdentifier().toString(), concatTrack.getIdentifier(), fileName + "." + FilenameUtils.getExtension(concatTrack.getURI().toString())));
                logger.info("Concatenated track {} got flavor '{}'", concatTrack, concatTrack.getFlavor());
                mediaPackage.add(concatTrack);
                queueTime += concatJob.get().getQueueTime();
            } else {
                // If there is no payload, then the item has not been distributed.
                logger.warn("Concat job {} does not contain a payload", concatJob);
            }
        } else {
            logger.warn("Concat job {} could not be updated since it cannot be found", job.getValue());
        }
    }
    // Trim presenter and presentation source track if longer than the duration from the SMIL catalog
    queueTime += checkForTrimming(mediaPackage, trimProfile, targetPresentationFlavor, trackDurationInSeconds, elementsToClean);
    queueTime += checkForTrimming(mediaPackage, trimProfile, deriveAudioFlavor(targetPresentationFlavor), trackDurationInSeconds, elementsToClean);
    queueTime += checkForTrimming(mediaPackage, trimProfile, targetPresenterFlavor, trackDurationInSeconds, elementsToClean);
    queueTime += checkForTrimming(mediaPackage, trimProfile, deriveAudioFlavor(targetPresenterFlavor), trackDurationInSeconds, elementsToClean);
    adjustAudioTrackTargetFlavor(mediaPackage, targetPresenterFlavor);
    adjustAudioTrackTargetFlavor(mediaPackage, targetPresentationFlavor);
    queueTime += checkForMuxing(mediaPackage, targetPresenterFlavor, targetPresentationFlavor, false, elementsToClean);
    queueTime += checkForEncodeToStandard(mediaPackage, forceEncoding, forceProfile, requiredExtensions, targetPresenterFlavor, targetPresentationFlavor, elementsToClean);
    final WorkflowOperationResult result = createResult(mediaPackage, Action.CONTINUE, queueTime);
    logger.debug("Partial import operation completed");
    return result;
}
Also used : HashMap(java.util.HashMap) TrackSelector(org.opencastproject.mediapackage.selector.TrackSelector) ArrayList(java.util.ArrayList) SMILElement(org.w3c.dom.smil.SMILElement) Attachment(org.opencastproject.mediapackage.Attachment) WorkflowOperationResult(org.opencastproject.workflow.api.WorkflowOperationResult) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) SMILParElement(org.w3c.dom.smil.SMILParElement) Job(org.opencastproject.job.api.Job) MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) SMILDocument(org.w3c.dom.smil.SMILDocument) NodeList(org.w3c.dom.NodeList) EncodingProfile(org.opencastproject.composer.api.EncodingProfile) MediaPackageElementFlavor(org.opencastproject.mediapackage.MediaPackageElementFlavor) MediaPackage(org.opencastproject.mediapackage.MediaPackage) Track(org.opencastproject.mediapackage.Track)

Example 9 with MediaPackageException

use of org.opencastproject.mediapackage.MediaPackageException in project opencast by opencast.

the class ComposerServiceTest method setUp.

@Before
public void setUp() throws Exception {
    // Skip tests if FFmpeg is not installed
    Assume.assumeTrue(ffmpegInstalled);
    // Create video only file
    File f = getFile("/video.mp4");
    sourceVideoOnly = File.createTempFile(FilenameUtils.getBaseName(f.getName()), ".mp4", testDir);
    FileUtils.copyFile(f, sourceVideoOnly);
    // Create another audio only file
    f = getFile("/audio.mp3");
    sourceAudioOnly = File.createTempFile(FilenameUtils.getBaseName(f.getName()), ".mp3", testDir);
    FileUtils.copyFile(f, sourceAudioOnly);
    // Create an image file
    f = getFile("/image.jpg");
    sourceImage = File.createTempFile(FilenameUtils.getBaseName(f.getName()), ".jpg", testDir);
    FileUtils.copyFile(f, sourceImage);
    // create the needed mocks
    BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
    EasyMock.expect(bc.getProperty(EasyMock.anyString())).andReturn(FFMPEG_BINARY);
    ComponentContext cc = EasyMock.createNiceMock(ComponentContext.class);
    EasyMock.expect(cc.getBundleContext()).andReturn(bc).anyTimes();
    JaxbOrganization org = new DefaultOrganization();
    HashSet<JaxbRole> roles = new HashSet<>();
    roles.add(new JaxbRole(DefaultOrganization.DEFAULT_ORGANIZATION_ADMIN, org, ""));
    User user = new JaxbUser("admin", "test", org, roles);
    OrganizationDirectoryService orgDirectory = EasyMock.createNiceMock(OrganizationDirectoryService.class);
    EasyMock.expect(orgDirectory.getOrganization((String) EasyMock.anyObject())).andReturn(org).anyTimes();
    UserDirectoryService userDirectory = EasyMock.createNiceMock(UserDirectoryService.class);
    EasyMock.expect(userDirectory.loadUser("admin")).andReturn(user).anyTimes();
    SecurityService securityService = EasyMock.createNiceMock(SecurityService.class);
    EasyMock.expect(securityService.getOrganization()).andReturn(org).anyTimes();
    EasyMock.expect(securityService.getUser()).andReturn(user).anyTimes();
    Workspace workspace = EasyMock.createNiceMock(Workspace.class);
    EasyMock.expect(workspace.get(EasyMock.anyObject())).andReturn(sourceVideoOnly).anyTimes();
    profileScanner = new EncodingProfileScanner();
    File encodingProfile = getFile("/encodingprofiles.properties");
    assertNotNull("Encoding profile must exist", encodingProfile);
    profileScanner.install(encodingProfile);
    // Finish setting up the mocks
    EasyMock.replay(bc, cc, orgDirectory, userDirectory, securityService, workspace);
    // Create an encoding engine factory
    inspectedTrack = (Track) MediaPackageElementParser.getFromXml(IOUtils.toString(ComposerServiceTest.class.getResourceAsStream("/composer_test_source_track_video.xml"), Charset.defaultCharset()));
    sourceVideoTrack = (Track) MediaPackageElementParser.getFromXml(IOUtils.toString(ComposerServiceTest.class.getResourceAsStream("/composer_test_source_track_video.xml"), Charset.defaultCharset()));
    sourceAudioTrack = (Track) MediaPackageElementParser.getFromXml(IOUtils.toString(ComposerServiceTest.class.getResourceAsStream("/composer_test_source_track_audio.xml"), Charset.defaultCharset()));
    // Create and populate the composer service
    composerService = new ComposerServiceImpl() {

        @Override
        protected Job inspect(Job job, URI workspaceURI) throws EncoderException {
            Job inspectionJob = EasyMock.createNiceMock(Job.class);
            try {
                EasyMock.expect(inspectionJob.getPayload()).andReturn(MediaPackageElementParser.getAsXml(inspectedTrack));
            } catch (MediaPackageException e) {
                throw new RuntimeException(e);
            }
            EasyMock.replay(inspectionJob);
            return inspectionJob;
        }
    };
    ServiceRegistry serviceRegistry = EasyMock.createMock(ServiceRegistry.class);
    final Capture<String> type = EasyMock.newCapture();
    final Capture<String> operation = EasyMock.newCapture();
    final Capture<List<String>> args = EasyMock.newCapture();
    EasyMock.expect(serviceRegistry.createJob(capture(type), capture(operation), capture(args), EasyMock.anyFloat())).andAnswer(() -> {
        // you could do work here to return something different if you needed.
        Job job = new JobImpl(0);
        job.setJobType(type.getValue());
        job.setOperation(operation.getValue());
        job.setArguments(args.getValue());
        job.setPayload(composerService.process(job));
        return job;
    }).anyTimes();
    composerService.setServiceRegistry(serviceRegistry);
    composerService.setProfileScanner(profileScanner);
    composerService.setWorkspace(workspace);
    EasyMock.replay(serviceRegistry);
}
Also used : User(org.opencastproject.security.api.User) JaxbUser(org.opencastproject.security.api.JaxbUser) JaxbUser(org.opencastproject.security.api.JaxbUser) URI(java.net.URI) SecurityService(org.opencastproject.security.api.SecurityService) List(java.util.List) ArrayList(java.util.ArrayList) Job(org.opencastproject.job.api.Job) HashSet(java.util.HashSet) MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) JobImpl(org.opencastproject.job.api.JobImpl) ComponentContext(org.osgi.service.component.ComponentContext) JaxbOrganization(org.opencastproject.security.api.JaxbOrganization) UserDirectoryService(org.opencastproject.security.api.UserDirectoryService) EncoderException(org.opencastproject.composer.api.EncoderException) JaxbRole(org.opencastproject.security.api.JaxbRole) ServiceRegistry(org.opencastproject.serviceregistry.api.ServiceRegistry) File(java.io.File) BundleContext(org.osgi.framework.BundleContext) DefaultOrganization(org.opencastproject.security.api.DefaultOrganization) OrganizationDirectoryService(org.opencastproject.security.api.OrganizationDirectoryService) Workspace(org.opencastproject.workspace.api.Workspace) Before(org.junit.Before)

Example 10 with MediaPackageException

use of org.opencastproject.mediapackage.MediaPackageException in project opencast by opencast.

the class CoverImageWorkflowOperationHandlerBase method start.

@Override
public WorkflowOperationResult start(final WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
    MediaPackage mediaPackage = workflowInstance.getMediaPackage();
    WorkflowOperationInstance operation = workflowInstance.getCurrentOperation();
    logger.info("Cover Image Workflow started for media package '{}'", mediaPackage.getIdentifier());
    // User XML metadata from operation configuration, fallback to default metadata
    String xml = operation.getConfiguration(XML_METADATA);
    if (xml == null) {
        xml = getMetadataXml(mediaPackage);
        logger.debug("Metadata was not part of operation configuration, using Dublin Core as fallback");
    }
    logger.debug("Metadata set to: {}", xml);
    String xsl = loadXsl(operation);
    logger.debug("XSL for transforming metadata to SVG loaded: {}", xsl);
    // Read image dimensions
    int width = getIntConfiguration(operation, WIDTH);
    logger.debug("Image width set to {}px", width);
    int height = getIntConfiguration(operation, HEIGHT);
    logger.debug("Image height set to {}px", height);
    // Read optional poster image flavor
    String posterImgUri = getPosterImageFileUrl(operation.getConfiguration(POSTERIMAGE_URL));
    if (posterImgUri == null)
        posterImgUri = getPosterImageFileUrl(mediaPackage, operation.getConfiguration(POSTERIMAGE_FLAVOR));
    if (posterImgUri == null) {
        logger.debug("No optional poster image set");
    } else {
        logger.debug("Poster image found at '{}'", posterImgUri);
    }
    // Read target flavor
    String targetFlavor = operation.getConfiguration(TARGET_FLAVOR);
    if (StringUtils.isBlank(targetFlavor)) {
        logger.warn("Required configuration key '{}' is blank", TARGET_FLAVOR);
        throw new WorkflowOperationException("Configuration key '" + TARGET_FLAVOR + "' must be set");
    }
    try {
        MediaPackageElementFlavor.parseFlavor(targetFlavor);
    } catch (IllegalArgumentException e) {
        logger.warn("Given target flavor '{}' is not a valid flavor", targetFlavor);
        throw new WorkflowOperationException(e);
    }
    Job generate;
    try {
        generate = getCoverImageService().generateCoverImage(xml, xsl, String.valueOf(width), String.valueOf(height), posterImgUri, targetFlavor);
        logger.debug("Job for cover image generation created");
        if (!waitForStatus(generate).isSuccess()) {
            throw new WorkflowOperationException("'Cover image' job did not successfuly end");
        }
        generate = serviceRegistry.getJob(generate.getId());
        Attachment coverImage = (Attachment) MediaPackageElementParser.getFromXml(generate.getPayload());
        URI attachmentUri = getWorkspace().moveTo(coverImage.getURI(), mediaPackage.getIdentifier().compact(), UUID.randomUUID().toString(), COVERIMAGE_FILENAME);
        coverImage.setURI(attachmentUri);
        coverImage.setMimeType(MimeTypes.PNG);
        // Add tags
        final String targetTags = StringUtils.trimToNull(operation.getConfiguration(TARGET_TAGS));
        if (targetTags != null) {
            for (String tag : asList(targetTags)) {
                logger.trace("Tagging image with '{}'", tag);
                if (StringUtils.trimToNull(tag) != null)
                    coverImage.addTag(tag);
            }
        }
        mediaPackage.add(coverImage);
    } catch (MediaPackageException e) {
        throw new WorkflowOperationException(e);
    } catch (NotFoundException e) {
        throw new WorkflowOperationException(e);
    } catch (ServiceRegistryException e) {
        throw new WorkflowOperationException(e);
    } catch (CoverImageException e) {
        throw new WorkflowOperationException(e);
    } catch (IllegalArgumentException e) {
        throw new WorkflowOperationException(e);
    } catch (IOException e) {
        throw new WorkflowOperationException(e);
    }
    logger.info("Cover Image Workflow finished successfully for media package '{}' within {}ms", mediaPackage.getIdentifier(), generate.getQueueTime());
    return createResult(mediaPackage, Action.CONTINUE, generate.getQueueTime());
}
Also used : MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) NotFoundException(org.opencastproject.util.NotFoundException) FileNotFoundException(java.io.FileNotFoundException) Attachment(org.opencastproject.mediapackage.Attachment) IOException(java.io.IOException) URI(java.net.URI) ServiceRegistryException(org.opencastproject.serviceregistry.api.ServiceRegistryException) WorkflowOperationInstance(org.opencastproject.workflow.api.WorkflowOperationInstance) CoverImageException(org.opencastproject.coverimage.CoverImageException) MediaPackage(org.opencastproject.mediapackage.MediaPackage) WorkflowOperationException(org.opencastproject.workflow.api.WorkflowOperationException) Job(org.opencastproject.job.api.Job)

Aggregations

MediaPackageException (org.opencastproject.mediapackage.MediaPackageException)72 Job (org.opencastproject.job.api.Job)42 IOException (java.io.IOException)34 MediaPackage (org.opencastproject.mediapackage.MediaPackage)33 NotFoundException (org.opencastproject.util.NotFoundException)31 URI (java.net.URI)25 ArrayList (java.util.ArrayList)25 MediaPackageElement (org.opencastproject.mediapackage.MediaPackageElement)21 WorkflowOperationException (org.opencastproject.workflow.api.WorkflowOperationException)20 ServiceRegistryException (org.opencastproject.serviceregistry.api.ServiceRegistryException)19 Track (org.opencastproject.mediapackage.Track)17 MediaPackageElementFlavor (org.opencastproject.mediapackage.MediaPackageElementFlavor)15 File (java.io.File)13 HashMap (java.util.HashMap)13 InputStream (java.io.InputStream)12 HttpResponse (org.apache.http.HttpResponse)12 UrlEncodedFormEntity (org.apache.http.client.entity.UrlEncodedFormEntity)12 HttpPost (org.apache.http.client.methods.HttpPost)12 BasicNameValuePair (org.apache.http.message.BasicNameValuePair)12 EncoderException (org.opencastproject.composer.api.EncoderException)12