use of org.opencastproject.workflow.api.WorkflowOperationException in project opencast by opencast.
the class PartialImportWorkflowOperationHandler method extractLastImageFrame.
private Attachment extractLastImageFrame(Track presentationTrack, List<MediaPackageElement> elementsToClean) throws EncoderException, MediaPackageException, WorkflowOperationException, NotFoundException {
VideoStream[] videoStreams = TrackSupport.byType(presentationTrack.getStreams(), VideoStream.class);
Map<String, String> properties = new HashMap<String, String>();
properties.put("frame", Long.toString(videoStreams[0].getFrameCount() - 1));
Job extractImageJob = composerService.image(presentationTrack, IMAGE_FRAME_PROFILE, properties);
if (!waitForStatus(extractImageJob).isSuccess())
throw new WorkflowOperationException("Extract image frame video job did not complete successfully");
// Get the latest copy
try {
extractImageJob = serviceRegistry.getJob(extractImageJob.getId());
} catch (ServiceRegistryException e) {
throw new WorkflowOperationException(e);
}
Attachment composedImages = (Attachment) MediaPackageElementParser.getArrayFromXml(extractImageJob.getPayload()).get(0);
elementsToClean.add(composedImages);
return composedImages;
}
use of org.opencastproject.workflow.api.WorkflowOperationException in project opencast by opencast.
the class PartialImportWorkflowOperationHandler method encodeToStandard.
/**
* Encode <code>track</code> using encoding profile <code>profile</code> and add the result to media package
* <code>mp</code> under the given <code>targetFlavor</code>.
*
* @return the encoder job's queue time
*/
private long encodeToStandard(MediaPackage mp, EncodingProfile profile, MediaPackageElementFlavor targetFlavor, Track track) throws EncoderException, MediaPackageException, WorkflowOperationException, NotFoundException, ServiceRegistryException, IOException {
Job encodeJob = composerService.encode(track, profile.getIdentifier());
if (!waitForStatus(encodeJob).isSuccess()) {
throw new WorkflowOperationException("Encoding of track " + track + " failed");
}
encodeJob = serviceRegistry.getJob(encodeJob.getId());
Track encodedTrack = (Track) MediaPackageElementParser.getFromXml(encodeJob.getPayload());
if (encodedTrack == null) {
throw new WorkflowOperationException("Encoded track " + track + " failed to produce a track");
}
URI uri;
if (FilenameUtils.getExtension(encodedTrack.getURI().toString()).equalsIgnoreCase(FilenameUtils.getExtension(track.getURI().toString()))) {
uri = workspace.moveTo(encodedTrack.getURI(), mp.getIdentifier().compact(), encodedTrack.getIdentifier(), FilenameUtils.getName(track.getURI().toString()));
} else {
// The new encoded file has a different extension.
uri = workspace.moveTo(encodedTrack.getURI(), mp.getIdentifier().compact(), encodedTrack.getIdentifier(), FilenameUtils.getBaseName(track.getURI().toString()) + "." + FilenameUtils.getExtension(encodedTrack.getURI().toString()));
}
encodedTrack.setURI(uri);
encodedTrack.setFlavor(targetFlavor);
mp.add(encodedTrack);
return encodeJob.getQueueTime();
}
use of org.opencastproject.workflow.api.WorkflowOperationException in project opencast by opencast.
the class PartialImportWorkflowOperationHandler method getSmilDocument.
/**
* Get the SMIL document from a catalog.
*/
private SMILDocument getSmilDocument(final Catalog smilCatalog) throws WorkflowOperationException {
FileInputStream in = null;
try {
File smilXmlFile = workspace.get(smilCatalog.getURI());
SmilXmlParser smilParser = new SmilXmlParser();
in = new FileInputStream(smilXmlFile);
return smilParser.parse(in);
} catch (Exception e) {
logger.error("Unable to parse smil catalog {}! {}", smilCatalog.getURI(), e);
throw new WorkflowOperationException(e);
} finally {
IOUtils.closeQuietly(in);
}
}
use of org.opencastproject.workflow.api.WorkflowOperationException in project opencast by opencast.
the class PrepareAVWorkflowOperationHandler method mux.
/**
* Merges audio and video track of the selected flavor and adds it to the media package. If there is nothing to mux, a
* new track with the target flavor is created (pointing to the original url).
*
* @param src
* The source media package
* @param operation
* the mux workflow operation
* @return the operation result containing the updated mediapackage
* @throws EncoderException
* if encoding fails
* @throws IOException
* if read/write operations from and to the workspace fail
* @throws NotFoundException
* if the workspace does not contain the requested element
*/
private WorkflowOperationResult mux(MediaPackage src, WorkflowOperationInstance operation) throws EncoderException, WorkflowOperationException, NotFoundException, MediaPackageException, IOException {
MediaPackage mediaPackage = (MediaPackage) src.clone();
// Read the configuration properties
String sourceFlavorName = StringUtils.trimToNull(operation.getConfiguration("source-flavor"));
String targetTrackTags = StringUtils.trimToNull(operation.getConfiguration("target-tags"));
String targetTrackFlavorName = StringUtils.trimToNull(operation.getConfiguration("target-flavor"));
String muxEncodingProfileName = StringUtils.trimToNull(operation.getConfiguration("mux-encoding-profile"));
String audioVideoEncodingProfileName = StringUtils.trimToNull(operation.getConfiguration("audio-video-encoding-profile"));
String videoOnlyEncodingProfileName = StringUtils.trimToNull(operation.getConfiguration("video-encoding-profile"));
String audioOnlyEncodingProfileName = StringUtils.trimToNull(operation.getConfiguration("audio-encoding-profile"));
String[] targetTags = StringUtils.split(targetTrackTags, ",");
List<String> removeTags = new ArrayList<String>();
List<String> addTags = new ArrayList<String>();
List<String> overrideTags = new ArrayList<String>();
if (targetTags != null) {
for (String tag : targetTags) {
if (tag.startsWith(MINUS)) {
removeTags.add(tag);
} else if (tag.startsWith(PLUS)) {
addTags.add(tag);
} else {
overrideTags.add(tag);
}
}
}
// Make sure the source flavor is properly set
if (sourceFlavorName == null)
throw new IllegalStateException("Source flavor must be specified");
MediaPackageElementFlavor sourceFlavor = MediaPackageElementFlavor.parseFlavor(sourceFlavorName);
// Make sure the target flavor is properly set
if (targetTrackFlavorName == null)
throw new IllegalStateException("Target flavor must be specified");
MediaPackageElementFlavor targetFlavor = MediaPackageElementFlavor.parseFlavor(targetTrackFlavorName);
// Reencode when there is no need for muxing?
boolean rewrite = true;
if (StringUtils.trimToNull(operation.getConfiguration(OPT_REWRITE)) != null) {
rewrite = Boolean.parseBoolean(operation.getConfiguration(OPT_REWRITE));
}
String audioMuxingSourceFlavors = StringUtils.trimToNull(operation.getConfiguration(OPT_AUDIO_MUXING_SOURCE_FLAVORS));
// Select those tracks that have matching flavors
Track[] tracks = mediaPackage.getTracks(sourceFlavor);
Track audioTrack = null;
Track videoTrack = null;
switch(tracks.length) {
case 0:
logger.info("No audio/video tracks with flavor '{}' found to prepare", sourceFlavor);
return createResult(mediaPackage, Action.CONTINUE);
case 1:
videoTrack = tracks[0];
if (!tracks[0].hasAudio() && tracks[0].hasVideo() && (audioMuxingSourceFlavors != null)) {
audioTrack = findAudioTrack(tracks[0], mediaPackage, audioMuxingSourceFlavors);
} else {
audioTrack = tracks[0];
}
break;
case 2:
for (Track track : tracks) {
if (track.hasAudio() && !track.hasVideo()) {
audioTrack = track;
} else if (!track.hasAudio() && track.hasVideo()) {
videoTrack = track;
} else {
throw new WorkflowOperationException("Multiple tracks with competing audio/video streams and flavor '" + sourceFlavor + "' found");
}
}
break;
default:
logger.error("More than two tracks with flavor {} found. No idea what we should be doing", sourceFlavor);
throw new WorkflowOperationException("More than two tracks with flavor '" + sourceFlavor + "' found");
}
Job job = null;
Track composedTrack = null;
// Make sure we have a matching combination
if (audioTrack == null && videoTrack != null) {
if (rewrite) {
logger.info("Encoding video only track {} to work version", videoTrack);
if (videoOnlyEncodingProfileName == null)
videoOnlyEncodingProfileName = PREPARE_VONLY_PROFILE;
// Find the encoding profile to make sure the given profile exists
EncodingProfile profile = composerService.getProfile(videoOnlyEncodingProfileName);
if (profile == null)
throw new IllegalStateException("Encoding profile '" + videoOnlyEncodingProfileName + "' was not found");
composedTrack = prepare(videoTrack, mediaPackage, videoOnlyEncodingProfileName);
} else {
composedTrack = (Track) videoTrack.clone();
composedTrack.setIdentifier(null);
mediaPackage.add(composedTrack);
}
} else if (videoTrack == null && audioTrack != null) {
if (rewrite) {
logger.info("Encoding audio only track {} to work version", audioTrack);
if (audioOnlyEncodingProfileName == null)
audioOnlyEncodingProfileName = PREPARE_AONLY_PROFILE;
// Find the encoding profile to make sure the given profile exists
EncodingProfile profile = composerService.getProfile(audioOnlyEncodingProfileName);
if (profile == null)
throw new IllegalStateException("Encoding profile '" + audioOnlyEncodingProfileName + "' was not found");
composedTrack = prepare(audioTrack, mediaPackage, audioOnlyEncodingProfileName);
} else {
composedTrack = (Track) audioTrack.clone();
composedTrack.setIdentifier(null);
mediaPackage.add(composedTrack);
}
} else if (audioTrack == videoTrack) {
if (rewrite) {
logger.info("Encoding audiovisual track {} to work version", videoTrack);
if (audioVideoEncodingProfileName == null)
audioVideoEncodingProfileName = PREPARE_AV_PROFILE;
// Find the encoding profile to make sure the given profile exists
EncodingProfile profile = composerService.getProfile(audioVideoEncodingProfileName);
if (profile == null)
throw new IllegalStateException("Encoding profile '" + audioVideoEncodingProfileName + "' was not found");
composedTrack = prepare(videoTrack, mediaPackage, audioVideoEncodingProfileName);
} else {
composedTrack = (Track) videoTrack.clone();
composedTrack.setIdentifier(null);
mediaPackage.add(composedTrack);
}
} else {
logger.info("Muxing audio and video only track {} to work version", videoTrack);
if (audioTrack.hasVideo()) {
logger.info("Stripping audio from track {}", audioTrack);
audioTrack = prepare(audioTrack, null, PREPARE_AONLY_PROFILE);
}
if (muxEncodingProfileName == null)
muxEncodingProfileName = MUX_AV_PROFILE;
// Find the encoding profile
EncodingProfile profile = composerService.getProfile(muxEncodingProfileName);
if (profile == null)
throw new IllegalStateException("Encoding profile '" + muxEncodingProfileName + "' was not found");
job = composerService.mux(videoTrack, audioTrack, profile.getIdentifier());
if (!waitForStatus(job).isSuccess()) {
throw new WorkflowOperationException("Muxing video track " + videoTrack + " and audio track " + audioTrack + " failed");
}
composedTrack = (Track) MediaPackageElementParser.getFromXml(job.getPayload());
mediaPackage.add(composedTrack);
String fileName = getFileNameFromElements(videoTrack, composedTrack);
composedTrack.setURI(workspace.moveTo(composedTrack.getURI(), mediaPackage.getIdentifier().toString(), composedTrack.getIdentifier(), fileName));
}
long timeInQueue = 0;
if (job != null) {
// add this receipt's queue time to the total
timeInQueue = job.getQueueTime();
}
// Update the track's flavor
composedTrack.setFlavor(targetFlavor);
logger.debug("Composed track has flavor '{}'", composedTrack.getFlavor());
// Add the target tags
if (overrideTags.size() > 0) {
composedTrack.clearTags();
for (String tag : overrideTags) {
logger.trace("Tagging composed track with '{}'", tag);
composedTrack.addTag(tag);
}
} else {
for (String tag : removeTags) {
logger.trace("Remove tagging '{}' from composed track", tag);
composedTrack.removeTag(tag.substring(MINUS.length()));
}
for (String tag : addTags) {
logger.trace("Add tagging '{}' to composed track", tag);
composedTrack.addTag(tag.substring(PLUS.length()));
}
}
return createResult(mediaPackage, Action.CONTINUE, timeInQueue);
}
use of org.opencastproject.workflow.api.WorkflowOperationException in project opencast by opencast.
the class SegmentPreviewsWorkflowOperationHandler method start.
/**
* {@inheritDoc}
*
* @see org.opencastproject.workflow.api.WorkflowOperationHandler#start(org.opencastproject.workflow.api.WorkflowInstance,
* JobContext)
*/
@Override
public WorkflowOperationResult start(final WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
logger.debug("Running segments preview workflow operation on {}", workflowInstance);
// Check if there is an mpeg-7 catalog containing video segments
MediaPackage src = (MediaPackage) workflowInstance.getMediaPackage().clone();
Catalog[] segmentCatalogs = src.getCatalogs(MediaPackageElements.SEGMENTS);
if (segmentCatalogs.length == 0) {
logger.info("Media package {} does not contain segment information", src);
return createResult(Action.CONTINUE);
}
// Create the images
try {
return createPreviews(src, workflowInstance.getCurrentOperation());
} catch (Exception e) {
throw new WorkflowOperationException(e);
}
}
Aggregations