Recherche avancée

Médias (91)

Autres articles (44)

  • (Dés)Activation de fonctionnalités (plugins)

    18 février 2011, par

    Pour gérer l’ajout et la suppression de fonctionnalités supplémentaires (ou plugins), MediaSPIP utilise à partir de la version 0.2 SVP.
    SVP permet l’activation facile de plugins depuis l’espace de configuration de MediaSPIP.
    Pour y accéder, il suffit de se rendre dans l’espace de configuration puis de se rendre sur la page "Gestion des plugins".
    MediaSPIP est fourni par défaut avec l’ensemble des plugins dits "compatibles", ils ont été testés et intégrés afin de fonctionner parfaitement avec chaque (...)

  • Les autorisations surchargées par les plugins

    27 avril 2010, par

    Mediaspip core
    autoriser_auteur_modifier() afin que les visiteurs soient capables de modifier leurs informations sur la page d’auteurs

  • Librairies et binaires spécifiques au traitement vidéo et sonore

    31 janvier 2010, par

    Les logiciels et librairies suivantes sont utilisées par SPIPmotion d’une manière ou d’une autre.
    Binaires obligatoires FFMpeg : encodeur principal, permet de transcoder presque tous les types de fichiers vidéo et sonores dans les formats lisibles sur Internet. CF ce tutoriel pour son installation ; Oggz-tools : outils d’inspection de fichiers ogg ; Mediainfo : récupération d’informations depuis la plupart des formats vidéos et sonores ;
    Binaires complémentaires et facultatifs flvtool2 : (...)

