use of org.opencastproject.mediapackage.Catalog in project opencast by opencast.
the class VideoSegmenterWorkflowOperationHandler method start.
/**
* {@inheritDoc}
*
* @see org.opencastproject.workflow.api.WorkflowOperationHandler#start(org.opencastproject.workflow.api.WorkflowInstance,
* JobContext)
*/
public WorkflowOperationResult start(final WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
logger.debug("Running video segmentation on workflow {}", workflowInstance.getId());
WorkflowOperationInstance operation = workflowInstance.getCurrentOperation();
MediaPackage mediaPackage = workflowInstance.getMediaPackage();
// Find movie track to analyze
String trackFlavor = StringUtils.trimToNull(operation.getConfiguration(PROP_ANALYSIS_TRACK_FLAVOR));
List<String> targetTags = asList(operation.getConfiguration(PROP_TARGET_TAGS));
List<Track> candidates = new ArrayList<Track>();
if (trackFlavor != null)
candidates.addAll(Arrays.asList(mediaPackage.getTracks(MediaPackageElementFlavor.parseFlavor(trackFlavor))));
else
candidates.addAll(Arrays.asList(mediaPackage.getTracks(MediaPackageElements.PRESENTATION_SOURCE)));
// Remove unsupported tracks (only those containing video can be segmented)
Iterator<Track> ti = candidates.iterator();
while (ti.hasNext()) {
Track t = ti.next();
if (!t.hasVideo())
ti.remove();
}
// Found one?
if (candidates.size() == 0) {
logger.info("No matching tracks available for video segmentation in workflow {}", workflowInstance);
return createResult(Action.CONTINUE);
}
// More than one left? Let's be pragmatic...
if (candidates.size() > 1) {
logger.info("Found more than one track to segment, choosing the first one ({})", candidates.get(0));
}
Track track = candidates.get(0);
// Segment the media package
Catalog mpeg7Catalog = null;
Job job = null;
try {
job = videosegmenter.segment(track);
if (!waitForStatus(job).isSuccess()) {
throw new WorkflowOperationException("Video segmentation of " + track + " failed");
}
mpeg7Catalog = (Catalog) MediaPackageElementParser.getFromXml(job.getPayload());
mediaPackage.add(mpeg7Catalog);
mpeg7Catalog.setURI(workspace.moveTo(mpeg7Catalog.getURI(), mediaPackage.getIdentifier().toString(), mpeg7Catalog.getIdentifier(), "segments.xml"));
mpeg7Catalog.setReference(new MediaPackageReferenceImpl(track));
// Add target tags
for (String tag : targetTags) {
mpeg7Catalog.addTag(tag);
}
} catch (Exception e) {
throw new WorkflowOperationException(e);
}
logger.debug("Video segmentation completed");
return createResult(mediaPackage, Action.CONTINUE, job.getQueueTime());
}
use of org.opencastproject.mediapackage.Catalog in project opencast by opencast.
the class ConfigurablePublishWorkflowOperationHandlerTest method testNormal.
@Test
public void testNormal() throws WorkflowOperationException, URISyntaxException, DistributionException, MediaPackageException {
String channelId = "engage-player";
String attachmentId = "attachment-id";
String catalogId = "catalog-id";
String trackId = "track-id";
Attachment attachment = new AttachmentImpl();
attachment.addTag("engage-download");
attachment.setIdentifier(attachmentId);
attachment.setURI(new URI("http://api.com/attachment"));
Catalog catalog = CatalogImpl.newInstance();
catalog.addTag("engage-download");
catalog.setIdentifier(catalogId);
catalog.setURI(new URI("http://api.com/catalog"));
Track track = new TrackImpl();
track.addTag("engage-streaming");
track.setIdentifier(trackId);
track.setURI(new URI("http://api.com/track"));
Publication publicationtest = new PublicationImpl(trackId, channelId, new URI("http://api.com/publication"), MimeType.mimeType(trackId, trackId));
Track unrelatedTrack = new TrackImpl();
unrelatedTrack.addTag("unrelated");
Capture<MediaPackageElement> capturePublication = Capture.newInstance();
MediaPackage mediapackageClone = EasyMock.createNiceMock(MediaPackage.class);
EasyMock.expect(mediapackageClone.getElements()).andStubReturn(new MediaPackageElement[] { attachment, catalog, track, unrelatedTrack });
EasyMock.expect(mediapackageClone.getIdentifier()).andStubReturn(new IdImpl("mp-id-clone"));
EasyMock.expectLastCall();
EasyMock.replay(mediapackageClone);
MediaPackage mediapackage = EasyMock.createNiceMock(MediaPackage.class);
EasyMock.expect(mediapackage.getElements()).andStubReturn(new MediaPackageElement[] { attachment, catalog, track, unrelatedTrack });
EasyMock.expect(mediapackage.clone()).andStubReturn(mediapackageClone);
EasyMock.expect(mediapackage.getIdentifier()).andStubReturn(new IdImpl("mp-id"));
mediapackage.add(EasyMock.capture(capturePublication));
mediapackage.add(publicationtest);
EasyMock.expect(mediapackage.getPublications()).andStubReturn(new Publication[] { publicationtest });
EasyMock.expectLastCall();
EasyMock.replay(mediapackage);
WorkflowOperationInstance op = EasyMock.createNiceMock(WorkflowOperationInstance.class);
EasyMock.expect(op.getConfiguration(ConfigurablePublishWorkflowOperationHandler.CHANNEL_ID_KEY)).andStubReturn(channelId);
EasyMock.expect(op.getConfiguration(ConfigurablePublishWorkflowOperationHandler.MIME_TYPE)).andStubReturn("text/html");
EasyMock.expect(op.getConfiguration(ConfigurablePublishWorkflowOperationHandler.URL_PATTERN)).andStubReturn("http://api.opencast.org/api/events/${event_id}");
EasyMock.expect(op.getConfiguration(ConfigurablePublishWorkflowOperationHandler.SOURCE_TAGS)).andStubReturn("engage-download,engage-streaming");
EasyMock.expect(op.getConfiguration(ConfigurablePublishWorkflowOperationHandler.CHECK_AVAILABILITY)).andStubReturn("true");
EasyMock.expect(op.getConfiguration(ConfigurablePublishWorkflowOperationHandler.STRATEGY)).andStubReturn("retract");
EasyMock.expect(op.getConfiguration(ConfigurablePublishWorkflowOperationHandler.MODE)).andStubReturn("single");
EasyMock.replay(op);
WorkflowInstance workflowInstance = EasyMock.createNiceMock(WorkflowInstance.class);
EasyMock.expect(workflowInstance.getMediaPackage()).andStubReturn(mediapackage);
EasyMock.expect(workflowInstance.getCurrentOperation()).andStubReturn(op);
EasyMock.replay(workflowInstance);
JobContext jobContext = EasyMock.createNiceMock(JobContext.class);
EasyMock.replay(jobContext);
Job attachmentJob = EasyMock.createNiceMock(Job.class);
EasyMock.expect(attachmentJob.getPayload()).andReturn(MediaPackageElementParser.getAsXml(attachment));
EasyMock.replay(attachmentJob);
Job catalogJob = EasyMock.createNiceMock(Job.class);
EasyMock.expect(catalogJob.getPayload()).andReturn(MediaPackageElementParser.getAsXml(catalog));
EasyMock.replay(catalogJob);
Job trackJob = EasyMock.createNiceMock(Job.class);
EasyMock.expect(trackJob.getPayload()).andReturn(MediaPackageElementParser.getAsXml(track));
EasyMock.replay(trackJob);
Job retractJob = EasyMock.createNiceMock(Job.class);
EasyMock.expect(retractJob.getPayload()).andReturn(MediaPackageElementParser.getAsXml(track));
EasyMock.replay(retractJob);
DownloadDistributionService distributionService = EasyMock.createNiceMock(DownloadDistributionService.class);
// Make sure that all of the elements are distributed.
EasyMock.expect(distributionService.distribute(channelId, mediapackage, attachmentId, true)).andReturn(attachmentJob);
EasyMock.expect(distributionService.distribute(channelId, mediapackage, catalogId, true)).andReturn(catalogJob);
EasyMock.expect(distributionService.distribute(channelId, mediapackage, trackId, true)).andReturn(trackJob);
EasyMock.expect(distributionService.retract(channelId, mediapackage, channelId)).andReturn(retractJob);
EasyMock.replay(distributionService);
SecurityService securityService = EasyMock.createNiceMock(SecurityService.class);
EasyMock.expect(securityService.getOrganization()).andStubReturn(org);
EasyMock.replay(securityService);
ServiceRegistry serviceRegistry = EasyMock.createNiceMock(ServiceRegistry.class);
EasyMock.replay(serviceRegistry);
// Override the waitForStatus method to not block the jobs
ConfigurablePublishWorkflowOperationHandler configurePublish = new ConfigurablePublishWorkflowOperationHandler() {
@Override
protected Result waitForStatus(long timeout, Job... jobs) {
HashMap<Job, Status> map = Stream.mk(jobs).foldl(new HashMap<Job, Status>(), new Fn2<HashMap<Job, Status>, Job, HashMap<Job, Status>>() {
@Override
public HashMap<Job, Status> apply(HashMap<Job, Status> a, Job b) {
a.put(b, Status.FINISHED);
return a;
}
});
return new Result(map);
}
};
configurePublish.setDownloadDistributionService(distributionService);
configurePublish.setSecurityService(securityService);
configurePublish.setServiceRegistry(serviceRegistry);
WorkflowOperationResult result = configurePublish.start(workflowInstance, jobContext);
assertNotNull(result.getMediaPackage());
assertTrue("The publication element has not been added to the mediapackage.", capturePublication.hasCaptured());
assertTrue("Some other type of element has been added to the mediapackage instead of the publication element.", capturePublication.getValue().getElementType().equals(MediaPackageElement.Type.Publication));
Publication publication = (Publication) capturePublication.getValue();
assertEquals(1, publication.getAttachments().length);
assertNotEquals(attachment.getIdentifier(), publication.getAttachments()[0].getIdentifier());
attachment.setIdentifier(publication.getAttachments()[0].getIdentifier());
assertEquals(attachment, publication.getAttachments()[0]);
assertEquals(1, publication.getCatalogs().length);
assertNotEquals(catalog.getIdentifier(), publication.getCatalogs()[0].getIdentifier());
catalog.setIdentifier(publication.getCatalogs()[0].getIdentifier());
assertEquals(catalog, publication.getCatalogs()[0]);
assertEquals(1, publication.getTracks().length);
assertNotEquals(track.getIdentifier(), publication.getTracks()[0].getIdentifier());
track.setIdentifier(publication.getTracks()[0].getIdentifier());
assertEquals(track, publication.getTracks()[0]);
}
use of org.opencastproject.mediapackage.Catalog in project opencast by opencast.
the class DublinCoreCatalogService method getMetadata.
/**
* {@inheritDoc}
*
* @see org.opencastproject.metadata.api.MetadataService#getMetadata(org.opencastproject.mediapackage.MediaPackage)
*/
@Override
public MediaPackageMetadata getMetadata(MediaPackage mp) {
MediapackageMetadataImpl metadata = new MediapackageMetadataImpl();
for (Catalog catalog : Stream.$(mp.getCatalogs(DublinCoreCatalog.ANY_DUBLINCORE)).sort(COMPARE_BY_FLAVOR)) {
DublinCoreCatalog dc = DublinCoreUtil.loadDublinCore(workspace, catalog);
if (MediaPackageElements.EPISODE.equals(catalog.getFlavor())) {
// Title
metadata.setTitle(dc.getFirst(DublinCore.PROPERTY_TITLE));
// use started date as created date (see MH-12250)
if (dc.hasValue(DublinCore.PROPERTY_TEMPORAL) && dc.getFirst(PROPERTY_TEMPORAL) != null) {
DCMIPeriod period = EncodingSchemeUtils.decodeMandatoryPeriod(dc.getFirst(PROPERTY_TEMPORAL));
metadata.setDate(period.getStart());
} else {
// ...and only if started date is not available the created date
if (dc.hasValue(DublinCore.PROPERTY_CREATED))
metadata.setDate(EncodingSchemeUtils.decodeDate(dc.get(DublinCore.PROPERTY_CREATED).get(0)));
}
// Series id
if (dc.hasValue(DublinCore.PROPERTY_IS_PART_OF))
metadata.setSeriesIdentifier(dc.get(DublinCore.PROPERTY_IS_PART_OF).get(0).getValue());
// Creator
if (dc.hasValue(DublinCore.PROPERTY_CREATOR)) {
List<String> creators = new ArrayList<String>();
for (DublinCoreValue creator : dc.get(DublinCore.PROPERTY_CREATOR)) {
creators.add(creator.getValue());
}
metadata.setCreators(creators.toArray(new String[creators.size()]));
}
// Contributor
if (dc.hasValue(DublinCore.PROPERTY_CONTRIBUTOR)) {
List<String> contributors = new ArrayList<String>();
for (DublinCoreValue contributor : dc.get(DublinCore.PROPERTY_CONTRIBUTOR)) {
contributors.add(contributor.getValue());
}
metadata.setContributors(contributors.toArray(new String[contributors.size()]));
}
// Subject
if (dc.hasValue(DublinCore.PROPERTY_SUBJECT)) {
List<String> subjects = new ArrayList<String>();
for (DublinCoreValue subject : dc.get(DublinCore.PROPERTY_SUBJECT)) {
subjects.add(subject.getValue());
}
metadata.setSubjects(subjects.toArray(new String[subjects.size()]));
}
// License
metadata.setLicense(dc.getFirst(DublinCore.PROPERTY_LICENSE));
// Language
metadata.setLanguage(dc.getFirst(DublinCore.PROPERTY_LANGUAGE));
} else if (MediaPackageElements.SERIES.equals(catalog.getFlavor())) {
// Series Title and Identifier
metadata.setSeriesTitle(dc.getFirst(DublinCore.PROPERTY_TITLE));
metadata.setSeriesIdentifier(dc.getFirst(DublinCore.PROPERTY_IDENTIFIER));
} else {
logger.debug("Excluding unknown catalog flavor '{}' from the top level metadata of mediapackage '{}'", catalog.getFlavor(), mp.getIdentifier());
}
}
return metadata;
}
use of org.opencastproject.mediapackage.Catalog in project opencast by opencast.
the class ToolsEndpoint method addSmilToArchive.
/**
* Adds the SMIL file as {@link Catalog} to the media package and sends the updated media package to the archive.
*
* @param mediaPackage
* the media package to at the SMIL catalog
* @param smil
* the SMIL catalog
* @return the updated media package
* @throws IOException
* if the SMIL catalog cannot be read or not be written to the archive
*/
MediaPackage addSmilToArchive(MediaPackage mediaPackage, final Smil smil) throws IOException {
MediaPackageElementFlavor mediaPackageElementFlavor = adminUIConfiguration.getSmilCatalogFlavor();
// set default catalog Id if there is none existing
String catalogId = smil.getId();
Catalog[] catalogs = mediaPackage.getCatalogs();
// get the first smil/cutting catalog-ID to overwrite it with new smil info
for (Catalog p : catalogs) {
if (p.getFlavor().matches(mediaPackageElementFlavor)) {
logger.debug("Set Idendifier for Smil-Catalog to: " + p.getIdentifier());
catalogId = p.getIdentifier();
break;
}
}
Catalog catalog = mediaPackage.getCatalog(catalogId);
URI smilURI;
try (InputStream is = IOUtils.toInputStream(smil.toXML(), "UTF-8")) {
smilURI = workspace.put(mediaPackage.getIdentifier().compact(), catalogId, TARGET_FILE_NAME, is);
} catch (SAXException e) {
logger.error("Error while serializing the SMIL catalog to XML: {}", e.getMessage());
throw new IOException(e);
} catch (JAXBException e) {
logger.error("Error while serializing the SMIL catalog to XML: {}", e.getMessage());
throw new IOException(e);
}
if (catalog == null) {
MediaPackageElementBuilder mpeBuilder = MediaPackageElementBuilderFactory.newInstance().newElementBuilder();
catalog = (Catalog) mpeBuilder.elementFromURI(smilURI, MediaPackageElement.Type.Catalog, adminUIConfiguration.getSmilCatalogFlavor());
mediaPackage.add(catalog);
}
catalog.setURI(smilURI);
catalog.setIdentifier(catalogId);
catalog.setMimeType(MimeTypes.XML);
for (String tag : adminUIConfiguration.getSmilCatalogTags()) {
catalog.addTag(tag);
}
// setting the URI to a new source so the checksum will most like be invalid
catalog.setChecksum(null);
try {
// FIXME SWITCHP-333: Start in new thread
assetManager.takeSnapshot(DEFAULT_OWNER, mediaPackage);
} catch (AssetManagerException e) {
logger.error("Error while adding the updated media package ({}) to the archive: {}", mediaPackage.getIdentifier(), e.getMessage());
throw new IOException(e);
}
return mediaPackage;
}
use of org.opencastproject.mediapackage.Catalog in project opencast by opencast.
the class ToolsEndpoint method getSegments.
/**
* Analyzes the media package and tries to get information about segments out of it.
*
* @param mediaPackage
* the media package
* @return a list of segments or an empty list if no segments could be found.
*/
private List<Tuple<Long, Long>> getSegments(final MediaPackage mediaPackage) {
List<Tuple<Long, Long>> segments = new ArrayList<>();
for (Catalog smilCatalog : mediaPackage.getCatalogs(adminUIConfiguration.getSmilCatalogFlavor())) {
try {
Smil smil = smilService.fromXml(workspace.get(smilCatalog.getURI())).getSmil();
segments = mergeSegments(segments, getSegmentsFromSmil(smil));
} catch (NotFoundException e) {
logger.warn("File '{}' could not be loaded by workspace service: {}", smilCatalog.getURI(), getStackTrace(e));
} catch (IOException e) {
logger.warn("Reading file '{}' from workspace service failed: {}", smilCatalog.getURI(), getStackTrace(e));
} catch (SmilException e) {
logger.warn("Error while parsing SMIL catalog '{}': {}", smilCatalog.getURI(), getStackTrace(e));
}
}
if (!segments.isEmpty())
return segments;
// Read from silence detection flavors
for (Catalog smilCatalog : mediaPackage.getCatalogs(adminUIConfiguration.getSmilSilenceFlavor())) {
try {
Smil smil = smilService.fromXml(workspace.get(smilCatalog.getURI())).getSmil();
segments = mergeSegments(segments, getSegmentsFromSmil(smil));
} catch (NotFoundException e) {
logger.warn("File '{}' could not be loaded by workspace service: {}", smilCatalog.getURI(), getStackTrace(e));
} catch (IOException e) {
logger.warn("Reading file '{}' from workspace service failed: {}", smilCatalog.getURI(), getStackTrace(e));
} catch (SmilException e) {
logger.warn("Error while parsing SMIL catalog '{}': {}", smilCatalog.getURI(), getStackTrace(e));
}
}
// Check for single segment to ignore
if (segments.size() == 1) {
Tuple<Long, Long> singleSegment = segments.get(0);
if (singleSegment.getA() == 0 && singleSegment.getB() >= mediaPackage.getDuration())
segments.remove(0);
}
return segments;
}
Aggregations