Search in sources :

Example 6 with EncoderException

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

the class EncoderEngine method extract.

/**
 * Extract several images from a video file.
 *
 * @param mediaSource
 *          File to extract images from
 * @param format
 *          Encoding profile to use for extraction
 * @param properties
 * @param times
 *          Times at which to extract the images
 * @return  List of image files
 * @throws EncoderException Something went wrong during image extraction
 */
List<File> extract(File mediaSource, EncodingProfile format, Map<String, String> properties, double... times) throws EncoderException {
    List<File> extractedImages = new LinkedList<>();
    try {
        // Extract one image if no times are specified
        if (times.length == 0) {
            extractedImages.add(encode(mediaSource, format, properties));
        }
        for (double time : times) {
            Map<String, String> params = new HashMap<>();
            if (properties != null) {
                params.putAll(properties);
            }
            DecimalFormatSymbols ffmpegFormat = new DecimalFormatSymbols();
            ffmpegFormat.setDecimalSeparator('.');
            DecimalFormat df = new DecimalFormat("0.00000", ffmpegFormat);
            params.put("time", df.format(time));
            extractedImages.add(encode(mediaSource, format, params));
        }
    } catch (Exception e) {
        cleanup(extractedImages);
        if (e instanceof EncoderException) {
            throw (EncoderException) e;
        } else {
            throw new EncoderException("Image extraction failed", e);
        }
    }
    return extractedImages;
}
Also used : EncoderException(org.opencastproject.composer.api.EncoderException) DecimalFormatSymbols(java.text.DecimalFormatSymbols) HashMap(java.util.HashMap) DecimalFormat(java.text.DecimalFormat) File(java.io.File) LinkedList(java.util.LinkedList) EncoderException(org.opencastproject.composer.api.EncoderException)

Example 7 with EncoderException

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

the class EncoderEngine method buildCommand.

/**
 * Creates the command that is sent to the commandline encoder.
 *
 * @return the commandline
 * @throws EncoderException
 *           in case of any error
 */
private List<String> buildCommand(final EncodingProfile profile, final Map<String, String> argumentReplacements) throws EncoderException {
    List<String> command = new ArrayList<>();
    command.add(binary);
    command.add("-nostats");
    String commandline = profile.getExtension(CMD_SUFFIX);
    // ffmpeg.command.concatCmd = -i ...
    for (String key : argumentReplacements.keySet()) {
        if (key.startsWith(CMD_SUFFIX + '.')) {
            final String shortKey = key.substring(CMD_SUFFIX.length() + 1);
            commandline = commandline.replace("#{" + shortKey + "}", argumentReplacements.get(key));
        }
    }
    String[] arguments;
    try {
        arguments = CommandLineUtils.translateCommandline(commandline);
    } catch (Exception e) {
        throw new EncoderException("Could not parse encoding profile command line", e);
    }
    for (String arg : arguments) {
        String result = processParameters(arg, argumentReplacements);
        if (StringUtils.isNotBlank(result)) {
            command.add(result);
        }
    }
    return command;
}
Also used : EncoderException(org.opencastproject.composer.api.EncoderException) ArrayList(java.util.ArrayList) EncoderException(org.opencastproject.composer.api.EncoderException)

Example 8 with EncoderException

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

the class EncoderEngine method process.

/**
 * Executes the command line encoder with the given set of files and properties and using the provided encoding
 * profile.
 *
 * @param source
 *          the source files for encoding
 * @param profile
 *          the profile identifier
 * @param properties
 *          the encoding properties to be interpreted by the actual encoder implementation
 * @return the processed file
 * @throws EncoderException
 *           if processing fails
 */
