use of org.opencastproject.composer.api.EncodingProfile in project opencast by opencast.
the class ComposerServiceImpl method composite.
/**
* {@inheritDoc}
*/
@Override
public Job composite(Dimension compositeTrackSize, Option<LaidOutElement<Track>> upperTrack, LaidOutElement<Track> lowerTrack, Option<LaidOutElement<Attachment>> watermark, String profileId, String background) throws EncoderException, MediaPackageException {
List<String> arguments = new ArrayList<>(9);
arguments.add(PROFILE_ID_INDEX, profileId);
arguments.add(LOWER_TRACK_INDEX, MediaPackageElementParser.getAsXml(lowerTrack.getElement()));
arguments.add(LOWER_TRACK_LAYOUT_INDEX, Serializer.json(lowerTrack.getLayout()).toJson());
if (upperTrack.isNone()) {
arguments.add(UPPER_TRACK_INDEX, NOT_AVAILABLE);
arguments.add(UPPER_TRACK_LAYOUT_INDEX, NOT_AVAILABLE);
} else {
arguments.add(UPPER_TRACK_INDEX, MediaPackageElementParser.getAsXml(upperTrack.get().getElement()));
arguments.add(UPPER_TRACK_LAYOUT_INDEX, Serializer.json(upperTrack.get().getLayout()).toJson());
}
arguments.add(COMPOSITE_TRACK_SIZE_INDEX, Serializer.json(compositeTrackSize).toJson());
arguments.add(BACKGROUND_COLOR_INDEX, background);
if (watermark.isSome()) {
LaidOutElement<Attachment> watermarkLaidOutElement = watermark.get();
arguments.add(WATERMARK_INDEX, MediaPackageElementParser.getAsXml(watermarkLaidOutElement.getElement()));
arguments.add(WATERMARK_LAYOUT_INDEX, Serializer.json(watermarkLaidOutElement.getLayout()).toJson());
}
try {
final EncodingProfile profile = profileScanner.getProfile(profileId);
return serviceRegistry.createJob(JOB_TYPE, Operation.Composite.toString(), arguments, profile.getJobLoad());
} catch (ServiceRegistryException e) {
throw new EncoderException("Unable to create composite job", e);
}
}
use of org.opencastproject.composer.api.EncodingProfile in project opencast by opencast.
the class ComposerServiceImpl method image.
@Override
public Job image(Track sourceTrack, String profileId, Map<String, String> properties) throws EncoderException, MediaPackageException {
if (sourceTrack == null)
throw new IllegalArgumentException("SourceTrack cannot be null");
List<String> arguments = new ArrayList<String>();
arguments.add(profileId);
arguments.add(MediaPackageElementParser.getAsXml(sourceTrack));
arguments.add(Boolean.FALSE.toString());
arguments.add(getPropertiesAsString(properties));
try {
final EncodingProfile profile = profileScanner.getProfile(profileId);
return serviceRegistry.createJob(JOB_TYPE, Operation.Image.toString(), arguments, profile.getJobLoad());
} catch (ServiceRegistryException e) {
throw new EncoderException("Unable to create a job", e);
}
}
use of org.opencastproject.composer.api.EncodingProfile in project opencast by opencast.
the class ComposerServiceImpl method convertImage.
/**
* {@inheritDoc}
*
* @see org.opencastproject.composer.api.ComposerService#convertImage(org.opencastproject.mediapackage.Attachment,
* java.lang.String)
*/
@Override
public Job convertImage(Attachment image, String profileId) throws EncoderException, MediaPackageException {
if (image == null)
throw new IllegalArgumentException("Source image cannot be null");
String[] parameters = new String[2];
parameters[0] = profileId;
parameters[1] = MediaPackageElementParser.getAsXml(image);
try {
final EncodingProfile profile = profileScanner.getProfile(profileId);
return serviceRegistry.createJob(JOB_TYPE, Operation.ImageConversion.toString(), Arrays.asList(parameters), profile.getJobLoad());
} catch (ServiceRegistryException e) {
throw new EncoderException("Unable to create a job", e);
}
}
use of org.opencastproject.composer.api.EncodingProfile in project opencast by opencast.
the class ComposerServiceImpl method composite.
private Option<Track> composite(Job job, Dimension compositeTrackSize, LaidOutElement<Track> lowerLaidOutElement, Option<LaidOutElement<Track>> upperLaidOutElement, Option<LaidOutElement<Attachment>> watermarkOption, String profileId, String backgroundColor) throws EncoderException, MediaPackageException {
// Get the encoding profile
final EncodingProfile profile = getProfile(job, profileId);
// Create the engine
final EncoderEngine encoderEngine = getEncoderEngine();
final String targetTrackId = idBuilder.createNew().toString();
Option<File> upperVideoFile = Option.none();
try {
// Get the tracks and make sure they exist
final File lowerVideoFile = loadTrackIntoWorkspace(job, "lower video", lowerLaidOutElement.getElement());
if (upperLaidOutElement.isSome()) {
upperVideoFile = Option.option(loadTrackIntoWorkspace(job, "upper video", upperLaidOutElement.get().getElement()));
}
File watermarkFile = null;
if (watermarkOption.isSome()) {
try {
watermarkFile = workspace.get(watermarkOption.get().getElement().getURI());
} catch (NotFoundException e) {
incident().recordFailure(job, WORKSPACE_GET_NOT_FOUND, e, getWorkspaceMediapackageParams("watermark image", watermarkOption.get().getElement()), NO_DETAILS);
throw new EncoderException("Requested watermark image " + watermarkOption.get().getElement() + " is not found");
} catch (IOException e) {
incident().recordFailure(job, WORKSPACE_GET_IO_EXCEPTION, e, getWorkspaceMediapackageParams("watermark image", watermarkOption.get().getElement()), NO_DETAILS);
throw new EncoderException("Unable to access right watermark image " + watermarkOption.get().getElement());
}
if (upperLaidOutElement.isSome()) {
logger.info("Composing lower video track {} {} and upper video track {} {} including watermark {} {} into {}", lowerLaidOutElement.getElement().getIdentifier(), lowerLaidOutElement.getElement().getURI(), upperLaidOutElement.get().getElement().getIdentifier(), upperLaidOutElement.get().getElement().getURI(), watermarkOption.get().getElement().getIdentifier(), watermarkOption.get().getElement().getURI(), targetTrackId);
} else {
logger.info("Composing video track {} {} including watermark {} {} into {}", lowerLaidOutElement.getElement().getIdentifier(), lowerLaidOutElement.getElement().getURI(), watermarkOption.get().getElement().getIdentifier(), watermarkOption.get().getElement().getURI(), targetTrackId);
}
} else {
if (upperLaidOutElement.isSome()) {
logger.info("Composing lower video track {} {} and upper video track {} {} into {}", lowerLaidOutElement.getElement().getIdentifier(), lowerLaidOutElement.getElement().getURI(), upperLaidOutElement.get().getElement().getIdentifier(), upperLaidOutElement.get().getElement().getURI(), targetTrackId);
} else {
logger.info("Composing video track {} {} into {}", lowerLaidOutElement.getElement().getIdentifier(), lowerLaidOutElement.getElement().getURI(), targetTrackId);
}
}
// Creating video filter command
final String compositeCommand = buildCompositeCommand(compositeTrackSize, lowerLaidOutElement, upperLaidOutElement, upperVideoFile, watermarkOption, watermarkFile, backgroundColor);
Map<String, String> properties = new HashMap<>();
properties.put(EncoderEngine.CMD_SUFFIX + ".compositeCommand", compositeCommand);
List<File> output;
try {
Map<String, File> source = new HashMap<>();
if (upperVideoFile.isSome()) {
source.put("audio", upperVideoFile.get());
}
source.put("video", lowerVideoFile);
output = encoderEngine.process(source, profile, properties);
} catch (EncoderException e) {
Map<String, String> params = new HashMap<>();
if (upperLaidOutElement.isSome()) {
params.put("upper", upperLaidOutElement.get().getElement().getURI().toString());
}
params.put("lower", lowerLaidOutElement.getElement().getURI().toString());
if (watermarkFile != null)
params.put("watermark", watermarkOption.get().getElement().getURI().toString());
params.put("profile", profile.getIdentifier());
params.put("properties", properties.toString());
incident().recordFailure(job, COMPOSITE_FAILED, e, params, detailsFor(e, encoderEngine));
throw e;
} finally {
activeEncoder.remove(encoderEngine);
}
// We expect one file as output
if (output.size() != 1) {
// Ensure we do not leave behind old files in the workspace
for (File file : output) {
FileUtils.deleteQuietly(file);
}
throw new EncoderException("Composite does not support multiple files as output");
}
// Put the file in the workspace
URI workspaceURI = putToCollection(job, output.get(0), "compound file");
// Have the compound track inspected and return the result
Job inspectionJob = inspect(job, workspaceURI);
Track inspectedTrack = (Track) MediaPackageElementParser.getFromXml(inspectionJob.getPayload());
inspectedTrack.setIdentifier(targetTrackId);
if (profile.getMimeType() != null)
inspectedTrack.setMimeType(MimeTypes.parseMimeType(profile.getMimeType()));
return some(inspectedTrack);
} catch (Exception e) {
if (upperLaidOutElement.isSome()) {
logger.warn("Error composing {} and {}: {}", lowerLaidOutElement.getElement(), upperLaidOutElement.get().getElement(), getStackTrace(e));
} else {
logger.warn("Error composing {}: {}", lowerLaidOutElement.getElement(), getStackTrace(e));
}
if (e instanceof EncoderException) {
throw (EncoderException) e;
} else {
throw new EncoderException(e);
}
}
}
use of org.opencastproject.composer.api.EncodingProfile in project opencast by opencast.
the class ComposerServiceImpl method extractImages.
private List<Attachment> extractImages(Job job, Track sourceTrack, String profileId, Map<String, String> properties, double... times) throws EncoderException {
logger.info("creating an image using video track {}", sourceTrack.getIdentifier());
// Get the encoding profile
final EncodingProfile profile = getProfile(job, profileId);
// Create the encoding engine
final EncoderEngine encoderEngine = getEncoderEngine();
// Finally get the file that needs to be encoded
File videoFile = loadTrackIntoWorkspace(job, "video", sourceTrack);
// Do the work
List<File> encodingOutput;
try {
encodingOutput = encoderEngine.extract(videoFile, profile, properties, times);
// check for validity of output
if (encodingOutput == null || encodingOutput.isEmpty()) {
logger.error("Image extraction from video {} with profile {} failed: no images were produced", sourceTrack.getURI(), profile.getIdentifier());
throw new EncoderException("Image extraction failed: no images were produced");
}
} catch (EncoderException e) {
Map<String, String> params = new HashMap<>();
params.put("video", sourceTrack.getURI().toString());
params.put("profile", profile.getIdentifier());
params.put("positions", Arrays.toString(times));
incident().recordFailure(job, IMAGE_EXTRACTION_FAILED, e, params, detailsFor(e, encoderEngine));
throw e;
} finally {
activeEncoder.remove(encoderEngine);
}
int i = 0;
List<URI> workspaceURIs = new LinkedList<>();
for (File output : encodingOutput) {
if (!output.exists() || output.length() == 0) {
logger.warn("Extracted image {} is empty!", output);
throw new EncoderException("Extracted image " + output.toString() + " is empty!");
}
// Put the file in the workspace
InputStream in = null;
try {
in = new FileInputStream(output);
URI returnURL = workspace.putInCollection(COLLECTION, job.getId() + "_" + i++ + "." + FilenameUtils.getExtension(output.getAbsolutePath()), in);
logger.debug("Copied image file to the workspace at {}", returnURL);
workspaceURIs.add(returnURL);
} catch (Exception e) {
cleanup(encodingOutput.toArray(new File[encodingOutput.size()]));
cleanupWorkspace(workspaceURIs.toArray(new URI[workspaceURIs.size()]));
incident().recordFailure(job, WORKSPACE_PUT_COLLECTION_IO_EXCEPTION, e, getWorkspaceCollectionParams("extracted image file", COLLECTION, output.toURI()), NO_DETAILS);
throw new EncoderException("Unable to put image file into the workspace", e);
} finally {
IOUtils.closeQuietly(in);
}
}
// cleanup
cleanup(encodingOutput.toArray(new File[encodingOutput.size()]));
MediaPackageElementBuilder builder = MediaPackageElementBuilderFactory.newInstance().newElementBuilder();
List<Attachment> imageAttachments = new LinkedList<Attachment>();
for (URI url : workspaceURIs) {
Attachment attachment = (Attachment) builder.elementFromURI(url, Attachment.TYPE, null);
imageAttachments.add(attachment);
}
return imageAttachments;
}
Aggregations