use of org.opencastproject.mediapackage.MediaPackageElementBuilder in project opencast by opencast.
the class TimelinePreviewsServiceImpl method createPreviewsFFmpeg.
/**
* Executes the FFmpeg command to generate a timeline previews image
*
* @param track the track to generate the timeline previews image for
* @param seconds the length of a segment that one preview image should represent
* @param width the width of a single preview image
* @param height the height of a single preview image
* @param tileX the horizontal number of preview images that are stored in the timeline previews image
* @param tileY the vertical number of preview images that are stored in the timeline previews image
* @param duration the duration for which preview images should be generated
* @return an attachment containing the timeline previews image
* @throws TimelinePreviewsException
*/
protected Attachment createPreviewsFFmpeg(Track track, double seconds, int width, int height, int tileX, int tileY, double duration) throws TimelinePreviewsException {
// copy source file into workspace
File mediaFile;
try {
mediaFile = workspace.get(track.getURI());
} catch (NotFoundException e) {
throw new TimelinePreviewsException("Error finding the media file in the workspace", e);
} catch (IOException e) {
throw new TimelinePreviewsException("Error reading the media file in the workspace", e);
}
String imageFilePath = FilenameUtils.removeExtension(mediaFile.getAbsolutePath()) + '_' + UUID.randomUUID() + "_timelinepreviews" + outputFormat;
int exitCode = 1;
String[] command = new String[] { binary, "-loglevel", "error", "-t", String.valueOf(duration - seconds / 2.0), "-i", mediaFile.getAbsolutePath(), "-vf", "fps=1/" + seconds + ",scale=" + width + ":" + height + ",tile=" + tileX + "x" + tileY, imageFilePath };
logger.debug("Start timeline previews ffmpeg process: {}", StringUtils.join(command, " "));
logger.info("Create timeline preview images file for track '{}' at {}", track.getIdentifier(), imageFilePath);
ProcessBuilder pbuilder = new ProcessBuilder(command);
pbuilder.redirectErrorStream(true);
Process ffmpegProcess = null;
exitCode = 1;
BufferedReader errStream = null;
try {
ffmpegProcess = pbuilder.start();
errStream = new BufferedReader(new InputStreamReader(ffmpegProcess.getInputStream()));
String line = errStream.readLine();
while (line != null) {
logger.error("FFmpeg error: " + line);
line = errStream.readLine();
}
exitCode = ffmpegProcess.waitFor();
} catch (IOException ex) {
throw new TimelinePreviewsException("Starting ffmpeg process failed", ex);
} catch (InterruptedException ex) {
throw new TimelinePreviewsException("Timeline preview creation was unexpectedly interrupted", ex);
} finally {
IoSupport.closeQuietly(ffmpegProcess);
IoSupport.closeQuietly(errStream);
if (exitCode != 0) {
try {
FileUtils.forceDelete(new File(imageFilePath));
} catch (IOException e) {
// it is ok, no output file was generated by ffmpeg
}
}
}
if (exitCode != 0)
throw new TimelinePreviewsException("Generating timeline preview for track " + track.getIdentifier() + " failed: ffmpeg process exited abnormally with exit code " + exitCode);
// put timeline previews image into workspace
FileInputStream timelinepreviewsFileInputStream = null;
URI previewsFileUri = null;
try {
timelinepreviewsFileInputStream = new FileInputStream(imageFilePath);
previewsFileUri = workspace.putInCollection(COLLECTION_ID, FilenameUtils.getName(imageFilePath), timelinepreviewsFileInputStream);
logger.info("Copied the created timeline preview images file to the workspace {}", previewsFileUri.toString());
} catch (FileNotFoundException ex) {
throw new TimelinePreviewsException(String.format("Timeline previews image file '%s' not found", imageFilePath), ex);
} catch (IOException ex) {
throw new TimelinePreviewsException(String.format("Can't write timeline preview images file '%s' to workspace", imageFilePath), ex);
} catch (IllegalArgumentException ex) {
throw new TimelinePreviewsException(ex);
} finally {
IoSupport.closeQuietly(timelinepreviewsFileInputStream);
logger.info("Deleted local timeline preview images file at {}", imageFilePath);
FileUtils.deleteQuietly(new File(imageFilePath));
}
// create media package element
MediaPackageElementBuilder mpElementBuilder = MediaPackageElementBuilderFactory.newInstance().newElementBuilder();
// it is up to the workflow operation handler to set the attachment flavor
Attachment timelinepreviewsMpe = (Attachment) mpElementBuilder.elementFromURI(previewsFileUri, MediaPackageElement.Type.Attachment, track.getFlavor());
// add reference to track
timelinepreviewsMpe.referTo(track);
// add additional properties to attachment
timelinepreviewsMpe.getProperties().put("imageSizeX", String.valueOf(tileX));
timelinepreviewsMpe.getProperties().put("imageSizeY", String.valueOf(tileY));
timelinepreviewsMpe.getProperties().put("resolutionX", String.valueOf(resolutionX));
timelinepreviewsMpe.getProperties().put("resolutionY", String.valueOf(resolutionY));
// set the flavor and an ID
timelinepreviewsMpe.setFlavor(track.getFlavor());
timelinepreviewsMpe.setIdentifier(IdBuilderFactory.newInstance().newIdBuilder().createNew().compact());
return timelinepreviewsMpe;
}
use of org.opencastproject.mediapackage.MediaPackageElementBuilder in project opencast by opencast.
the class IBMWatsonTranscriptionService method getGeneratedTranscription.
@Override
public MediaPackageElement getGeneratedTranscription(String mpId, String jobId) throws TranscriptionServiceException {
try {
// If jobId is unknown, look for all jobs associated to that mpId
if (jobId == null || "null".equals(jobId)) {
jobId = null;
for (TranscriptionJobControl jc : database.findByMediaPackage(mpId)) {
if (TranscriptionJobControl.Status.Closed.name().equals(jc.getStatus()) || TranscriptionJobControl.Status.TranscriptionComplete.name().equals(jc.getStatus()))
jobId = jc.getTranscriptionJobId();
}
}
if (jobId == null)
throw new TranscriptionServiceException("No completed or closed transcription job found in database for media package " + mpId);
// Results already saved?
URI uri = workspace.getCollectionURI(TRANSCRIPT_COLLECTION, buildResultsFileName(jobId));
try {
workspace.get(uri);
} catch (Exception e) {
// Not saved yet so call the ibm watson service to get the results
getAndSaveJobResults(jobId);
}
MediaPackageElementBuilder builder = MediaPackageElementBuilderFactory.newInstance().newElementBuilder();
return builder.elementFromURI(uri, Attachment.TYPE, new MediaPackageElementFlavor("captions", "ibm-watson-json"));
} catch (TranscriptionDatabaseException e) {
throw new TranscriptionServiceException("Job id not informed and could not find transcription", e);
}
}
use of org.opencastproject.mediapackage.MediaPackageElementBuilder in project opencast by opencast.
the class ExportWorkflowPropertiesWOH method start.
@Override
public WorkflowOperationResult start(WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
logger.info("Start exporting workflow properties for workflow {}", workflowInstance);
final MediaPackage mediaPackage = workflowInstance.getMediaPackage();
final Set<String> keys = $(getOptConfig(workflowInstance, KEYS_PROPERTY)).bind(Strings.splitCsv).toSet();
final String targetFlavorString = getOptConfig(workflowInstance, TARGET_FLAVOR_PROPERTY).getOr(DEFAULT_TARGET_FLAVOR);
final Stream<String> targetTags = $(getOptConfig(workflowInstance, TARGET_TAGS_PROPERTY)).bind(Strings.splitCsv);
final MediaPackageElementFlavor targetFlavor = MediaPackageElementFlavor.parseFlavor(targetFlavorString);
// Read optional existing workflow properties from mediapackage
Properties workflowProps = new Properties();
Opt<Attachment> existingPropsElem = loadPropertiesElementFromMediaPackage(targetFlavor, workflowInstance);
if (existingPropsElem.isSome()) {
workflowProps = loadPropertiesFromXml(workspace, existingPropsElem.get().getURI());
// Remove specified keys
for (String key : keys) workflowProps.remove(key);
}
// Extend with specified properties
for (String key : workflowInstance.getConfigurationKeys()) {
if (keys.isEmpty() || keys.contains(key))
workflowProps.put(key, workflowInstance.getConfiguration(key));
}
// Store properties as an attachment
Attachment attachment;
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
workflowProps.storeToXML(out, null, "UTF-8");
String elementId = UUID.randomUUID().toString();
URI uri = workspace.put(mediaPackage.getIdentifier().compact(), elementId, EXPORTED_PROPERTIES_FILENAME, new ByteArrayInputStream(out.toByteArray()));
MediaPackageElementBuilder builder = MediaPackageElementBuilderFactory.newInstance().newElementBuilder();
attachment = (Attachment) builder.elementFromURI(uri, Attachment.TYPE, targetFlavor);
attachment.setMimeType(MimeTypes.XML);
} catch (IOException e) {
logger.error("Unable to store workflow properties as Attachment with flavor '{}': {}", targetFlavorString, ExceptionUtils.getStackTrace(e));
throw new WorkflowOperationException("Unable to store workflow properties as Attachment", e);
}
// Add the target tags
for (String tag : targetTags) {
logger.trace("Tagging with '{}'", tag);
attachment.addTag(tag);
}
// Update attachment
if (existingPropsElem.isSome())
mediaPackage.remove(existingPropsElem.get());
mediaPackage.add(attachment);
logger.info("Added properties from {} as Attachment with flavor {}", workflowInstance, targetFlavorString);
logger.debug("Workflow properties: {}", propertiesAsString(workflowProps));
return createResult(mediaPackage, null, Action.CONTINUE, 0);
}
use of org.opencastproject.mediapackage.MediaPackageElementBuilder in project opencast by opencast.
the class AttachmentTest method testFromURL.
/**
* Test method for {@link org.opencastproject.mediapackage.attachment.AttachmentImpl#fromURI(java.net.URI)}.
*/
@Test
public void testFromURL() {
MediaPackageElementBuilderFactory factory = MediaPackageElementBuilderFactory.newInstance();
MediaPackageElementBuilder builder = factory.newElementBuilder();
MediaPackageElement packageElement = null;
// Create the element
try {
packageElement = builder.elementFromURI(coverFile.toURI());
} catch (UnsupportedElementException e) {
fail("Attachment is unsupported: " + e.getMessage());
}
// Type test
assertTrue("Type mismatch", packageElement instanceof Attachment);
}
use of org.opencastproject.mediapackage.MediaPackageElementBuilder in project opencast by opencast.
the class MediaInspector method inspectTrack.
/**
* Inspects the element that is passed in as uri.
*
* @param trackURI
* the element uri
* @return the inspected track
* @throws org.opencastproject.inspection.api.MediaInspectionException
* if inspection fails
*/
public Track inspectTrack(URI trackURI, Map<String, String> options) throws MediaInspectionException {
logger.debug("inspect(" + trackURI + ") called, using workspace " + workspace);
throwExceptionIfInvalid(options);
try {
// Get the file from the URL (runtime exception if invalid)
File file = null;
try {
file = workspace.get(trackURI);
} catch (NotFoundException notFound) {
throw new MediaInspectionException("Unable to find resource " + trackURI, notFound);
} catch (IOException ioe) {
throw new MediaInspectionException("Error reading " + trackURI + " from workspace", ioe);
}
// TODO: Try to guess the extension from the container's metadata
if ("".equals(FilenameUtils.getExtension(file.getName()))) {
throw new MediaInspectionException("Can not inspect files without a filename extension");
}
MediaContainerMetadata metadata = getFileMetadata(file, getAccurateFrameCount(options));
if (metadata == null) {
throw new MediaInspectionException("Media analyzer returned no metadata from " + file);
} else {
MediaPackageElementBuilder elementBuilder = MediaPackageElementBuilderFactory.newInstance().newElementBuilder();
TrackImpl track;
MediaPackageElement element;
try {
element = elementBuilder.elementFromURI(trackURI, MediaPackageElement.Type.Track, null);
} catch (UnsupportedElementException e) {
throw new MediaInspectionException("Unable to create track element from " + file, e);
}
track = (TrackImpl) element;
// Duration
if (metadata.getDuration() != null && metadata.getDuration() > 0)
track.setDuration(metadata.getDuration());
// Checksum
try {
track.setChecksum(Checksum.create(ChecksumType.DEFAULT_TYPE, file));
} catch (IOException e) {
throw new MediaInspectionException("Unable to read " + file, e);
}
// Mimetype
InputStream is = null;
try {
// Try to get the Mimetype from Apache Tika
is = new FileInputStream(file);
MimeType mimeType = extractContentType(is);
// If Mimetype could not be extracted try to get it from opencast
if (mimeType == null) {
mimeType = MimeTypes.fromURL(file.toURI().toURL());
// The mimetype library doesn't know about audio/video metadata, so the type might be wrong.
if ("audio".equals(mimeType.getType()) && metadata.hasVideoStreamMetadata()) {
mimeType = MimeTypes.parseMimeType("video/" + mimeType.getSubtype());
} else if ("video".equals(mimeType.getType()) && !metadata.hasVideoStreamMetadata()) {
mimeType = MimeTypes.parseMimeType("audio/" + mimeType.getSubtype());
}
}
track.setMimeType(mimeType);
} catch (Exception e) {
logger.error("Unable to find mimetype for {}", file.getAbsolutePath());
} finally {
IoSupport.closeQuietly(is);
}
// Audio metadata
try {
addAudioStreamMetadata(track, metadata);
} catch (Exception e) {
throw new MediaInspectionException("Unable to extract audio metadata from " + file, e);
}
// Videometadata
try {
addVideoStreamMetadata(track, metadata);
} catch (Exception e) {
throw new MediaInspectionException("Unable to extract video metadata from " + file, e);
}
return track;
}
} catch (Exception e) {
logger.warn("Error inspecting " + trackURI, e);
if (e instanceof MediaInspectionException) {
throw (MediaInspectionException) e;
} else {
throw new MediaInspectionException(e);
}
}
}
Aggregations