use of org.opencastproject.mediapackage.MediaPackageReference in project opencast by opencast.
the class SolrIndexManager method addMpeg7Metadata.
/**
* Add the mpeg 7 catalog data to the solr document.
*
* @param doc
* the input document to the solr index
* @param mpeg7
* the mpeg7 catalog
*/
@SuppressWarnings("unchecked")
static void addMpeg7Metadata(SolrInputDocument doc, MediaPackage mediaPackage, Mpeg7Catalog mpeg7) {
// Check for multimedia content
if (!mpeg7.multimediaContent().hasNext()) {
logger.warn("Mpeg-7 doesn't contain multimedia content");
return;
}
// Get the content duration by looking at the first content track. This
// of course assumes that all tracks are equally long.
MultimediaContent<? extends MultimediaContentType> mc = mpeg7.multimediaContent().next();
MultimediaContentType mct = mc.elements().next();
MediaTime mediaTime = mct.getMediaTime();
Schema.setDcExtent(doc, mediaTime.getMediaDuration().getDurationInMilliseconds());
// Check if the keywords have been filled by (manually) added dublin
// core data. If not, look for the most relevant fields in mpeg-7.
SortedSet<TextAnnotation> sortedAnnotations = null;
if (!"".equals(Schema.getOcKeywords(doc))) {
sortedAnnotations = new TreeSet<TextAnnotation>(new Comparator<TextAnnotation>() {
@Override
public int compare(TextAnnotation a1, TextAnnotation a2) {
if ((RELEVANCE_BOOST * a1.getRelevance() + a1.getConfidence()) > (RELEVANCE_BOOST * a2.getRelevance() + a2.getConfidence()))
return -1;
else if ((RELEVANCE_BOOST * a1.getRelevance() + a1.getConfidence()) < (RELEVANCE_BOOST * a2.getRelevance() + a2.getConfidence()))
return 1;
return 0;
}
});
}
// Iterate over the tracks and extract keywords and hints
Iterator<MultimediaContent<? extends MultimediaContentType>> mmIter = mpeg7.multimediaContent();
int segmentCount = 0;
while (mmIter.hasNext()) {
MultimediaContent<?> multimediaContent = mmIter.next();
// We need to process visual segments first, due to the way they are handled in the ui.
for (Iterator<?> iterator = multimediaContent.elements(); iterator.hasNext(); ) {
MultimediaContentType type = (MultimediaContentType) iterator.next();
if (!(type instanceof Video) && !(type instanceof AudioVisual))
continue;
// for every segment in the current multimedia content track
Video video = (Video) type;
Iterator<VideoSegment> vsegments = (Iterator<VideoSegment>) video.getTemporalDecomposition().segments();
while (vsegments.hasNext()) {
VideoSegment segment = vsegments.next();
StringBuffer segmentText = new StringBuffer();
StringBuffer hintField = new StringBuffer();
// Collect the video text elements to a segment text
SpatioTemporalDecomposition spt = segment.getSpatioTemporalDecomposition();
if (spt != null) {
for (VideoText videoText : spt.getVideoText()) {
if (segmentText.length() > 0)
segmentText.append(" ");
segmentText.append(videoText.getText().getText());
// TODO: Add hint on bounding box
}
}
// Add keyword annotations
Iterator<TextAnnotation> textAnnotations = segment.textAnnotations();
while (textAnnotations.hasNext()) {
TextAnnotation textAnnotation = textAnnotations.next();
Iterator<?> kwIter = textAnnotation.keywordAnnotations();
while (kwIter.hasNext()) {
KeywordAnnotation keywordAnnotation = (KeywordAnnotation) kwIter.next();
if (segmentText.length() > 0)
segmentText.append(" ");
segmentText.append(keywordAnnotation.getKeyword());
}
}
// Add free text annotations
Iterator<TextAnnotation> freeIter = segment.textAnnotations();
if (freeIter.hasNext()) {
Iterator<FreeTextAnnotation> freeTextIter = freeIter.next().freeTextAnnotations();
while (freeTextIter.hasNext()) {
FreeTextAnnotation freeTextAnnotation = freeTextIter.next();
if (segmentText.length() > 0)
segmentText.append(" ");
segmentText.append(freeTextAnnotation.getText());
}
}
// add segment text to solr document
Schema.setSegmentText(doc, new DField<String>(segmentText.toString(), Integer.toString(segmentCount)));
// get the segments time properties
MediaTimePoint timepoint = segment.getMediaTime().getMediaTimePoint();
MediaDuration duration = segment.getMediaTime().getMediaDuration();
// TODO: define a class with hint field constants
hintField.append("time=" + timepoint.getTimeInMilliseconds() + "\n");
hintField.append("duration=" + duration.getDurationInMilliseconds() + "\n");
// Look for preview images. Their characteristics are that they are
// attached as attachments with a flavor of preview/<something>.
String time = timepoint.toString();
for (Attachment slide : mediaPackage.getAttachments(MediaPackageElements.PRESENTATION_SEGMENT_PREVIEW)) {
MediaPackageReference ref = slide.getReference();
if (ref != null && time.equals(ref.getProperty("time"))) {
hintField.append("preview");
hintField.append(".");
hintField.append(ref.getIdentifier());
hintField.append("=");
hintField.append(slide.getURI().toString());
hintField.append("\n");
}
}
logger.trace("Adding segment: " + timepoint.toString());
Schema.setSegmentHint(doc, new DField<String>(hintField.toString(), Integer.toString(segmentCount)));
// increase segment counter
segmentCount++;
}
}
}
// Put the most important keywords into a special solr field
if (sortedAnnotations != null) {
Schema.setOcKeywords(doc, importantKeywordsString(sortedAnnotations).toString());
}
}
use of org.opencastproject.mediapackage.MediaPackageReference in project opencast by opencast.
the class SegmentPreviewsWorkflowOperationHandler method createPreviews.
/**
* Encode tracks from MediaPackage using profiles stored in properties and updates current MediaPackage.
*
* @param mediaPackage
* @param properties
* @return the operation result containing the updated mediapackage
* @throws EncoderException
* @throws ExecutionException
* @throws InterruptedException
* @throws IOException
* @throws NotFoundException
* @throws WorkflowOperationException
*/
private WorkflowOperationResult createPreviews(final MediaPackage mediaPackage, WorkflowOperationInstance operation) throws EncoderException, InterruptedException, ExecutionException, NotFoundException, MediaPackageException, IOException, WorkflowOperationException {
long totalTimeInQueue = 0;
// Read the configuration properties
String sourceVideoFlavor = StringUtils.trimToNull(operation.getConfiguration("source-flavor"));
String sourceTags = StringUtils.trimToNull(operation.getConfiguration("source-tags"));
String targetImageTags = StringUtils.trimToNull(operation.getConfiguration("target-tags"));
String targetImageFlavor = StringUtils.trimToNull(operation.getConfiguration("target-flavor"));
String encodingProfileName = StringUtils.trimToNull(operation.getConfiguration("encoding-profile"));
String referenceFlavor = StringUtils.trimToNull(operation.getConfiguration("reference-flavor"));
String referenceTags = StringUtils.trimToNull(operation.getConfiguration("reference-tags"));
// Find the encoding profile
EncodingProfile profile = composerService.getProfile(encodingProfileName);
if (profile == null)
throw new IllegalStateException("Encoding profile '" + encodingProfileName + "' was not found");
List<String> sourceTagSet = asList(sourceTags);
// Select the tracks based on the tags and flavors
Set<Track> videoTrackSet = new HashSet<>();
for (Track track : mediaPackage.getTracksByTags(sourceTagSet)) {
if (sourceVideoFlavor == null || (track.getFlavor() != null && sourceVideoFlavor.equals(track.getFlavor().toString()))) {
if (!track.hasVideo())
continue;
videoTrackSet.add(track);
}
}
if (videoTrackSet.size() == 0) {
logger.debug("Mediapackage {} has no suitable tracks to extract images based on tags {} and flavor {}", mediaPackage, sourceTags, sourceVideoFlavor);
return createResult(mediaPackage, Action.CONTINUE);
} else {
// Determine the tagset for the reference
List<String> referenceTagSet = asList(referenceTags);
// Determine the reference master
for (Track t : videoTrackSet) {
// Try to load the segments catalog
MediaPackageReference trackReference = new MediaPackageReferenceImpl(t);
Catalog[] segmentCatalogs = mediaPackage.getCatalogs(MediaPackageElements.SEGMENTS, trackReference);
Mpeg7Catalog mpeg7 = null;
if (segmentCatalogs.length > 0) {
mpeg7 = loadMpeg7Catalog(segmentCatalogs[0]);
if (segmentCatalogs.length > 1)
logger.warn("More than one segments catalog found for track {}. Resuming with the first one ({})", t, mpeg7);
} else {
logger.debug("No segments catalog found for track {}", t);
continue;
}
// Check the catalog's consistency
if (mpeg7.videoContent() == null || mpeg7.videoContent().next() == null) {
logger.info("Segments catalog {} contains no video content", mpeg7);
continue;
}
Video videoContent = mpeg7.videoContent().next();
TemporalDecomposition<? extends Segment> decomposition = videoContent.getTemporalDecomposition();
// Are there any segments?
if (decomposition == null || !decomposition.hasSegments()) {
logger.info("Segments catalog {} contains no video content", mpeg7);
continue;
}
// Is a derived track with the configured reference flavor available?
MediaPackageElement referenceMaster = getReferenceMaster(mediaPackage, t, referenceFlavor, referenceTagSet);
// Create the preview images according to the mpeg7 segments
if (t.hasVideo() && mpeg7 != null) {
Iterator<? extends Segment> segmentIterator = decomposition.segments();
List<MediaTimePoint> timePointList = new LinkedList<>();
while (segmentIterator.hasNext()) {
Segment segment = segmentIterator.next();
MediaTimePoint tp = segment.getMediaTime().getMediaTimePoint();
timePointList.add(tp);
}
// convert to time array
double[] timeArray = new double[timePointList.size()];
for (int i = 0; i < timePointList.size(); i++) timeArray[i] = (double) timePointList.get(i).getTimeInMilliseconds() / 1000;
Job job = composerService.image(t, profile.getIdentifier(), timeArray);
if (!waitForStatus(job).isSuccess()) {
throw new WorkflowOperationException("Extracting preview image from " + t + " failed");
}
// Get the latest copy
try {
job = serviceRegistry.getJob(job.getId());
} catch (ServiceRegistryException e) {
throw new WorkflowOperationException(e);
}
// add this receipt's queue time to the total
totalTimeInQueue += job.getQueueTime();
List<? extends MediaPackageElement> composedImages = MediaPackageElementParser.getArrayFromXml(job.getPayload());
Iterator<MediaTimePoint> it = timePointList.iterator();
for (MediaPackageElement element : composedImages) {
Attachment composedImage = (Attachment) element;
if (composedImage == null)
throw new IllegalStateException("Unable to compose image");
// Add the flavor, either from the operation configuration or from the composer
if (targetImageFlavor != null) {
composedImage.setFlavor(MediaPackageElementFlavor.parseFlavor(targetImageFlavor));
logger.debug("Preview image has flavor '{}'", composedImage.getFlavor());
}
// Set the mimetype
if (profile.getMimeType() != null)
composedImage.setMimeType(MimeTypes.parseMimeType(profile.getMimeType()));
// Add tags
for (String tag : asList(targetImageTags)) {
logger.trace("Tagging image with '{}'", tag);
composedImage.addTag(tag);
}
// Refer to the original track including a timestamp
MediaPackageReferenceImpl ref = new MediaPackageReferenceImpl(referenceMaster);
ref.setProperty("time", it.next().toString());
composedImage.setReference(ref);
// store new image in the mediaPackage
mediaPackage.add(composedImage);
String fileName = getFileNameFromElements(t, composedImage);
composedImage.setURI(workspace.moveTo(composedImage.getURI(), mediaPackage.getIdentifier().toString(), composedImage.getIdentifier(), fileName));
}
}
}
}
return createResult(mediaPackage, Action.CONTINUE, totalTimeInQueue);
}
use of org.opencastproject.mediapackage.MediaPackageReference in project opencast by opencast.
the class OaiPmhPublicationServiceImpl method filterMediaPackage.
/**
* Creates a clone of the media package and removes those elements that do not match the flavor and tags filter
* criteria.
*
* @param mediaPackage
* the media package
* @param flavors
* the flavors
* @param tags
* the tags
* @return the filtered media package
*/
private MediaPackage filterMediaPackage(MediaPackage mediaPackage, Set<MediaPackageElementFlavor> flavors, Set<String> tags) throws MediaPackageException {
if (flavors.isEmpty() && tags.isEmpty())
throw new IllegalArgumentException("Flavors or tags parameter must be set");
MediaPackage filteredMediaPackage = (MediaPackage) mediaPackage.clone();
// The list of elements to keep
List<MediaPackageElement> keep = new ArrayList<>();
SimpleElementSelector selector = new SimpleElementSelector();
// Filter elements
for (MediaPackageElementFlavor flavor : flavors) {
selector.addFlavor(flavor);
}
for (String tag : tags) {
selector.addTag(tag);
}
keep.addAll(selector.select(mediaPackage, true));
// Keep publications
for (Publication p : filteredMediaPackage.getPublications()) keep.add(p);
// Fix references and flavors
for (MediaPackageElement element : filteredMediaPackage.getElements()) {
if (!keep.contains(element)) {
logger.debug("Removing {} '{}' from media package '{}'", element.getElementType().toString().toLowerCase(), element.getIdentifier(), filteredMediaPackage.getIdentifier().toString());
filteredMediaPackage.remove(element);
continue;
}
// Is the element referencing anything?
MediaPackageReference reference = element.getReference();
if (reference != null) {
Map<String, String> referenceProperties = reference.getProperties();
MediaPackageElement referencedElement = mediaPackage.getElementByReference(reference);
// if we are distributing the referenced element, everything is fine. Otherwise...
if (referencedElement != null && !keep.contains(referencedElement)) {
// Follow the references until we find a flavor
MediaPackageElement parent = null;
while ((parent = mediaPackage.getElementByReference(reference)) != null) {
if (parent.getFlavor() != null && element.getFlavor() == null) {
element.setFlavor(parent.getFlavor());
}
if (parent.getReference() == null)
break;
reference = parent.getReference();
}
// Done. Let's cut the path but keep references to the mediapackage itself
if (reference != null && reference.getType().equals(MediaPackageReference.TYPE_MEDIAPACKAGE))
element.setReference(reference);
else if (reference != null && (referenceProperties == null || referenceProperties.size() == 0))
element.clearReference();
else {
// Ok, there is more to that reference than just pointing at an element. Let's keep the original,
// you never know.
referencedElement.setURI(null);
referencedElement.setChecksum(null);
}
}
}
}
return filteredMediaPackage;
}
use of org.opencastproject.mediapackage.MediaPackageReference in project opencast by opencast.
the class AssetManagerSnapshotWorkflowOperationHandler method getMediaPackageForArchival.
protected MediaPackage getMediaPackageForArchival(MediaPackage current, List<String> tags, String[] sourceFlavors) throws MediaPackageException {
MediaPackage mp = (MediaPackage) current.clone();
Collection<MediaPackageElement> keep;
if (tags.isEmpty() && sourceFlavors.length < 1) {
keep = new ArrayList<>(Arrays.asList(current.getElementsByTags(tags)));
} else {
SimpleElementSelector simpleElementSelector = new SimpleElementSelector();
for (String flavor : sourceFlavors) {
simpleElementSelector.addFlavor(flavor);
}
for (String tag : tags) {
simpleElementSelector.addTag(tag);
}
keep = simpleElementSelector.select(current, false);
}
// Also archive the publication elements
for (Publication publication : current.getPublications()) {
keep.add(publication);
}
// Mark everything that is set for removal
List<MediaPackageElement> removals = new ArrayList<MediaPackageElement>();
for (MediaPackageElement element : mp.getElements()) {
if (!keep.contains(element)) {
removals.add(element);
}
}
// Fix references and flavors
for (MediaPackageElement element : mp.getElements()) {
if (removals.contains(element))
continue;
// Is the element referencing anything?
MediaPackageReference reference = element.getReference();
if (reference != null) {
Map<String, String> referenceProperties = reference.getProperties();
MediaPackageElement referencedElement = mp.getElementByReference(reference);
// if we are distributing the referenced element, everything is fine. Otherwise...
if (referencedElement != null && removals.contains(referencedElement)) {
// Follow the references until we find a flavor
MediaPackageElement parent;
while ((parent = current.getElementByReference(reference)) != null) {
if (parent.getFlavor() != null && element.getFlavor() == null) {
element.setFlavor(parent.getFlavor());
}
if (parent.getReference() == null) {
break;
}
reference = parent.getReference();
}
// Done. Let's cut the path but keep references to the mediapackage itself
if (reference != null && reference.getType().equals(MediaPackageReference.TYPE_MEDIAPACKAGE))
element.setReference(reference);
else if (reference != null && (referenceProperties == null || referenceProperties.size() == 0))
element.clearReference();
else {
// Ok, there is more to that reference than just pointing at an element. Let's keep the original,
// you never know.
removals.remove(referencedElement);
referencedElement.setURI(null);
referencedElement.setChecksum(null);
}
}
}
}
// Remove everything we don't want to add to publish
for (MediaPackageElement element : removals) {
mp.remove(element);
}
return mp;
}
use of org.opencastproject.mediapackage.MediaPackageReference in project opencast by opencast.
the class PublishEngageWorkflowOperationHandler method getMediaPackageForSearchIndex.
/**
* Returns a mediapackage that only contains elements that are marked for distribution.
*
* @param current
* the current mediapackage
* @param jobs
* the distribution jobs
* @param downloadSubflavor
* flavor to be applied to elements distributed to download
* @param downloadTargetTags
* tags to be applied to elements distributed to downloads
* @param downloadElementIds
* identifiers for elements that have been distributed to downloads
* @param streamingSubflavor
* flavor to be applied to elements distributed to streaming
* @param streamingElementIds
* identifiers for elements that have been distributed to streaming
* @param streamingTargetTags
* tags to be applied to elements distributed to streaming
* @return the new mediapackage
*/
protected MediaPackage getMediaPackageForSearchIndex(MediaPackage current, List<Job> jobs, MediaPackageElementFlavor downloadSubflavor, String[] downloadTargetTags, Set<String> downloadElementIds, MediaPackageElementFlavor streamingSubflavor, Set<String> streamingElementIds, String[] streamingTargetTags) throws MediaPackageException, NotFoundException, ServiceRegistryException, WorkflowOperationException {
MediaPackage mp = (MediaPackage) current.clone();
// All the jobs have passed, let's update the mediapackage with references to the distributed elements
List<String> elementsToPublish = new ArrayList<String>();
Map<String, String> distributedElementIds = new HashMap<String, String>();
for (Job entry : jobs) {
Job job = serviceRegistry.getJob(entry.getId());
// If there is no payload, then the item has not been distributed.
if (job.getPayload() == null)
continue;
List<MediaPackageElement> distributedElements = null;
try {
distributedElements = (List<MediaPackageElement>) MediaPackageElementParser.getArrayFromXml(job.getPayload());
} catch (MediaPackageException e) {
throw new WorkflowOperationException(e);
}
// kind of element. So we just keep on looping.
if (distributedElements == null || distributedElements.size() < 1)
continue;
for (MediaPackageElement distributedElement : distributedElements) {
String sourceElementId = distributedElement.getIdentifier();
if (sourceElementId != null) {
MediaPackageElement sourceElement = mp.getElementById(sourceElementId);
// Make sure the mediapackage is prompted to create a new identifier for this element
distributedElement.setIdentifier(null);
if (sourceElement != null) {
// Adjust the flavor and tags for downloadable elements
if (downloadElementIds.contains(sourceElementId)) {
if (downloadSubflavor != null) {
MediaPackageElementFlavor flavor = sourceElement.getFlavor();
if (flavor != null) {
MediaPackageElementFlavor newFlavor = new MediaPackageElementFlavor(flavor.getType(), downloadSubflavor.getSubtype());
distributedElement.setFlavor(newFlavor);
}
}
} else // Adjust the flavor and tags for streaming elements
if (streamingElementIds.contains(sourceElementId)) {
if (streamingSubflavor != null && streamingElementIds.contains(sourceElementId)) {
MediaPackageElementFlavor flavor = sourceElement.getFlavor();
if (flavor != null) {
MediaPackageElementFlavor newFlavor = new MediaPackageElementFlavor(flavor.getType(), streamingSubflavor.getSubtype());
distributedElement.setFlavor(newFlavor);
}
}
}
// Copy references from the source elements to the distributed elements
MediaPackageReference ref = sourceElement.getReference();
if (ref != null && mp.getElementByReference(ref) != null) {
MediaPackageReference newReference = (MediaPackageReference) ref.clone();
distributedElement.setReference(newReference);
}
}
}
if (isStreamingFormat(distributedElement))
applyTags(distributedElement, streamingTargetTags);
else
applyTags(distributedElement, downloadTargetTags);
// Add the new element to the mediapackage
mp.add(distributedElement);
elementsToPublish.add(distributedElement.getIdentifier());
distributedElementIds.put(sourceElementId, distributedElement.getIdentifier());
}
}
// Mark everything that is set for removal
List<MediaPackageElement> removals = new ArrayList<MediaPackageElement>();
for (MediaPackageElement element : mp.getElements()) {
if (!elementsToPublish.contains(element.getIdentifier())) {
removals.add(element);
}
}
// Translate references to the distributed artifacts
for (MediaPackageElement element : mp.getElements()) {
if (removals.contains(element))
continue;
// Is the element referencing anything?
MediaPackageReference reference = element.getReference();
if (reference == null)
continue;
// See if the element has been distributed
String distributedElementId = distributedElementIds.get(reference.getIdentifier());
if (distributedElementId == null)
continue;
MediaPackageReference translatedReference = new MediaPackageReferenceImpl(mp.getElementById(distributedElementId));
if (reference.getProperties() != null) {
translatedReference.getProperties().putAll(reference.getProperties());
}
// Set the new reference
element.setReference(translatedReference);
}
// Remove everything we don't want to add to publish
for (MediaPackageElement element : removals) {
mp.remove(element);
}
return mp;
}
Aggregations