Sur d’autres sites (9622)

  • DASH package (mpd) I made freezes after raising the onratechange event

    7 mars 2016, par Nick Birke

    I am trying to created an adaptive stream from an mp4 file. I have a decent amount of experience at doing streaming, and have successfully implemented smooth streaming via Silverlight. We want a solution for everything that works in HTML5. I am pursuing DASH. So here are the steps I take...

    1. Resample the mp4 to different sizes using ffmpeg.
    2. Ensure the files are properly fragmented using Bento4s mp4Fragment utility.
    3. Create the DASH mpd file and associated segments using Bento4s mp4dash utility.

    I have done a lot of work to learn each of these utilities and create a process that gets to output that I think will work. To create reliable DASH artifacts. But it seems I am doing something wrong. Here are examples of command lines I run.

    For step one I create three different files... for three different rates and sizes... (these may not be the exact command lines, they are from old notes... but the parameter values are the ones I am using for sure)

    ffmpeg -y -i C:\_SIMULATED_SHARE_C\ff\big_buck_bunny.mp4 -c:v libx264 -x264opts keyint=24:min-keyint=24:no-scenecut -b:v 1500k -maxrate 1500k -bufsize 1000k -vf "scale=-1:720" C:\_SIMULATED_SHARE_C\ff\output\outputfile720.mp4

    ffmpeg -y -i C:\_SIMULATED_SHARE_C\ff\big_buck_bunny.mp4 -c:v libx264 -x264opts keyint=24:min-keyint=24:no-scenecut -b:v 800k -maxrate 800k -bufsize 500k -vf "scale=-1:540" C:\_SIMULATED_SHARE_C\ff\output\outputfile540.mp4

    ffmpeg -y -i C:\_SIMULATED_SHARE_C\ff\big_buck_bunny.mp4 -c:v libx264 -x264opts keyint=24:min-keyint=24:no-scenecut -b:v 400k -maxrate 400k -bufsize 400k -vf "scale=-1:360" C:\_SIMULATED_SHARE_C\ff\output\outputfile360.mp4

    So that gives you the three files that need to be fragmented. So I fragment them using the mp4fragment utility from Bento4. That command line is simple so I will not offer an example.

    The I use Bento4s mp4dash to create the dash. Something like this...

    "E:\\_INSTALL\\Bento4\\Bento4-SDK-1-4-3-607.x86-microsoft-win32-vs2010\\Bento4-SDK-1-4-3-607.x86-microsoft-win32-vs2010\\bin\\mp4dash.exe --mpd-name=\"\\\\d9fqt52\\_SIMULATED_SHARE_C\\ff\\output\\dash\\something.mpd\" -f -o \"\\\\d9fqt52\\_SIMULATED_SHARE_C\\ff\\output\\dash\" \"\\\\d9fqt52\\_SIMULATED_SHARE_C\\ff\\output\\bunny360f.mp4\" \"\\\\d9fqt52\\_SIMULATED_SHARE_C\\ff\\output\\bunny540f.mp4\" \"\\\\d9fqt52\\_SIMULATED_SHARE_C\\ff\\output\\bunny720f.mp4\" "

    This runs ok. And creates the mpd file, an audio folder with segment files, an a video folder with 3 folders each with the segment files.

    I am able to configure IIS to play the mpd ok. As well as the segement files. The video plays fine... and then it stops. It freezes between 50 and 60 seconds. Right before it freezes I can confirm that the onratechange event of the HTML5 video tag is raised. This is an event that is raised with the rate of play is changed. I do nothing to change this it just happens.

    The actual video in question is about 1hr long. Also I am using the dash.js library as a player.

    If you can identify any components or specifics I should change please let me know !

    UPDATE ON MAR 7, 2016

    As requested here is the MPD content...

    <?xml version="1.0" ?>
    <mpd mediapresentationduration="PT51M51.909S" minbuffertime="PT0.80S" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="static" xmlns="urn:mpeg:dash:schema:mpd:2011">
     
     <period>
       
       <adaptationset lang="en" mimetype="audio/mp4" segmentalignment="true" startwithsap="1">
         <segmenttemplate duration="801" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4f" startnumber="1" timescale="1000"></segmenttemplate>
         <representation audiosamplingrate="48000" bandwidth="132491" codecs="mp4a.40.2">
           <audiochannelconfiguration schemeiduri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"></audiochannelconfiguration>
         </representation>
       </adaptationset>
       
       <adaptationset maxheight="720" maxwidth="1280" mimetype="video/mp4" minheight="540" minwidth="640" segmentalignment="true" startwithsap="1">
         <segmenttemplate duration="801" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4f" startnumber="1" timescale="1000"></segmenttemplate>
         <representation bandwidth="785536" codecs="avc1.64001F" framerate="30000/1001" height="540" scantype="progressive" width="960"></representation>
         <representation bandwidth="403537" codecs="avc1.64001E" framerate="30000/1001" height="360" scantype="progressive" width="640"></representation>
         <representation bandwidth="1496514" codecs="avc1.64001F" framerate="30000/1001" height="720" scantype="progressive" width="1280"></representation>
       </adaptationset>
     </period>
    </mpd>

    UPDATE ON MAR 7, 2016

    Here is the console output for two different videos that just stop for some unknown reason between 50 and 60s

    ///ABS VIDEO

    58393][rulesController] [RULES]: playbackTimeRule [Fragment:download,82,MediaSegment,0video] Default
    dash.all.js:11 [58395][rulesController] [RULES]: sameTimeRequestRule [Fragment:download,82,MediaSegment,0,video] Default
    dash.all.js:11 [58401][indexHandler][audio] Getting the request for time: 82.082
    dash.all.js:11 [58403][indexHandler][audio] Index for time 82.082 is 81
    dash.all.js:11 [58405][indexHandler][audio] SegmentTemplate: 81.08099999999999 / 1361.235
    dash.all.js:11 [58406][indexHandler][audio] SegmentTemplate: 82.082 / 1361.235
    dash.all.js:11 [58407][rulesController] [RULES]: playbackTimeRule [Fragment:download,82,MediaSegment,0audio] Default
    dash.all.js:11 [58417][fragmentLoader] loaded video:MediaSegment:82.082 (200, 18ms, 2ms)
    dash.all.js:11 [58419][rulesController] [RULES]: sameTimeRequestRule [Fragment:download,82,MediaSegment,0,audio] Default
    dash.all.js:11 [58435][fragmentLoader] loaded audio:MediaSegment:82.082 (200, 14ms, 0ms)
    dash.all.js:11 [59390][indexHandler][video] Getting the request for time: 83.083
    dash.all.js:11 [59392][indexHandler][video] Index for time 83.083 is 82
    dash.all.js:11 [59393][indexHandler][video] SegmentTemplate: 82.082 / 1361.235
    dash.all.js:11 [59394][indexHandler][video] SegmentTemplate: 83.08299999999998 / 1361.235
    dash.all.js:11 [59395][rulesController] [RULES]: playbackTimeRule [Fragment:download,83,MediaSegment,0video] Default
    dash.all.js:11 [59396][rulesController] [RULES]: sameTimeRequestRule [Fragment:download,83,MediaSegment,0,video] Default
    dash.all.js:11 [59401][indexHandler][audio] Getting the request for time: 83.083
    dash.all.js:11 [59403][indexHandler][audio] Index for time 83.083 is 82
    dash.all.js:11 [59404][indexHandler][audio] SegmentTemplate: 82.082 / 1361.235
    dash.all.js:11 [59406][indexHandler][audio] SegmentTemplate: 83.08299999999998 / 1361.235
    dash.all.js:11 [59408][rulesController] [RULES]: playbackTimeRule [Fragment:download,83,MediaSegment,0audio] Default
    dash.all.js:11 [59416][fragmentLoader] loaded video:MediaSegment:83.08299999999998 (200, 17ms, 1ms)
    dash.all.js:11 [59418][rulesController] [RULES]: sameTimeRequestRule [Fragment:download,83,MediaSegment,0,audio] Default
    dash.all.js:11 [59437][fragmentLoader] loaded audio:MediaSegment:83.08299999999998 (200, 14ms, 1ms)
    dash.all.js:11 [59902][scheduleController][video] Stalling Buffer
    dash.all.js:11 [59903][bufferController][video] Waiting for more buffer before starting playback.
    dash.all.js:11 [59906][scheduleController][audio] Stalling Buffer
    dash.all.js:11 [59907][bufferController][audio] Waiting for more buffer before starting playback.
    dash.all.js:11 [63684][playbackController] <video> ratechange:  0




    ///HOG VIDEO

    [58250][rulesController] [RULES]: playbackTimeRule [Fragment:download,105,MediaSegment,0audio] Default
    dash.all.js:11 [58266][fragmentLoader] loaded video:MediaSegment:84.105 (200, 28ms, 1ms)
    dash.all.js:11 [58269][rulesController] [RULES]: sameTimeRequestRule [Fragment:download,105,MediaSegment,0,audio] Default
    dash.all.js:11 [58287][fragmentLoader] loaded audio:MediaSegment:84.105 (200, 14ms, 1ms)
    dash.all.js:11 [58982][indexHandler][video] Getting the request for time: 84.906
    dash.all.js:11 [58983][indexHandler][video] Index for time 84.906 is 105
    dash.all.js:11 [58984][indexHandler][video] SegmentTemplate: 84.105 / 3111.909
    dash.all.js:11 [58984][indexHandler][video] SegmentTemplate: 84.906 / 3111.909
    dash.all.js:11 [58985][rulesController] [RULES]: playbackTimeRule [Fragment:download,106,MediaSegment,0video] Default
    dash.all.js:11 [58986][rulesController] [RULES]: sameTimeRequestRule [Fragment:download,106,MediaSegment,0,video] Default
    dash.all.js:11 [58989][indexHandler][audio] Getting the request for time: 84.906
    dash.all.js:11 [58990][indexHandler][audio] Index for time 84.906 is 105
    dash.all.js:11 [58991][indexHandler][audio] SegmentTemplate: 84.105 / 3111.909
    dash.all.js:11 [58992][indexHandler][audio] SegmentTemplate: 84.906 / 3111.909
    dash.all.js:11 [58993][rulesController] [RULES]: playbackTimeRule [Fragment:download,106,MediaSegment,0audio] Default
    dash.all.js:11 [59002][fragmentLoader] loaded video:MediaSegment:84.906 (200, 14ms, 1ms)
    dash.all.js:11 [59003][rulesController] [RULES]: sameTimeRequestRule [Fragment:download,106,MediaSegment,0,audio] Default
    dash.all.js:11 [59014][fragmentLoader] loaded audio:MediaSegment:84.906 (200, 8ms, 1ms)
    dash.all.js:11 [59735][scheduleController][video] Stalling Buffer
    dash.all.js:11 [59736][bufferController][video] Waiting for more buffer before starting playback.
    dash.all.js:11 [59738][scheduleController][audio] Stalling Buffer
    dash.all.js:11 [59739][bufferController][audio] Waiting for more buffer before starting playback.
    dash.all.js:11 [61695][playbackController] <video> ratechange:  0
    </video></video>
  • H264 Encoding - Could not play video using VLC Player

    31 mars 2016, par bot1131357

    I am have trouble encoding an H264 video correctly using FFmpeg libav. I could not play the encoded video in VLC media player, and although I could play the video on MPC-HC the time shows 00:00/00:00. Clearly I’m missing something.

    The Media info from MPC-HC shows this :

    General
    Format : AVC
    Format/Info : Advanced Video Codec
    File size : 110 KiB
    Duration : 2s 400ms
    Overall bit rate : 375 Kbps
    Writing library : x264 core 148 r2665 a01e339
    Encoding settings : cabac=0 / ref=3 / deblock=1:0:0 / analyse=0x1:0x111 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=0 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=7 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=0 / weightp=0 / keyint=12 / keyint_min=1 / scenecut=40 / intra_refresh=0 / rc_lookahead=12 / rc=abr / mbtree=1 / bitrate=2000 / ratetol=1.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00

    Video
    Format : AVC
    Format/Info : Advanced Video Codec
    Format profile : Baseline@L2.1
    Format settings, CABAC : No
    Format settings, ReFrames : 3 frames
    Format settings, GOP : M=1, N=12
    Duration : 2s 400ms
    Bit rate : 2 000 Kbps
    Width : 320 pixels
    Height : 240 pixels
    Display aspect ratio : 4:3
    Frame rate mode : Variable
    Frame rate : 20.833 fps
    Color space : YUV
    Chroma subsampling : 4:2:0
    Bit depth : 8 bits
    Scan type : Progressive
    Bits/(Pixel*Frame) : 1.250
    Stream size : 586 KiB
    Writing library : x264 core 148 r2665 a01e339
    Encoding settings : cabac=0 / ref=3 / deblock=1:0:0 / analyse=0x1:0x111 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=0 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=7 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=0 / weightp=0 / keyint=12 / keyint_min=1 / scenecut=40 / intra_refresh=0 / rc_lookahead=12 / rc=abr / mbtree=1 / bitrate=2000 / ratetol=1.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00

    I noticed something odd in the above info :
    - The frame rate is 20.833 fps, instead of the specified 10 fps.
    - Duration of 2s 400ms did not seem right either, since the video played for more than 4s.

    Also, (AVFrame* picture)->pict_type is always set to AV_PICTURE_TYPE_NONE. I don’t think this is normal.

    The library that I’m using is ffmpeg-20160219-git-98a0053-win32-dev. I would really really appreciate if you could help me out of this confusion.

    /*
    * Video encoding example
    */
    char filename[] = "test.mp4";
    int main(int argc, char** argv)
    {
       AVCodec *codec = NULL;
       AVCodecContext *codecCtx= NULL;
       AVFormatContext *pFormatCtx = NULL;
       AVStream * pVideoStream = NULL;
       AVFrame *picture = NULL;

       int i, x, y,            //
           ret,                // Return value
           got_packet_ptr;     // Data encoded into packet

       printf("Video encoding\n");

       // Register all formats and codecs
       av_register_all();

       // allocate context
       pFormatCtx = avformat_alloc_context();
       memcpy(pFormatCtx->filename,filename,
           min(strlen(filename), sizeof(pFormatCtx->filename)));

       // guess format
       pFormatCtx->oformat = av_guess_format("h264", NULL, NULL);
       if (NULL==pFormatCtx->oformat)
       {
           cerr &lt;&lt; "Could not guess output format" &lt;&lt; endl;
           return -1;
       }  

       // Find the codec.
       codec = avcodec_find_encoder(pFormatCtx->oformat->video_codec);
       if (codec == NULL) {
           fprintf(stderr, "Codec not found\n");
           return -1;
       }

       // Set context
       int framerate = 10;
       codecCtx = avcodec_alloc_context3(codec);
       avcodec_get_context_defaults3(codecCtx, codec);
       codecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
       codecCtx->profile = FF_PROFILE_H264_BASELINE;
       // Resolution must be a multiple of two.
       codecCtx->width  = 320;
       codecCtx->height = 240;

       codecCtx->bit_rate = 2000000;
       codecCtx->time_base.den = framerate;
       codecCtx->time_base.num = 1;
       codecCtx->gop_size = 12; // emit one intra frame every twelve frames at most

       // Open the codec.  
       if (avcodec_open2(codecCtx, codec, NULL) &lt; 0)
       {
           printf("Cannot open video codec\n");
           return -1;
       }

       // Add stream to pFormatCtx
       pVideoStream = avformat_new_stream(pFormatCtx, codec);
       if (!pVideoStream)
       {
           printf("Cannot add new video stream\n");
           return -1;
       }
       pVideoStream->codec = codecCtx;
       pVideoStream->time_base.den = framerate;
       pVideoStream->time_base.num = 1;

       if (avio_open2(&amp;pFormatCtx->pb, filename, AVIO_FLAG_WRITE, NULL, NULL) &lt; 0)
       {
           printf("Cannot open file\n");
           return -1;
       }

       // Write file header.
       avformat_write_header(pFormatCtx, NULL);

       // Create frame
       picture= av_frame_alloc();
       picture->format = codecCtx->pix_fmt;
       picture->width  = codecCtx->width;
       picture->height = codecCtx->height;

       int bufferImgSize = av_image_get_buffer_size(codecCtx->pix_fmt, codecCtx->width,
                       codecCtx->height,1);    
       av_image_alloc(picture->data, picture->linesize, codecCtx->width, codecCtx->height,                 codecCtx->pix_fmt, 32);

       AVPacket avpkt;

       /* encode 1 second of video */
       for(i=0;i&lt;50;i++)
       {
           /* prepare a dummy image */
           /* Y */
           for(y=0;yheight;y++)
           {
               for(x=0;xwidth;x++)
               {
                   picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
               }
           }
           /* Cb and Cr */
           for(y=0;yheight/2;y++)
           {
               for(x=0;xwidth/2;x++)
               {
                   picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
                   picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
               }
           }

           // Get timestamp
           picture->pts = (float) i * (1000.0/(float)(codecCtx->time_base.den)) * 90;

           // Encode frame to packet
           av_init_packet(&amp;avpkt);
           got_packet_ptr = 0;
           int error = avcodec_encode_video2(codecCtx, &amp;avpkt, picture, &amp;got_packet_ptr);
           if (!error &amp;&amp; got_packet_ptr > 0)
           {
               // Write packet with frame.
               ret = (av_interleaved_write_frame(pFormatCtx, &amp;avpkt) == 0);        
           }  
           av_packet_unref(&amp;avpkt);
       }

       // Flush remaining encoded data
       while(1)
       {
           av_init_packet(&amp;avpkt);
           got_packet_ptr = 0;
           // Encode frame to packet.
           int error = avcodec_encode_video2(codecCtx, &amp;avpkt, NULL, &amp;got_packet_ptr);
           if (!error &amp;&amp; got_packet_ptr > 0)
           {
               // Write packet with frame.
               ret = (av_interleaved_write_frame(pFormatCtx, &amp;avpkt) == 0);        
           }
           else
           {
               break;
           }
           av_packet_unref(&amp;avpkt);
       }
       av_write_trailer(pFormatCtx);

       av_packet_unref(&amp;avpkt);
       av_frame_free(&amp;picture);

       avcodec_close(codecCtx);
       av_free(codecCtx);

       cin.get();
    }
  • Encoding Exception during Transcode with audio files

    6 mai 2016, par Hakop Zakaryan

    I am attempting to transcode using an FFMPEG Wrapper Library called JAVE on Mac OSX 10.11.3 using Eclipse 4.50

    My Converter.java class looks something like this :

    package matador;

    import it.sauronsoftware.jave.AudioAttributes;
    import it.sauronsoftware.jave.EncodingAttributes;
    import it.sauronsoftware.jave.EncoderException;
    import it.sauronsoftware.jave.InputFormatException;
    import it.sauronsoftware.jave.Encoder;
    import java.io.*;

    public class Converter {

    public static void main(String[] args) throws InputFormatException, EncoderException {

       File source = new File("Classic.m4a");
       File target = new File("target.mp3");

       AudioAttributes audio = new AudioAttributes();
       audio.setCodec("libmp3lame");
       audio.setBitRate(new Integer(128000));
       audio.setChannels(new Integer(2));
       audio.setSamplingRate(new Integer(44100));

       EncodingAttributes attrs = new EncodingAttributes();
       attrs.setFormat("mp3");
       attrs.setAudioAttributes(audio);

       Encoder encoder = new Encoder(new MyFFMPEGExecutableLocator());
       try {
       encoder.encode(source, target, attrs, null);
       } catch (IllegalArgumentException e) {

           e.printStackTrace();
       } catch (InputFormatException e) {

           e.printStackTrace();
       } catch (EncoderException e) {

           e.printStackTrace();
       }

    }

    }

    The problem I am running into is that with specific audio files (regardless of format) give me this EncoderException :

    it.sauronsoftware.jave.EncoderException:   Metadata:
    at it.sauronsoftware.jave.Encoder.encode(Encoder.java:863)
    at matador.Converter.main(Converter.java:32)

    I have looked through Encoder.java and the EncoderException on line 863 is this specific code :

    } else if (!line.startsWith("Output #0")) {
    throw new EncoderException(line);

    I have been unable to figure out why this may be occurring but specific audio files (WAV/AAC/etc) do encode yet a majority just give this exception.

    Thank you for the help !

    Edit : As per request for possibly being able to help me further, here is the entirety of the Encoder.java code :

    package it.sauronsoftware.jave;

    import java.io.File;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.Hashtable;
    import java.util.StringTokenizer;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    public class Encoder {

    private static final Pattern FORMAT_PATTERN = Pattern
           .compile("^\\s*([D ])([E ])\\s+([\\w,]+)\\s+.+$");

    private static final Pattern ENCODER_DECODER_PATTERN = Pattern.compile(
           "^\\s*([D ])([E ])([AVS]).{3}\\s+(.+)$", Pattern.CASE_INSENSITIVE);

    private static final Pattern PROGRESS_INFO_PATTERN = Pattern.compile(
           "\\s*(\\w+)\\s*=\\s*(\\S+)\\s*", Pattern.CASE_INSENSITIVE);

    private static final Pattern SIZE_PATTERN = Pattern.compile(
           "(\\d+)x(\\d+)", Pattern.CASE_INSENSITIVE);

    private static final Pattern FRAME_RATE_PATTERN = Pattern.compile(
           "([\\d.]+)\\s+(?:fps|tb\\(r\\))", Pattern.CASE_INSENSITIVE);

    private static final Pattern BIT_RATE_PATTERN = Pattern.compile(
           "(\\d+)\\s+kb/s", Pattern.CASE_INSENSITIVE);

    private static final Pattern SAMPLING_RATE_PATTERN = Pattern.compile(
           "(\\d+)\\s+Hz", Pattern.CASE_INSENSITIVE);

    private static final Pattern CHANNELS_PATTERN = Pattern.compile(
           "(mono|stereo)", Pattern.CASE_INSENSITIVE);

    private static final Pattern SUCCESS_PATTERN = Pattern.compile(
           "^\\s*video\\:\\S+\\s+audio\\:\\S+\\s+global headers\\:\\S+.*$",
           Pattern.CASE_INSENSITIVE);

    private FFMPEGLocator locator;

    public Encoder() {
       this.locator = new DefaultFFMPEGLocator();
    }

    public Encoder(FFMPEGLocator locator) {
       this.locator = locator;
    }

    public String[] getAudioDecoders() throws EncoderException {
       ArrayList res = new ArrayList();
       FFMPEGExecutor ffmpeg = locator.createExecutor();
       ffmpeg.addArgument("-formats");
       try {
           ffmpeg.execute();
           RBufferedReader reader = null;
           reader = new RBufferedReader(new InputStreamReader(ffmpeg
                   .getInputStream()));
           String line;
           boolean evaluate = false;
           while ((line = reader.readLine()) != null) {
               if (line.trim().length() == 0) {
                   continue;
               }
               if (evaluate) {
                   Matcher matcher = ENCODER_DECODER_PATTERN.matcher(line);
                   if (matcher.matches()) {
                       String decoderFlag = matcher.group(1);
                       String audioVideoFlag = matcher.group(3);
                       if ("D".equals(decoderFlag)
                               &amp;&amp; "A".equals(audioVideoFlag)) {
                           String name = matcher.group(4);
                           res.add(name);
                       }
                   } else {
                       break;
                   }
               } else if (line.trim().equals("Codecs:")) {
                   evaluate = true;
               }
           }
       } catch (IOException e) {
           throw new EncoderException(e);
       } finally {
           ffmpeg.destroy();
       }
       int size = res.size();
       String[] ret = new String[size];
       for (int i = 0; i &lt; size; i++) {
           ret[i] = (String) res.get(i);
       }
       return ret;
    }

    public String[] getAudioEncoders() throws EncoderException {
       ArrayList res = new ArrayList();
       FFMPEGExecutor ffmpeg = locator.createExecutor();
       ffmpeg.addArgument("-formats");
       try {
           ffmpeg.execute();
           RBufferedReader reader = null;
           reader = new RBufferedReader(new InputStreamReader(ffmpeg
                   .getInputStream()));
           String line;
           boolean evaluate = false;
           while ((line = reader.readLine()) != null) {
               if (line.trim().length() == 0) {
                   continue;
               }
               if (evaluate) {
                   Matcher matcher = ENCODER_DECODER_PATTERN.matcher(line);
                   if (matcher.matches()) {
                       String encoderFlag = matcher.group(2);
                       String audioVideoFlag = matcher.group(3);
                       if ("E".equals(encoderFlag)
                               &amp;&amp; "A".equals(audioVideoFlag)) {
                           String name = matcher.group(4);
                           res.add(name);
                       }
                   } else {
                       break;
                   }
               } else if (line.trim().equals("Codecs:")) {
                   evaluate = true;
               }
           }
       } catch (IOException e) {
           throw new EncoderException(e);
       } finally {
           ffmpeg.destroy();
       }
       int size = res.size();
       String[] ret = new String[size];
       for (int i = 0; i &lt; size; i++) {
           ret[i] = (String) res.get(i);
       }
       return ret;
    }

    public String[] getVideoDecoders() throws EncoderException {
       ArrayList res = new ArrayList();
       FFMPEGExecutor ffmpeg = locator.createExecutor();
       ffmpeg.addArgument("-formats");
       try {
           ffmpeg.execute();
           RBufferedReader reader = null;
           reader = new RBufferedReader(new InputStreamReader(ffmpeg
                   .getInputStream()));
           String line;
           boolean evaluate = false;
           while ((line = reader.readLine()) != null) {
               if (line.trim().length() == 0) {
                   continue;
               }
               if (evaluate) {
                   Matcher matcher = ENCODER_DECODER_PATTERN.matcher(line);
                   if (matcher.matches()) {
                       String decoderFlag = matcher.group(1);
                       String audioVideoFlag = matcher.group(3);
                       if ("D".equals(decoderFlag)
                               &amp;&amp; "V".equals(audioVideoFlag)) {
                           String name = matcher.group(4);
                           res.add(name);
                       }
                   } else {
                       break;
                   }
               } else if (line.trim().equals("Codecs:")) {
                   evaluate = true;
               }
           }
       } catch (IOException e) {
           throw new EncoderException(e);
       } finally {
           ffmpeg.destroy();
       }
       int size = res.size();
       String[] ret = new String[size];
       for (int i = 0; i &lt; size; i++) {
           ret[i] = (String) res.get(i);
       }
       return ret;
    }

    public String[] getVideoEncoders() throws EncoderException {
       ArrayList res = new ArrayList();
       FFMPEGExecutor ffmpeg = locator.createExecutor();
       ffmpeg.addArgument("-formats");
       try {
           ffmpeg.execute();
           RBufferedReader reader = null;
           reader = new RBufferedReader(new InputStreamReader(ffmpeg
                   .getInputStream()));
           String line;
           boolean evaluate = false;
           while ((line = reader.readLine()) != null) {
               if (line.trim().length() == 0) {
                   continue;
               }
               if (evaluate) {
                   Matcher matcher = ENCODER_DECODER_PATTERN.matcher(line);
                   if (matcher.matches()) {
                       String encoderFlag = matcher.group(2);
                       String audioVideoFlag = matcher.group(3);
                       if ("E".equals(encoderFlag)
                               &amp;&amp; "V".equals(audioVideoFlag)) {
                           String name = matcher.group(4);
                           res.add(name);
                       }
                   } else {
                       break;
                   }
               } else if (line.trim().equals("Codecs:")) {
                   evaluate = true;
               }
           }
       } catch (IOException e) {
           throw new EncoderException(e);
       } finally {
           ffmpeg.destroy();
       }
       int size = res.size();
       String[] ret = new String[size];
       for (int i = 0; i &lt; size; i++) {
           ret[i] = (String) res.get(i);
       }
       return ret;
    }

    public String[] getSupportedEncodingFormats() throws EncoderException {
       ArrayList res = new ArrayList();
       FFMPEGExecutor ffmpeg = locator.createExecutor();
       ffmpeg.addArgument("-formats");
       try {
           ffmpeg.execute();
           RBufferedReader reader = null;
           reader = new RBufferedReader(new InputStreamReader(ffmpeg
                   .getInputStream()));
           String line;
           boolean evaluate = false;
           while ((line = reader.readLine()) != null) {
               if (line.trim().length() == 0) {
                   continue;
               }
               if (evaluate) {
                   Matcher matcher = FORMAT_PATTERN.matcher(line);
                   if (matcher.matches()) {
                       String encoderFlag = matcher.group(2);
                       if ("E".equals(encoderFlag)) {
                           String aux = matcher.group(3);
                           StringTokenizer st = new StringTokenizer(aux, ",");
                           while (st.hasMoreTokens()) {
                               String token = st.nextToken().trim();
                               if (!res.contains(token)) {
                                   res.add(token);
                               }
                           }
                       }
                   } else {
                       break;
                   }
               } else if (line.trim().equals("File formats:")) {
                   evaluate = true;
               }
           }
       } catch (IOException e) {
           throw new EncoderException(e);
       } finally {
           ffmpeg.destroy();
       }
       int size = res.size();
       String[] ret = new String[size];
       for (int i = 0; i &lt; size; i++) {
           ret[i] = (String) res.get(i);
       }
       return ret;
    }

    public String[] getSupportedDecodingFormats() throws EncoderException {
       ArrayList res = new ArrayList();
       FFMPEGExecutor ffmpeg = locator.createExecutor();
       ffmpeg.addArgument("-formats");
       try {
           ffmpeg.execute();
           RBufferedReader reader = null;
           reader = new RBufferedReader(new InputStreamReader(ffmpeg
                   .getInputStream()));
           String line;
           boolean evaluate = false;
           while ((line = reader.readLine()) != null) {
               if (line.trim().length() == 0) {
                   continue;
               }
               if (evaluate) {
                   Matcher matcher = FORMAT_PATTERN.matcher(line);
                   if (matcher.matches()) {
                       String decoderFlag = matcher.group(1);
                       if ("D".equals(decoderFlag)) {
                           String aux = matcher.group(3);
                           StringTokenizer st = new StringTokenizer(aux, ",");
                           while (st.hasMoreTokens()) {
                               String token = st.nextToken().trim();
                               if (!res.contains(token)) {
                                   res.add(token);
                               }
                           }
                       }
                   } else {
                       break;
                   }
               } else if (line.trim().equals("File formats:")) {
                   evaluate = true;
               }
           }
       } catch (IOException e) {
           throw new EncoderException(e);
       } finally {
           ffmpeg.destroy();
       }
       int size = res.size();
       String[] ret = new String[size];
       for (int i = 0; i &lt; size; i++) {
           ret[i] = (String) res.get(i);
       }
       return ret;
    }

    public MultimediaInfo getInfo(File source) throws InputFormatException,
           EncoderException {
       FFMPEGExecutor ffmpeg = locator.createExecutor();
       ffmpeg.addArgument("-i");
       ffmpeg.addArgument(source.getAbsolutePath());
       try {
           ffmpeg.execute();
       } catch (IOException e) {
           throw new EncoderException(e);
       }
       try {
           RBufferedReader reader = null;
           reader = new RBufferedReader(new InputStreamReader(ffmpeg
                   .getErrorStream()));
           return parseMultimediaInfo(source, reader);
       } finally {
           ffmpeg.destroy();
       }
    }

    private MultimediaInfo parseMultimediaInfo(File source,
           RBufferedReader reader) throws InputFormatException,
           EncoderException {
       Pattern p1 = Pattern.compile("^\\s*Input #0, (\\w+).+$\\s*",
               Pattern.CASE_INSENSITIVE);
       Pattern p2 = Pattern.compile(
               "^\\s*Duration: (\\d\\d):(\\d\\d):(\\d\\d)\\.(\\d).*$",
               Pattern.CASE_INSENSITIVE);
       Pattern p3 = Pattern.compile(
               "^\\s*Stream #\\S+: ((?:Audio)|(?:Video)|(?:Data)): (.*)\\s*$",
               Pattern.CASE_INSENSITIVE);
       MultimediaInfo info = null;
       try {
           int step = 0;
           while (true) {
               String line = reader.readLine();
               if (line == null) {
                   break;
               }
               if (step == 0) {
                   String token = source.getAbsolutePath() + ": ";
                   if (line.startsWith(token)) {
                       String message = line.substring(token.length());
                       throw new InputFormatException(message);
                   }
                   Matcher m = p1.matcher(line);
                   if (m.matches()) {
                       String format = m.group(1);
                       info = new MultimediaInfo();
                       info.setFormat(format);
                       step++;
                   }
               } else if (step == 1) {
                   Matcher m = p2.matcher(line);
                   if (m.matches()) {
                       long hours = Integer.parseInt(m.group(1));
                       long minutes = Integer.parseInt(m.group(2));
                       long seconds = Integer.parseInt(m.group(3));
                       long dec = Integer.parseInt(m.group(4));
                       long duration = (dec * 100L) + (seconds * 1000L)
                               + (minutes * 60L * 1000L)
                               + (hours * 60L * 60L * 1000L);
                       info.setDuration(duration);
                       step++;
                   } else {
                       step = 3;
                   }
               } else if (step == 2) {
                   Matcher m = p3.matcher(line);
                   if (m.matches()) {
                       String type = m.group(1);
                       String specs = m.group(2);
                       if ("Video".equalsIgnoreCase(type)) {
                           VideoInfo video = new VideoInfo();
                           StringTokenizer st = new StringTokenizer(specs, ",");
                           for (int i = 0; st.hasMoreTokens(); i++) {
                               String token = st.nextToken().trim();
                               if (i == 0) {
                                   video.setDecoder(token);
                               } else {
                                   boolean parsed = false;
                                   // Video size.
                                   Matcher m2 = SIZE_PATTERN.matcher(token);
                                   if (!parsed &amp;&amp; m2.find()) {
                                       int width = Integer.parseInt(m2
                                               .group(1));
                                       int height = Integer.parseInt(m2
                                               .group(2));
                                       video.setSize(new VideoSize(width,
                                               height));
                                       parsed = true;
                                   }
                                   // Frame rate.
                                   m2 = FRAME_RATE_PATTERN.matcher(token);
                                   if (!parsed &amp;&amp; m2.find()) {
                                       try {
                                           float frameRate = Float
                                                   .parseFloat(m2.group(1));
                                           video.setFrameRate(frameRate);
                                       } catch (NumberFormatException e) {
                                           ;
                                       }
                                       parsed = true;
                                   }
                                   // Bit rate.
                                   m2 = BIT_RATE_PATTERN.matcher(token);
                                   if (!parsed &amp;&amp; m2.find()) {
                                       int bitRate = Integer.parseInt(m2
                                               .group(1));
                                       video.setBitRate(bitRate);
                                       parsed = true;
                                   }
                               }
                           }
                           info.setVideo(video);
                       } else if ("Audio".equalsIgnoreCase(type)) {
                           AudioInfo audio = new AudioInfo();
                           StringTokenizer st = new StringTokenizer(specs, ",");
                           for (int i = 0; st.hasMoreTokens(); i++) {
                               String token = st.nextToken().trim();
                               if (i == 0) {
                                   audio.setDecoder(token);
                               } else {
                                   boolean parsed = false;
                                   // Sampling rate.
                                   Matcher m2 = SAMPLING_RATE_PATTERN
                                           .matcher(token);
                                   if (!parsed &amp;&amp; m2.find()) {
                                       int samplingRate = Integer.parseInt(m2
                                               .group(1));
                                       audio.setSamplingRate(samplingRate);
                                       parsed = true;
                                   }
                                   // Channels.
                                   m2 = CHANNELS_PATTERN.matcher(token);
                                   if (!parsed &amp;&amp; m2.find()) {
                                       String ms = m2.group(1);
                                       if ("mono".equalsIgnoreCase(ms)) {
                                           audio.setChannels(1);
                                       } else if ("stereo"
                                               .equalsIgnoreCase(ms)) {
                                           audio.setChannels(2);
                                       }
                                       parsed = true;
                                   }
                                   // Bit rate.
                                   m2 = BIT_RATE_PATTERN.matcher(token);
                                   if (!parsed &amp;&amp; m2.find()) {
                                       int bitRate = Integer.parseInt(m2
                                               .group(1));
                                       audio.setBitRate(bitRate);
                                       parsed = true;
                                   }
                               }
                           }
                           info.setAudio(audio);
                       }
                   } else {
                       step = 3;
                   }
               }
               if (step == 3) {
                   reader.reinsertLine(line);
                   break;
               }
           }
       } catch (IOException e) {
           throw new EncoderException(e);
       }
       if (info == null) {
           throw new InputFormatException();
       }
       return info;
    }

    private Hashtable parseProgressInfoLine(String line) {
       Hashtable table = null;
       Matcher m = PROGRESS_INFO_PATTERN.matcher(line);
       while (m.find()) {
           if (table == null) {
               table = new Hashtable();
           }
           String key = m.group(1);
           String value = m.group(2);
           table.put(key, value);
       }
       return table;
    }

    public void encode(File source, File target, EncodingAttributes attributes)
           throws IllegalArgumentException, InputFormatException,
           EncoderException {
       encode(source, target, attributes, null);
    }

    public void encode(File source, File target, EncodingAttributes attributes,
           EncoderProgressListener listener) throws IllegalArgumentException,
           InputFormatException, EncoderException {
       String formatAttribute = attributes.getFormat();
       Float offsetAttribute = attributes.getOffset();
       Float durationAttribute = attributes.getDuration();
       AudioAttributes audioAttributes = attributes.getAudioAttributes();
       VideoAttributes videoAttributes = attributes.getVideoAttributes();
       if (audioAttributes == null &amp;&amp; videoAttributes == null) {
           throw new IllegalArgumentException(
                   "Both audio and video attributes are null");
       }
       target = target.getAbsoluteFile();
       target.getParentFile().mkdirs();
       FFMPEGExecutor ffmpeg = locator.createExecutor();
       if (offsetAttribute != null) {
           ffmpeg.addArgument("-ss");
           ffmpeg.addArgument(String.valueOf(offsetAttribute.floatValue()));
       }
       ffmpeg.addArgument("-i");
       ffmpeg.addArgument(source.getAbsolutePath());
       if (durationAttribute != null) {
           ffmpeg.addArgument("-t");
           ffmpeg.addArgument(String.valueOf(durationAttribute.floatValue()));
       }
       if (videoAttributes == null) {
           ffmpeg.addArgument("-vn");
       } else {
           String codec = videoAttributes.getCodec();
           if (codec != null) {
               ffmpeg.addArgument("-vcodec");
               ffmpeg.addArgument(codec);
           }
           String tag = videoAttributes.getTag();
           if (tag != null) {
               ffmpeg.addArgument("-vtag");
               ffmpeg.addArgument(tag);
           }
           Integer bitRate = videoAttributes.getBitRate();
           if (bitRate != null) {
               ffmpeg.addArgument("-b");
               ffmpeg.addArgument(String.valueOf(bitRate.intValue()));
           }
           Integer frameRate = videoAttributes.getFrameRate();
           if (frameRate != null) {
               ffmpeg.addArgument("-r");
               ffmpeg.addArgument(String.valueOf(frameRate.intValue()));
           }
           VideoSize size = videoAttributes.getSize();
           if (size != null) {
               ffmpeg.addArgument("-s");
               ffmpeg.addArgument(String.valueOf(size.getWidth()) + "x"
                       + String.valueOf(size.getHeight()));
           }
       }
       if (audioAttributes == null) {
           ffmpeg.addArgument("-an");
       } else {
           String codec = audioAttributes.getCodec();
           if (codec != null) {
               ffmpeg.addArgument("-acodec");
               ffmpeg.addArgument(codec);
           }
           Integer bitRate = audioAttributes.getBitRate();
           if (bitRate != null) {
               ffmpeg.addArgument("-ab");
               ffmpeg.addArgument(String.valueOf(bitRate.intValue()));
           }
           Integer channels = audioAttributes.getChannels();
           if (channels != null) {
               ffmpeg.addArgument("-ac");
               ffmpeg.addArgument(String.valueOf(channels.intValue()));
           }
           Integer samplingRate = audioAttributes.getSamplingRate();
           if (samplingRate != null) {
               ffmpeg.addArgument("-ar");
               ffmpeg.addArgument(String.valueOf(samplingRate.intValue()));
           }
           Integer volume = audioAttributes.getVolume();
           if (volume != null) {
               ffmpeg.addArgument("-vol");
               ffmpeg.addArgument(String.valueOf(volume.intValue()));
           }
       }
       ffmpeg.addArgument("-f");
       ffmpeg.addArgument(formatAttribute);
       ffmpeg.addArgument("-y");
       ffmpeg.addArgument(target.getAbsolutePath());
       try {
           ffmpeg.execute();
       } catch (IOException e) {
           throw new EncoderException(e);
       }
       try {
           String lastWarning = null;
           long duration;
           long progress = 0;
           RBufferedReader reader = null;
           reader = new RBufferedReader(new InputStreamReader(ffmpeg
                   .getErrorStream()));
           MultimediaInfo info = parseMultimediaInfo(source, reader);
           if (durationAttribute != null) {
               duration = (long) Math
                       .round((durationAttribute.floatValue() * 1000L));
           } else {
               duration = info.getDuration();
               if (offsetAttribute != null) {
                   duration -= (long) Math
                           .round((offsetAttribute.floatValue() * 1000L));
               }
           }
           if (listener != null) {
               listener.sourceInfo(info);
           }
           int step = 0;
           String line;
           while ((line = reader.readLine()) != null) {
               if (step == 0) {
                   if (line.startsWith("WARNING: ")) {
                       if (listener != null) {
                           listener.message(line);
                       }
                   } else if (!line.startsWith("Output #0")) {
                       throw new EncoderException(line);
                   } else {
                       step++;
                   }
               } else if (step == 1) {
                   if (!line.startsWith("  ")) {
                       step++;
                   }
               }
               if (step == 2) {
                   if (!line.startsWith("Stream mapping:")) {
                       throw new EncoderException(line);
                   } else {
                       step++;
                   }
               } else if (step == 3) {
                   if (!line.startsWith("  ")) {
                       step++;
                   }
               }
               if (step == 4) {
                   line = line.trim();
                   if (line.length() > 0) {
                       Hashtable table = parseProgressInfoLine(line);
                       if (table == null) {
                           if (listener != null) {
                               listener.message(line);
                           }
                           lastWarning = line;
                       } else {
                           if (listener != null) {
                               String time = (String) table.get("time");
                               if (time != null) {
                                   int dot = time.indexOf('.');
                                   if (dot > 0 &amp;&amp; dot == time.length() - 2
                                           &amp;&amp; duration > 0) {
                                       String p1 = time.substring(0, dot);
                                       String p2 = time.substring(dot + 1);
                                       try {
                                           long i1 = Long.parseLong(p1);
                                           long i2 = Long.parseLong(p2);
                                           progress = (i1 * 1000L)
                                                   + (i2 * 100L);
                                           int perm = (int) Math
                                                   .round((double) (progress * 1000L)
                                                           / (double) duration);
                                           if (perm > 1000) {
                                               perm = 1000;kMDItemAudioEncodingApplication = "Lavf57.26.100"
                                           }
                                           listener.progress(perm);
                                       } catch (NumberFormatException e) {
                                           ;
                                       }
                                   }
                               }
                           }
                           lastWarning = null;
                       }
                   }
               }
           }
           if (lastWarning != null) {
               if (!SUCCESS_PATTERN.matcher(lastWarning).matches()) {
                   throw new EncoderException(lastWarning);
               }
           }
       } catch (IOException e) {
           throw new EncoderException(e);
       } finally {
           ffmpeg.destroy();
       }
    }

    }