Search in sources :

Example 1 with EncoderException

use of org.opencastproject.composer.api.EncoderException in project opencast by opencast.

the class ComposerServiceImpl method concat.

@Override
public Job concat(String profileId, Dimension outputDimension, float outputFrameRate, Track... tracks) throws EncoderException, MediaPackageException {
    ArrayList<String> arguments = new ArrayList<String>();
    arguments.add(0, profileId);
    if (outputDimension != null) {
        arguments.add(1, Serializer.json(outputDimension).toJson());
    } else {
        arguments.add(1, "");
    }
    arguments.add(2, String.format(Locale.US, "%f", outputFrameRate));
    for (int i = 0; i < tracks.length; i++) {
        arguments.add(i + 3, MediaPackageElementParser.getAsXml(tracks[i]));
    }
    try {
        final EncodingProfile profile = profileScanner.getProfile(profileId);
        return serviceRegistry.createJob(JOB_TYPE, Operation.Concat.toString(), arguments, profile.getJobLoad());
    } catch (ServiceRegistryException e) {
        throw new EncoderException("Unable to create concat job", e);
    }
}
Also used : EncoderException(org.opencastproject.composer.api.EncoderException) ArrayList(java.util.ArrayList) EncodingProfile(org.opencastproject.composer.api.EncodingProfile) ServiceRegistryException(org.opencastproject.serviceregistry.api.ServiceRegistryException)

Example 2 with EncoderException

use of org.opencastproject.composer.api.EncoderException in project opencast by opencast.

the class ComposerServiceImpl method encode.

/**
 * Encodes audio and video track to a file. If both an audio and a video track are given, they are muxed together into
 * one movie container.
 *
 * @param tracks
 *          tracks to use for processing
 * @param profileId
 *          the encoding profile
 * @param properties
 *          encoding properties
 * @return the encoded track or none if the operation does not return a track. This may happen for example when doing
 *         two pass encodings where the first pass only creates metadata for the second one
 * @throws EncoderException
 *           if encoding fails
 */
private Option<Track> encode(final Job job, Map<String, Track> tracks, String profileId) throws EncoderException, MediaPackageException {
    final String targetTrackId = idBuilder.createNew().toString();
    Map<String, File> files = new HashMap<>();
    // Get the tracks and make sure they exist
    for (Entry<String, Track> track : tracks.entrySet()) {
        files.put(track.getKey(), loadTrackIntoWorkspace(job, track.getKey(), track.getValue()));
    }
    // Get the encoding profile
    final EncodingProfile profile = getProfile(job, profileId);
    List<String> trackMsg = new LinkedList<>();
    for (Entry<String, Track> track : tracks.entrySet()) {
        trackMsg.add(String.format("%s: %s", track.getKey(), track.getValue().getIdentifier()));
    }
    logger.info("Encoding {} into {} using profile {}", StringUtils.join(trackMsg, ", "), targetTrackId, profileId);
    // Do the work
    final EncoderEngine encoder = getEncoderEngine();
    List<File> output;
    try {
        output = encoder.process(files, profile, null);
    } catch (EncoderException e) {
        Map<String, String> params = new HashMap<>();
        for (Entry<String, Track> track : tracks.entrySet()) {
            params.put(track.getKey(), track.getValue().getIdentifier());
        }
        params.put("profile", profile.getIdentifier());
        params.put("properties", "EMPTY");
        incident().recordFailure(job, ENCODING_FAILED, e, params, detailsFor(e, encoder));
        throw e;
    } finally {
        activeEncoder.remove(encoder);
    }
    // We expect zero or one file as output
    if (output.size() == 0) {
        return none();
    } else 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), "encoded file");
    // Have the encoded 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);
}
Also used : HashMap(java.util.HashMap) EncodingProfile(org.opencastproject.composer.api.EncodingProfile) URI(java.net.URI) LinkedList(java.util.LinkedList) EncoderException(org.opencastproject.composer.api.EncoderException) Entry(java.util.Map.Entry) Job(org.opencastproject.job.api.Job) File(java.io.File) Map(java.util.Map) HashMap(java.util.HashMap) Track(org.opencastproject.mediapackage.Track)

Example 3 with EncoderException

use of org.opencastproject.composer.api.EncoderException in project opencast by opencast.

the class ComposerServiceImpl method convertImage.

/**
 * Converts an image from <code>sourceImage</code> to a new format.
 *
 * @param job
 *          the associated job
 * @param sourceImage
 *          the source image
 * @param profileId
 *          the identifer of the encoding profile to use
 * @return the image as an attachment or none if the operation does not return an image. This may happen for example
 *         when doing two pass encodings where the first pass only creates metadata for the second one
 * @throws EncoderException
 *           if converting the image fails
 */
