Search in sources :

Example 6 with EncodingProfile

use of org.opencastproject.composer.api.EncodingProfile 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 7 with EncodingProfile

use of org.opencastproject.composer.api.EncodingProfile 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 8 with EncodingProfile

use of org.opencastproject.composer.api.EncodingProfile 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 9 with EncodingProfile

use of org.opencastproject.composer.api.EncodingProfile 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)

Example 10 with EncodingProfile

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

the class EncodingProfileScanner method install.

/**
 * {@inheritDoc}
 *
 * @see org.apache.felix.fileinstall.ArtifactInstaller#install(java.io.File)
 */
@Override
public void install(File artifact) throws Exception {
    logger.info("Registering encoding profiles from {}", artifact);
    try {
        Map<String, EncodingProfile> profileMap = loadFromProperties(artifact);
        for (Map.Entry<String, EncodingProfile> entry : profileMap.entrySet()) {
            logger.info("Installed profile {}", entry.getValue().getIdentifier());
            profiles.put(entry.getKey(), entry.getValue());
        }
        sumInstalledFiles++;
    } catch (Exception e) {
        logger.error("Encoding profiles could not be read from {}: {}", artifact, e.getMessage());
    }
    // Determine the number of available profiles
    String[] filesInDirectory = artifact.getParentFile().list(new FilenameFilter() {

        public boolean accept(File arg0, String name) {
            return name.endsWith(".properties");
        }
    });
    // Once all profiles have been loaded, announce readiness
    if (filesInDirectory.length == sumInstalledFiles) {
        Dictionary<String, String> properties = new Hashtable<String, String>();
        properties.put(ARTIFACT, "encodingprofile");
        logger.debug("Indicating readiness of encoding profiles");
        bundleCtx.registerService(ReadinessIndicator.class.getName(), new ReadinessIndicator(), properties);
        logger.info("All {} encoding profiles installed", filesInDirectory.length);
    } else {
        logger.debug("{} of {} encoding profiles installed", sumInstalledFiles, filesInDirectory.length);
    }
}
Also used : FilenameFilter(java.io.FilenameFilter) ReadinessIndicator(org.opencastproject.util.ReadinessIndicator) Hashtable(java.util.Hashtable) EncodingProfile(org.opencastproject.composer.api.EncodingProfile) HashMap(java.util.HashMap) Map(java.util.Map) File(java.io.File) ConfigurationException(org.opencastproject.util.ConfigurationException) IOException(java.io.IOException)

Aggregations

EncodingProfile (org.opencastproject.composer.api.EncodingProfile)38 EncoderException (org.opencastproject.composer.api.EncoderException)16 Track (org.opencastproject.mediapackage.Track)15 HashMap (java.util.HashMap)14 Job (org.opencastproject.job.api.Job)13 ArrayList (java.util.ArrayList)12 Test (org.junit.Test)12 Map (java.util.Map)10 ServiceRegistryException (org.opencastproject.serviceregistry.api.ServiceRegistryException)10 File (java.io.File)9 URI (java.net.URI)8 IOException (java.io.IOException)7 WorkflowOperationException (org.opencastproject.workflow.api.WorkflowOperationException)7 Attachment (org.opencastproject.mediapackage.Attachment)6 MediaPackage (org.opencastproject.mediapackage.MediaPackage)6 MediaPackageElementFlavor (org.opencastproject.mediapackage.MediaPackageElementFlavor)6 MediaPackageException (org.opencastproject.mediapackage.MediaPackageException)6 NotFoundException (org.opencastproject.util.NotFoundException)6 LinkedList (java.util.LinkedList)5 WorkflowOperationResult (org.opencastproject.workflow.api.WorkflowOperationResult)5