List<File> process(Map<String, File> source, EncodingProfile profile, Map<String, String> properties) throws EncoderException {
    // Fist, update the parameters
    Map<String, String> params = new HashMap<>();
    if (properties != null)
        params.putAll(properties);
    // build command
    if (source.isEmpty()) {
        throw new IllegalArgumentException("At least one track must be specified.");
    }
    // Set encoding parameters
    for (Map.Entry<String, File> f : source.entrySet()) {
        final String input = FilenameUtils.normalize(f.getValue().getAbsolutePath());
        final String pre = "in." + f.getKey();
        params.put(pre + ".path", input);
        params.put(pre + ".name", FilenameUtils.getBaseName(input));
        params.put(pre + ".suffix", FilenameUtils.getExtension(input));
        params.put(pre + ".filename", FilenameUtils.getName(input));
        params.put(pre + ".mimetype", MimetypesFileTypeMap.getDefaultFileTypeMap().getContentType(input));
    }
    final File parentFile = source.getOrDefault("video", source.get("audio"));
    final String outDir = parentFile.getAbsoluteFile().getParent();
    final String outFileName = FilenameUtils.getBaseName(parentFile.getName()) + "_" + UUID.randomUUID().toString();
    params.put("out.dir", outDir);
    params.put("out.name", outFileName);
    if (profile.getSuffix() != null) {
        final String outSuffix = processParameters(profile.getSuffix(), params);
        params.put("out.suffix", outSuffix);
    }
    for (String tag : profile.getTags()) {
        final String suffix = processParameters(profile.getSuffix(tag), params);
        params.put("out.suffix." + tag, suffix);
    }
    // create encoder process.
    final List<String> command = buildCommand(profile, params);
    logger.info("Executing encoding command: {}", command);
    List<File> outFiles = new ArrayList<>();
    BufferedReader in = null;
    Process encoderProcess = null;
    try {
        ProcessBuilder processBuilder = new ProcessBuilder(command);
        processBuilder.redirectErrorStream(REDIRECT_ERROR_STREAM);
        encoderProcess = processBuilder.start();
        processes.add(encoderProcess);
        // tell encoder listeners about output
        in = new BufferedReader(new InputStreamReader(encoderProcess.getInputStream()));
        String line;
        while ((line = in.readLine()) != null) {
            handleEncoderOutput(outFiles, line);
        }
        // wait until the task is finished
        int exitCode = encoderProcess.waitFor();
        if (exitCode != 0) {
            throw new EncoderException("Encoder exited abnormally with status " + exitCode);
        }
        logger.info("Tracks {} successfully encoded using profile '{}'", source, profile.getIdentifier());
        return outFiles;
    } catch (Exception e) {
        logger.warn("Error while encoding {}  using profile '{}'", source, profile.getIdentifier(), e);
        // Ensure temporary data are removed
        for (File outFile : outFiles) {
            if (FileUtils.deleteQuietly(outFile)) {
                logger.debug("Removed output file of failed encoding process: {}", outFile);
            }
        }
        throw new EncoderException(e);
    } finally {
        IoSupport.closeQuietly(in);
        IoSupport.closeQuietly(encoderProcess);
    }
}
Also used : InputStreamReader(java.io.InputStreamReader) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) EncoderException(org.opencastproject.composer.api.EncoderException) EncoderException(org.opencastproject.composer.api.EncoderException) BufferedReader(java.io.BufferedReader) HashMap(java.util.HashMap) MimetypesFileTypeMap(javax.activation.MimetypesFileTypeMap) Map(java.util.Map) File(java.io.File)

Example 9 with EncoderException

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

the class ComposerRestService method image.

/**
 * Encodes a track in a media package.
 *
 * @param sourceTrackXml
 *          The source track
 * @param profileId
 *          The profile to use in encoding this track
 * @param times
 *          one or more times in seconds separated by comma
 * @return A {@link Response} with the resulting track in the response body
 * @throws Exception
 */
@POST
@Path("image")
@Produces(MediaType.TEXT_XML)
@RestQuery(name = "image", description = "Starts an image extraction process, based on the specified encoding profile ID and the source track", restParameters = { @RestParameter(description = "The track containing the video stream", isRequired = true, name = "sourceTrack", type = Type.TEXT, defaultValue = "${this.videoTrackDefault}"), @RestParameter(description = "The encoding profile to use", isRequired = true, name = "profileId", type = Type.STRING, defaultValue = "player-preview.http"), @RestParameter(description = "The number of seconds (many numbers can be specified, separated by semicolon) into the video to extract the image", isRequired = false, name = "time", type = Type.STRING), @RestParameter(description = "An optional set of key=value\\n properties", isRequired = false, name = "properties", type = TEXT) }, reponses = { @RestResponse(description = "Results in an xml document containing the image attachment", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "If required parameters aren't set or if sourceTrack isn't from the type Track", responseCode = HttpServletResponse.SC_BAD_REQUEST) }, returnDescription = "The image extraction job")
public Response image(@FormParam("sourceTrack") String sourceTrackXml, @FormParam("profileId") String profileId, @FormParam("time") String times, @FormParam("properties") LocalHashMap localMap) throws Exception {
    // Ensure that the POST parameters are present
    if (StringUtils.isBlank(sourceTrackXml) || StringUtils.isBlank(profileId))
        return Response.status(Response.Status.BAD_REQUEST).entity("sourceTrack and profileId must not be null").build();
    // Deserialize the source track
    MediaPackageElement sourceTrack = MediaPackageElementParser.getFromXml(sourceTrackXml);
    if (!Track.TYPE.equals(sourceTrack.getElementType()))
        return Response.status(Response.Status.BAD_REQUEST).entity("sourceTrack element must be of type track").build();
    boolean timeBased = false;
    double[] timeArray = null;
    if (StringUtils.isNotBlank(times)) {
        // parse time codes
        try {
            timeArray = parseTimeArray(times);
        } catch (Exception e) {
            return Response.status(Response.Status.BAD_REQUEST).entity("could not parse times: invalid format").build();
        }
        timeBased = true;
    } else if (localMap == null) {
        return Response.status(Response.Status.BAD_REQUEST).build();
    }
    try {
        // Asynchronously encode the specified tracks
        Job job;
        if (timeBased) {
            job = composerService.image((Track) sourceTrack, profileId, timeArray);
        } else {
            job = composerService.image((Track) sourceTrack, profileId, localMap.getMap());
        }
        return Response.ok().entity(new JaxbJob(job)).build();
    } catch (EncoderException e) {
        logger.warn("Unable to extract image(s): " + e.getMessage());
        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
    }
}
Also used : EncoderException(org.opencastproject.composer.api.EncoderException) MediaPackageElement(org.opencastproject.mediapackage.MediaPackageElement) JaxbJob(org.opencastproject.job.api.JaxbJob) JaxbJob(org.opencastproject.job.api.JaxbJob) Job(org.opencastproject.job.api.Job) NotFoundException(org.opencastproject.util.NotFoundException) EncoderException(org.opencastproject.composer.api.EncoderException) Track(org.opencastproject.mediapackage.Track) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) RestQuery(org.opencastproject.util.doc.rest.RestQuery)