private Option<Attachment> convertImage(Job job, Attachment sourceImage, String profileId) throws EncoderException, MediaPackageException {
    logger.info("Converting {}", sourceImage);
    // 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 imageFile;
    try {
        imageFile = workspace.get(sourceImage.getURI());
    } catch (NotFoundException e) {
        incident().recordFailure(job, WORKSPACE_GET_NOT_FOUND, e, getWorkspaceMediapackageParams("source image", sourceImage), NO_DETAILS);
        throw new EncoderException("Requested video track " + sourceImage + " was not found", e);
    } catch (IOException e) {
        incident().recordFailure(job, WORKSPACE_GET_IO_EXCEPTION, e, getWorkspaceMediapackageParams("source image", sourceImage), NO_DETAILS);
        throw new EncoderException("Error accessing video track " + sourceImage, e);
    }
    // Do the work
    File output;
    try {
        output = encoderEngine.encode(imageFile, profile, null);
    } catch (EncoderException e) {
        Map<String, String> params = new HashMap<>();
        params.put("image", sourceImage.getURI().toString());
        params.put("profile", profile.getIdentifier());
        incident().recordFailure(job, CONVERT_IMAGE_FAILED, e, params, detailsFor(e, encoderEngine));
        throw e;
    } finally {
        activeEncoder.remove(encoderEngine);
    }
    // encoding did not return a file
    if (!output.exists() || output.length() == 0)
        return none();
    // Put the file in the workspace
    URI workspaceURI = putToCollection(job, output, "converted image file");
    MediaPackageElementBuilder builder = MediaPackageElementBuilderFactory.newInstance().newElementBuilder();
    Attachment attachment = (Attachment) builder.elementFromURI(workspaceURI, Attachment.TYPE, null);
    return some(attachment);
}
Also used : EncoderException(org.opencastproject.composer.api.EncoderException) MediaPackageElementBuilder(org.opencastproject.mediapackage.MediaPackageElementBuilder) EncodingProfile(org.opencastproject.composer.api.EncodingProfile) NotFoundException(org.opencastproject.util.NotFoundException) Attachment(org.opencastproject.mediapackage.Attachment) IOException(java.io.IOException) File(java.io.File) Map(java.util.Map) HashMap(java.util.HashMap) URI(java.net.URI)

Example 4 with EncoderException

use of org.opencastproject.composer.api.EncoderException in project opencast by opencast.

the class ComposerServiceImpl method image.

/**
 * Extracts an image from <code>sourceTrack</code> at the given point in time.
 *
 * @param job
 *          the associated job
 * @param sourceTrack
 *          the source track
 * @param profileId
 *          the identifier of the encoding profile to use
 * @param times
 *          (one or more) times in seconds
 * @return the images as an attachment element list
 * @throws EncoderException
 *           if extracting the image fails
 */
protected List<Attachment> image(Job job, Track sourceTrack, String profileId, double... times) throws EncoderException, MediaPackageException {
    if (sourceTrack == null)
        throw new EncoderException("SourceTrack cannot be null");
    validateVideoStream(job, sourceTrack);
    // The time should not be outside of the track's duration
    for (double time : times) {
        if (sourceTrack.getDuration() == null) {
            Map<String, String> params = new HashMap<>();
            params.put("track-id", sourceTrack.getIdentifier());
            params.put("track-url", sourceTrack.getURI().toString());
            incident().recordFailure(job, IMAGE_EXTRACTION_UNKNOWN_DURATION, params);
            throw new EncoderException("Unable to extract an image from a track with unknown duration");
        }
        if (time < 0 || time * 1000 > sourceTrack.getDuration()) {
            Map<String, String> params = new HashMap<>();
            params.put("track-id", sourceTrack.getIdentifier());
            params.put("track-url", sourceTrack.getURI().toString());
            params.put("track-duration", sourceTrack.getDuration().toString());
            params.put("time", Double.toString(time));
            incident().recordFailure(job, IMAGE_EXTRACTION_TIME_OUTSIDE_DURATION, params);
            throw new EncoderException("Can not extract an image at time " + time + " from a track with duration " + sourceTrack.getDuration());
        }
    }
    return extractImages(job, sourceTrack, profileId, null, times);
}
Also used : EncoderException(org.opencastproject.composer.api.EncoderException) HashMap(java.util.HashMap)

Example 5 with EncoderException

use of org.opencastproject.composer.api.EncoderException in project opencast by opencast.

the class ComposerServiceImpl method concat.

