use of org.opencastproject.mediapackage.Attachment in project opencast by opencast.
the class TextAnalyzerServiceImpl method extract.
/**
* Starts text extraction on the image and returns a receipt containing the final result in the form of an
* Mpeg7Catalog.
*
* @param image
* the element to analyze
* @param block
* <code>true</code> to make this operation synchronous
* @return a receipt containing the resulting mpeg-7 catalog
* @throws TextAnalyzerException
*/
private Catalog extract(Job job, Attachment image) throws TextAnalyzerException, MediaPackageException {
final Attachment attachment = image;
final URI imageUrl = attachment.getURI();
File imageFile = null;
try {
Mpeg7CatalogImpl mpeg7 = Mpeg7CatalogImpl.newInstance();
logger.info("Starting text extraction from {}", imageUrl);
try {
imageFile = workspace.get(imageUrl);
} catch (NotFoundException e) {
throw new TextAnalyzerException("Image " + imageUrl + " not found in workspace", e);
} catch (IOException e) {
throw new TextAnalyzerException("Unable to access " + imageUrl + " in workspace", e);
}
VideoText[] videoTexts = analyze(imageFile, image.getIdentifier());
// Create a temporal decomposition
MediaTime mediaTime = new MediaTimeImpl(0, 0);
Video avContent = mpeg7.addVideoContent(image.getIdentifier(), mediaTime, null);
TemporalDecomposition<VideoSegment> temporalDecomposition = (TemporalDecomposition<VideoSegment>) avContent.getTemporalDecomposition();
// Add a segment
VideoSegment videoSegment = temporalDecomposition.createSegment("segment-0");
videoSegment.setMediaTime(mediaTime);
// Add the video text to the spacio temporal decomposition of the segment
SpatioTemporalDecomposition spatioTemporalDecomposition = videoSegment.createSpatioTemporalDecomposition(true, false);
for (VideoText videoText : videoTexts) {
spatioTemporalDecomposition.addVideoText(videoText);
}
logger.info("Text extraction of {} finished, {} lines found", attachment.getURI(), videoTexts.length);
URI uri;
InputStream in;
try {
in = mpeg7CatalogService.serialize(mpeg7);
} catch (IOException e) {
throw new TextAnalyzerException("Error serializing mpeg7", e);
}
try {
uri = workspace.putInCollection(COLLECTION_ID, job.getId() + ".xml", in);
} catch (IOException e) {
throw new TextAnalyzerException("Unable to put mpeg7 into the workspace", e);
}
Catalog catalog = (Catalog) MediaPackageElementBuilderFactory.newInstance().newElementBuilder().newElement(Catalog.TYPE, MediaPackageElements.TEXTS);
catalog.setURI(uri);
logger.debug("Created MPEG7 catalog for {}", imageUrl);
return catalog;
} catch (Exception e) {
logger.warn("Error extracting text from " + imageUrl, e);
if (e instanceof TextAnalyzerException) {
throw (TextAnalyzerException) e;
} else {
throw new TextAnalyzerException(e);
}
} finally {
try {
workspace.delete(imageUrl);
} catch (Exception e) {
logger.warn("Unable to delete temporary text analysis image {}: {}", imageUrl, e);
}
}
}
use of org.opencastproject.mediapackage.Attachment in project opencast by opencast.
the class TextAnalyzerServiceImpl method process.
/**
* {@inheritDoc}
*
* @see org.opencastproject.job.api.AbstractJobProducer#process(org.opencastproject.job.api.Job)
*/
@Override
protected String process(Job job) throws Exception {
Operation op = null;
String operation = job.getOperation();
List<String> arguments = job.getArguments();
try {
op = Operation.valueOf(operation);
switch(op) {
case Extract:
Attachment element = (Attachment) MediaPackageElementParser.getFromXml(arguments.get(0));
Catalog catalog = extract(job, element);
return MediaPackageElementParser.getAsXml(catalog);
default:
throw new IllegalStateException("Don't know how to handle operation '" + operation + "'");
}
} catch (IllegalArgumentException e) {
throw new ServiceRegistryException("This service can't handle operations of type '" + op + "'", e);
} catch (IndexOutOfBoundsException e) {
throw new ServiceRegistryException("This argument list for operation '" + op + "' does not meet expectations", e);
} catch (Exception e) {
throw new ServiceRegistryException("Error handling operation '" + op + "'", e);
}
}
use of org.opencastproject.mediapackage.Attachment 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.Attachment in project opencast by opencast.
the class TimelinePreviewsServiceImpl method process.
/**
* {@inheritDoc}
*
* @see org.opencastproject.job.api.AbstractJobProducer#process(org.opencastproject.job.api.Job)
*/
@Override
protected String process(Job job) throws Exception {
Operation op = null;
String operation = job.getOperation();
List<String> arguments = job.getArguments();
try {
op = Operation.valueOf(operation);
switch(op) {
case TimelinePreview:
Track track = (Track) MediaPackageElementParser.getFromXml(arguments.get(0));
int imageCount = Integer.parseInt(arguments.get(1));
Attachment timelinePreviewsMpe = generatePreviewImages(job, track, imageCount);
return MediaPackageElementParser.getAsXml(timelinePreviewsMpe);
default:
throw new IllegalStateException("Don't know how to handle operation '" + operation + "'");
}
} catch (IllegalArgumentException e) {
throw new ServiceRegistryException("This service can't handle operations of type '" + op + "'", e);
} catch (IndexOutOfBoundsException e) {
throw new ServiceRegistryException("This argument list for operation '" + op + "' does not meet expectations", e);
} catch (Exception e) {
throw new ServiceRegistryException("Error handling operation '" + op + "'", e);
}
}
use of org.opencastproject.mediapackage.Attachment in project opencast by opencast.
the class SchedulerServiceImplTest method addAcl.
private String addAcl(Opt<String> id, MediaPackage mediaPackage, final AccessControlList acl) throws Exception {
String attachmentId = UUID.randomUUID().toString();
Attachment attachment = null;
if (id.isSome()) {
attachmentId = id.get();
attachment = mediaPackage.getAttachment(attachmentId);
}
URI uri = workspace.put(mediaPackage.getIdentifier().compact(), attachmentId, "security.xml", IOUtils.toInputStream(XACMLUtils.getXacml(mediaPackage, acl), StandardCharsets.UTF_8.name()));
if (attachment == null) {
attachment = (Attachment) mediaPackage.add(uri, Type.Attachment, MediaPackageElements.XACML_POLICY_EPISODE);
attachment.setIdentifier(attachmentId);
}
attachment.setChecksum(null);
return attachmentId;
}
Aggregations