use of org.opencastproject.mediapackage.Attachment in project opencast by opencast.
the class ComposerServiceTest method testConvertImage.
@Test
public void testConvertImage() throws Exception {
assertTrue(sourceImage.isFile());
Attachment imageAttachment = (Attachment) MediaPackageElementParser.getFromXml(IOUtils.toString(ComposerServiceTest.class.getResourceAsStream("/composer_test_source_attachment_image.xml"), Charset.defaultCharset()));
// Need different media files
Workspace workspace = EasyMock.createNiceMock(Workspace.class);
EasyMock.expect(workspace.get(EasyMock.anyObject())).andReturn(sourceImage).anyTimes();
EasyMock.expect(workspace.putInCollection(EasyMock.anyString(), EasyMock.anyString(), EasyMock.anyObject())).andReturn(sourceImage.toURI()).anyTimes();
composerService.setWorkspace(workspace);
EasyMock.replay(workspace);
Job job = composerService.convertImage(imageAttachment, "image-conversion.http");
MediaPackageElementParser.getFromXml(job.getPayload());
}
use of org.opencastproject.mediapackage.Attachment in project opencast by opencast.
the class WaveformServiceImpl method extractWaveform.
/**
* Create and run waveform extraction ffmpeg command.
*
* @param track source audio/video track with at least one audio channel
* @return waveform image attachment
* @throws WaveformServiceException if processing fails
*/
private Attachment extractWaveform(Track track) throws WaveformServiceException {
if (!track.hasAudio()) {
throw new WaveformServiceException("Track has no audio");
}
// copy source file into workspace
File mediaFile;
try {
mediaFile = workspace.get(track.getURI());
} catch (NotFoundException e) {
throw new WaveformServiceException("Error finding the media file in the workspace", e);
} catch (IOException e) {
throw new WaveformServiceException("Error reading the media file in the workspace", e);
}
String waveformFilePath = FilenameUtils.removeExtension(mediaFile.getAbsolutePath()).concat('-' + track.getIdentifier()).concat("-waveform.png");
// create ffmpeg command
String[] command = new String[] { binary, "-nostats", "-i", mediaFile.getAbsolutePath(), "-lavfi", createWaveformFilter(track), "-an", "-vn", "-sn", "-y", waveformFilePath };
logger.debug("Start waveform ffmpeg process: {}", StringUtils.join(command, " "));
logger.info("Create waveform image file for track '{}' at {}", track.getIdentifier(), waveformFilePath);
// run ffmpeg
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process ffmpegProcess = null;
int exitCode = 1;
BufferedReader errStream = null;
try {
ffmpegProcess = pb.start();
errStream = new BufferedReader(new InputStreamReader(ffmpegProcess.getInputStream()));
String line = errStream.readLine();
while (line != null) {
logger.debug(line);
line = errStream.readLine();
}
exitCode = ffmpegProcess.waitFor();
} catch (IOException ex) {
throw new WaveformServiceException("Start ffmpeg process failed", ex);
} catch (InterruptedException ex) {
throw new WaveformServiceException("Waiting for encoder process exited was interrupted unexpectly", ex);
} finally {
IoSupport.closeQuietly(ffmpegProcess);
IoSupport.closeQuietly(errStream);
if (exitCode != 0) {
try {
FileUtils.forceDelete(new File(waveformFilePath));
} catch (IOException e) {
// it is ok, no output file was generated by ffmpeg
}
}
}
if (exitCode != 0)
throw new WaveformServiceException("The encoder process exited abnormally with exit code " + exitCode);
// put waveform image into workspace
FileInputStream waveformFileInputStream = null;
URI waveformFileUri;
try {
waveformFileInputStream = new FileInputStream(waveformFilePath);
waveformFileUri = workspace.putInCollection(COLLECTION_ID, FilenameUtils.getName(waveformFilePath), waveformFileInputStream);
logger.info("Copied the created waveform to the workspace {}", waveformFileUri);
} catch (FileNotFoundException ex) {
throw new WaveformServiceException(String.format("Waveform image file '%s' not found", waveformFilePath), ex);
} catch (IOException ex) {
throw new WaveformServiceException(String.format("Can't write waveform image file '%s' to workspace", waveformFilePath), ex);
} catch (IllegalArgumentException ex) {
throw new WaveformServiceException(ex);
} finally {
IoSupport.closeQuietly(waveformFileInputStream);
logger.info("Deleted local waveform image file at {}", waveformFilePath);
FileUtils.deleteQuietly(new File(waveformFilePath));
}
// create media package element
MediaPackageElementBuilder mpElementBuilder = MediaPackageElementBuilderFactory.newInstance().newElementBuilder();
// it is up to the workflow operation handler to set the attachment flavor
Attachment waveformMpe = (Attachment) mpElementBuilder.elementFromURI(waveformFileUri, Type.Attachment, track.getFlavor());
waveformMpe.setIdentifier(IdBuilderFactory.newInstance().newIdBuilder().createNew().compact());
return waveformMpe;
}
use of org.opencastproject.mediapackage.Attachment in project opencast by opencast.
the class WaveformWorkflowOperationHandlerTest method setUp.
@Before
public void setUp() throws Exception {
handler = new WaveformWorkflowOperationHandler() {
@Override
protected JobBarrier.Result waitForStatus(Job... jobs) throws IllegalStateException, IllegalArgumentException {
JobBarrier.Result result = EasyMock.createNiceMock(JobBarrier.Result.class);
EasyMock.expect(result.isSuccess()).andReturn(true).anyTimes();
EasyMock.replay(result);
return result;
}
};
track = new TrackImpl();
track.setFlavor(MediaPackageElementFlavor.parseFlavor("xy/source"));
track.setAudio(Arrays.asList(null, null));
MediaPackageBuilder builder = new MediaPackageBuilderImpl();
MediaPackage mediaPackage = builder.createNew();
mediaPackage.setIdentifier(new IdImpl("123-456"));
mediaPackage.add(track);
instance = EasyMock.createNiceMock(WorkflowOperationInstanceImpl.class);
EasyMock.expect(instance.getConfiguration("target-flavor")).andReturn("*/*").anyTimes();
EasyMock.expect(instance.getConfiguration("target-tags")).andReturn("a,b,c").anyTimes();
workflow = EasyMock.createNiceMock(WorkflowInstanceImpl.class);
EasyMock.expect(workflow.getMediaPackage()).andReturn(mediaPackage).anyTimes();
EasyMock.expect(workflow.getCurrentOperation()).andReturn(instance).anyTimes();
Attachment payload = new AttachmentImpl();
payload.setIdentifier("x");
payload.setFlavor(MediaPackageElementFlavor.parseFlavor("xy/source"));
Job job = new JobImpl(0);
job.setPayload(MediaPackageElementParser.getAsXml(payload));
WaveformService waveformService = EasyMock.createNiceMock(WaveformService.class);
EasyMock.expect(waveformService.createWaveformImage(EasyMock.anyObject())).andReturn(job);
Workspace workspace = EasyMock.createNiceMock(Workspace.class);
EasyMock.replay(waveformService, workspace, workflow);
handler.setWaveformService(waveformService);
handler.setWorkspace(workspace);
}
use of org.opencastproject.mediapackage.Attachment 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.Attachment in project opencast by opencast.
the class ToolsEndpoint method getVideoEditor.
@GET
@Path("{mediapackageid}/editor.json")
@Produces(MediaType.APPLICATION_JSON)
@RestQuery(name = "getVideoEditor", description = "Returns all the information required to get the editor tool started", returnDescription = "JSON object", pathParameters = { @RestParameter(name = "mediapackageid", description = "The id of the media package", isRequired = true, type = RestParameter.Type.STRING) }, reponses = { @RestResponse(description = "Media package found", responseCode = SC_OK), @RestResponse(description = "Media package not found", responseCode = SC_NOT_FOUND) })
public Response getVideoEditor(@PathParam("mediapackageid") final String mediaPackageId) throws IndexServiceException, NotFoundException {
if (!isEditorAvailable(mediaPackageId))
return R.notFound();
// Select tracks
final Event event = getEvent(mediaPackageId).get();
final MediaPackage mp = index.getEventMediapackage(event);
List<MediaPackageElement> previewPublications = getPreviewElementsFromPublication(getInternalPublication(mp));
// Collect previews and tracks
List<JValue> jPreviews = new ArrayList<>();
List<JValue> jTracks = new ArrayList<>();
for (MediaPackageElement element : previewPublications) {
final URI elementUri;
if (urlSigningService.accepts(element.getURI().toString())) {
try {
String clientIP = null;
if (signWithClientIP) {
clientIP = securityService.getUserIP();
}
elementUri = new URI(urlSigningService.sign(element.getURI().toString(), expireSeconds, null, clientIP));
} catch (URISyntaxException e) {
logger.error("Error while trying to sign the preview urls because: {}", getStackTrace(e));
throw new WebApplicationException(e, SC_INTERNAL_SERVER_ERROR);
} catch (UrlSigningException e) {
logger.error("Error while trying to sign the preview urls because: {}", getStackTrace(e));
throw new WebApplicationException(e, SC_INTERNAL_SERVER_ERROR);
}
} else {
elementUri = element.getURI();
}
jPreviews.add(obj(f("uri", v(elementUri.toString())), f("flavor", v(element.getFlavor().getType()))));
if (!Type.Track.equals(element.getElementType()))
continue;
JObject jTrack = obj(f("id", v(element.getIdentifier())), f("flavor", v(element.getFlavor().getType())));
// Check if there's a waveform for the current track
Opt<Attachment> optWaveform = getWaveformForTrack(mp, element);
if (optWaveform.isSome()) {
final URI waveformUri;
if (urlSigningService.accepts(element.getURI().toString())) {
try {
waveformUri = new URI(urlSigningService.sign(optWaveform.get().getURI().toString(), expireSeconds, null, null));
} catch (URISyntaxException e) {
logger.error("Error while trying to serialize the waveform urls because: {}", getStackTrace(e));
throw new WebApplicationException(e, SC_INTERNAL_SERVER_ERROR);
} catch (UrlSigningException e) {
logger.error("Error while trying to sign the preview urls because: {}", getStackTrace(e));
throw new WebApplicationException(e, SC_INTERNAL_SERVER_ERROR);
}
} else {
waveformUri = optWaveform.get().getURI();
}
jTracks.add(jTrack.merge(obj(f("waveform", v(waveformUri.toString())))));
} else {
jTracks.add(jTrack);
}
}
// Get existing segments
List<JValue> jSegments = new ArrayList<>();
for (Tuple<Long, Long> segment : getSegments(mp)) {
jSegments.add(obj(f(START_KEY, v(segment.getA())), f(END_KEY, v(segment.getB()))));
}
// Get workflows
List<JValue> jWorkflows = new ArrayList<>();
for (WorkflowDefinition workflow : getEditingWorkflows()) {
jWorkflows.add(obj(f("id", v(workflow.getId())), f("name", v(workflow.getTitle(), Jsons.BLANK))));
}
return RestUtils.okJson(obj(f("title", v(mp.getTitle(), Jsons.BLANK)), f("date", v(event.getRecordingStartDate(), Jsons.BLANK)), f("series", obj(f("id", v(event.getSeriesId(), Jsons.BLANK)), f("title", v(event.getSeriesName(), Jsons.BLANK)))), f("presenters", arr($(event.getPresenters()).map(Functions.stringToJValue))), f("previews", arr(jPreviews)), f(TRACKS_KEY, arr(jTracks)), f("duration", v(mp.getDuration())), f(SEGMENTS_KEY, arr(jSegments)), f("workflows", arr(jWorkflows))));
}
Aggregations