private Option<Track> concat(Job job, List<Track> tracks, String profileId, Dimension outputDimension, float outputFrameRate) throws EncoderException, MediaPackageException {
    if (tracks.size() < 2) {
        Map<String, String> params = new HashMap<>();
        params.put("tracks-size", Integer.toString(tracks.size()));
        params.put("tracks", StringUtils.join(tracks, ","));
        incident().recordFailure(job, CONCAT_LESS_TRACKS, params);
        throw new EncoderException("The track parameter must at least have two tracks present");
    }
    boolean onlyAudio = true;
    for (Track t : tracks) {
        if (t.hasVideo()) {
            onlyAudio = false;
            break;
        }
    }
    if (!onlyAudio && outputDimension == null) {
        Map<String, String> params = new HashMap<>();
        params.put("tracks", StringUtils.join(tracks, ","));
        incident().recordFailure(job, CONCAT_NO_DIMENSION, params);
        throw new EncoderException("The output dimension id parameter must not be null when concatenating video");
    }
    final String targetTrackId = idBuilder.createNew().toString();
    // Get the tracks and make sure they exist
    List<File> trackFiles = new ArrayList<>();
    int i = 0;
    for (Track track : tracks) {
        if (!track.hasAudio() && !track.hasVideo()) {
            Map<String, String> params = new HashMap<>();
            params.put("track-id", track.getIdentifier());
            params.put("track-url", track.getURI().toString());
            incident().recordFailure(job, NO_STREAMS, params);
            throw new EncoderException("Track has no audio or video stream available: " + track);
        }
        trackFiles.add(i++, loadTrackIntoWorkspace(job, "concat", track));
    }
    // Create the engine
    final EncoderEngine encoderEngine = getEncoderEngine();
    if (onlyAudio) {
        logger.info("Concatenating audio tracks {} into {}", trackFiles, targetTrackId);
    } else {
        logger.info("Concatenating video tracks {} into {}", trackFiles, targetTrackId);
    }
    // Get the encoding profile
    EncodingProfile profile = getProfile(job, profileId);
    // Creating video filter command for concat
    final String concatCommand = buildConcatCommand(onlyAudio, outputDimension, outputFrameRate, trackFiles, tracks);
    Map<String, String> properties = new HashMap<>();
    properties.put(EncoderEngine.CMD_SUFFIX + ".concatCommand", concatCommand);
    File output;
    try {
        output = encoderEngine.encode(trackFiles.get(0), profile, properties);
    } catch (EncoderException e) {
        Map<String, String> params = new HashMap<>();
        List<String> trackList = new ArrayList<>();
        for (Track t : tracks) {
            trackList.add(t.getURI().toString());
        }
        params.put("tracks", StringUtils.join(trackList, ","));
        params.put("profile", profile.getIdentifier());
        params.put("properties", properties.toString());
        incident().recordFailure(job, CONCAT_FAILED, e, params, detailsFor(e, encoderEngine));
        throw e;
    } finally {
        activeEncoder.remove(encoderEngine);
    }
    // concat did not return a file
    if (!output.exists() || output.length() == 0)
        return none();
    // Put the file in the workspace
    URI workspaceURI = putToCollection(job, output, "concatenated file");
    // Have the concat 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);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) EncodingProfile(org.opencastproject.composer.api.EncodingProfile) URI(java.net.URI) EncoderException(org.opencastproject.composer.api.EncoderException) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) Job(org.opencastproject.job.api.Job) File(java.io.File) Map(java.util.Map) HashMap(java.util.HashMap) Track(org.opencastproject.mediapackage.Track)

Aggregations

EncoderException (org.opencastproject.composer.api.EncoderException)41 Job (org.opencastproject.job.api.Job)26 IOException (java.io.IOException)19 ArrayList (java.util.ArrayList)19 MediaPackageException (org.opencastproject.mediapackage.MediaPackageException)19 EncodingProfile (org.opencastproject.composer.api.EncodingProfile)16 URI (java.net.URI)12 HashMap (java.util.HashMap)12 Track (org.opencastproject.mediapackage.Track)12 File (java.io.File)11 NotFoundException (org.opencastproject.util.NotFoundException)11 HttpResponse (org.apache.http.HttpResponse)10 UrlEncodedFormEntity (org.apache.http.client.entity.UrlEncodedFormEntity)10 HttpPost (org.apache.http.client.methods.HttpPost)10 BasicNameValuePair (org.apache.http.message.BasicNameValuePair)10 ServiceRegistryException (org.opencastproject.serviceregistry.api.ServiceRegistryException)10 Map (java.util.Map)9 MediaPackageElement (org.opencastproject.mediapackage.MediaPackageElement)7 LinkedList (java.util.LinkedList)6 POST (javax.ws.rs.POST)6