Example 10 with EncoderException

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

the class ComposerRestService method mux.

/**
 * Encodes a track.
 *
 * @param audioSourceTrackXml
 *          The audio source track
 * @param videoSourceTrackXml
 *          The video source track
 * @param profileId
 *          The profile to use in encoding this track
 * @return A response containing the job for this encoding job in the response body.
 * @throws Exception
 */
@POST
@Path("mux")
@Produces(MediaType.TEXT_XML)
@RestQuery(name = "mux", description = "Starts an encoding process, which will mux the two tracks using the given encoding profile", restParameters = { @RestParameter(description = "The track containing the audio stream", isRequired = true, name = "sourceAudioTrack", type = Type.TEXT, defaultValue = "${this.audioTrackDefault}"), @RestParameter(description = "The track containing the video stream", isRequired = true, name = "sourceVideoTrack", type = Type.TEXT, defaultValue = "${this.videoTrackDefault}"), @RestParameter(description = "The encoding profile to use", isRequired = true, name = "profileId", type = Type.STRING, defaultValue = "mp4-medium.http") }, reponses = { @RestResponse(description = "Results in an xml document containing the job for the encoding task", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "If required parameters aren't set or if the source tracks aren't from the type Track", responseCode = HttpServletResponse.SC_BAD_REQUEST) }, returnDescription = "")
public Response mux(@FormParam("audioSourceTrack") String audioSourceTrackXml, @FormParam("videoSourceTrack") String videoSourceTrackXml, @FormParam("profileId") String profileId) throws Exception {
    // Ensure that the POST parameters are present
    if (StringUtils.isBlank(audioSourceTrackXml) || StringUtils.isBlank(videoSourceTrackXml) || StringUtils.isBlank(profileId)) {
        return Response.status(Response.Status.BAD_REQUEST).entity("audioSourceTrack, videoSourceTrack, and profileId must not be null").build();
    }
    // Deserialize the audio track
    MediaPackageElement audioSourceTrack = MediaPackageElementParser.getFromXml(audioSourceTrackXml);
    if (!Track.TYPE.equals(audioSourceTrack.getElementType()))
        return Response.status(Response.Status.BAD_REQUEST).entity("audioSourceTrack must be of type track").build();
    // Deserialize the video track
    MediaPackageElement videoSourceTrack = MediaPackageElementParser.getFromXml(videoSourceTrackXml);
    if (!Track.TYPE.equals(videoSourceTrack.getElementType()))
        return Response.status(Response.Status.BAD_REQUEST).entity("videoSourceTrack must be of type track").build();
    try {
        // Asynchronously encode the specified tracks
        Job job = composerService.mux((Track) videoSourceTrack, (Track) audioSourceTrack, profileId);
        return Response.ok().entity(new JaxbJob(job)).build();
    } catch (EncoderException e) {
        logger.warn("Unable to mux tracks: " + e.getMessage());
        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
    }
}
Also used : EncoderException(org.opencastproject.composer.api.EncoderException) MediaPackageElement(org.opencastproject.mediapackage.MediaPackageElement) JaxbJob(org.opencastproject.job.api.JaxbJob) JaxbJob(org.opencastproject.job.api.JaxbJob) Job(org.opencastproject.job.api.Job) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) RestQuery(org.opencastproject.util.doc.rest.RestQuery)

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