Recherche avancée

Médias (91)

Autres articles (76)

  • Support de tous types de médias

    10 avril 2011

    Contrairement à beaucoup de logiciels et autres plate-formes modernes de partage de documents, MediaSPIP a l’ambition de gérer un maximum de formats de documents différents qu’ils soient de type : images (png, gif, jpg, bmp et autres...) ; audio (MP3, Ogg, Wav et autres...) ; vidéo (Avi, MP4, Ogv, mpg, mov, wmv et autres...) ; contenu textuel, code ou autres (open office, microsoft office (tableur, présentation), web (html, css), LaTeX, Google Earth) (...)

  • Submit bugs and patches

    13 avril 2011

    Unfortunately a software is never perfect.
    If you think you have found a bug, report it using our ticket system. Please to help us to fix it by providing the following information : the browser you are using, including the exact version as precise an explanation as possible of the problem if possible, the steps taken resulting in the problem a link to the site / page in question
    If you think you have solved the bug, fill in a ticket and attach to it a corrective patch.
    You may also (...)

  • Les tâches Cron régulières de la ferme

    1er décembre 2010, par

    La gestion de la ferme passe par l’exécution à intervalle régulier de plusieurs tâches répétitives dites Cron.
    Le super Cron (gestion_mutu_super_cron)
    Cette tâche, planifiée chaque minute, a pour simple effet d’appeler le Cron de l’ensemble des instances de la mutualisation régulièrement. Couplée avec un Cron système sur le site central de la mutualisation, cela permet de simplement générer des visites régulières sur les différents sites et éviter que les tâches des sites peu visités soient trop (...)

Sur d’autres sites (11492)

  • x264 encoded frames into a mp4 container with ffmpeg API

    10 septembre 2019, par PJD

    I'm struggling with understanding what is and what is not needed in getting my already encoded x264 frames into a video container file using ffmpeg's libavformat API.

    



    My current program will get the x264 frames like this -

    



    while( x264_encoder_delayed_frames( h ) )
{
    printf("Writing delayed frame %u\n", delayed_frame_counter++);
    i_frame_size = x264_encoder_encode( h, &nal, &i_nal, NULL, &pic_out );
    if( i_frame_size < 0 ) {
            printf("Failed to encode a delayed x264 frame.\n");
            return ERROR;
        }
    else if( i_frame_size )
    {
        if( !fwrite(nal->p_payload, i_frame_size, 1, video_file_ptr) ) {
            printf("Failed to write a delayed x264 frame.\n");
            return ERROR;
        }
    }
}


    



    If I use the CLI to the ffmpeg binary, I can put these frames into a container using :

    



    ffmpeg -i "raw_frames.h264" -c:v copy -f mp4 "video.mp4"


    



    I would like to code this function into my program using the libavformat API though. I'm a little stuck in the concepts and the order on which each ffmpeg function is needed to be called.

    



    So far I have written :

    



            mAVOutputFormat = av_guess_format("gen_vid.mp4", NULL, NULL);
        printf("Guessed format\n");

        int ret = avformat_alloc_output_context2(&mAVFormatContext, NULL, NULL, "gen_vid.mp4");
        printf("Created context = %d\n", ret);
        printf("Format = %s\n", mAVFormatContext->oformat->name);

        mAVStream = avformat_new_stream(mAVFormatContext, 0);
        if (!mAVStream) {
            printf("Failed allocating output stream\n");
        } else {
            printf("Allocated stream.\n");
        }

        mAVCodecParameters = mAVStream->codecpar;
        if (mAVCodecParameters->codec_type != AVMEDIA_TYPE_AUDIO &&
            mAVCodecParameters->codec_type != AVMEDIA_TYPE_VIDEO &&
            mAVCodecParameters->codec_type != AVMEDIA_TYPE_SUBTITLE) {
            printf("Invalid codec?\n");
        }

        if (!(mAVFormatContext->oformat->flags & AVFMT_NOFILE)) {
            ret = avio_open(&mAVFormatContext->pb, "gen_vid.mp4", AVIO_FLAG_WRITE);
            if (ret < 0) {
              printf("Could not open output file '%s'", "gen_vid.mp4");
            }
          }

        ret = avformat_write_header(mAVFormatContext, NULL);
        if (ret < 0) {
          printf("Error occurred when opening output file\n");
        }


    



    This will print out :

    



    Guessed format
Created context = 0
Format = mp4
Allocated stream.
Invalid codec?
[mp4 @ 0x55ffcea2a2c0] Could not find tag for codec none in stream #0, codec not currently supported in container
Error occurred when opening output file


    



    How can I make sure the codec type is set correctly for my video ?
Next I need to somehow point my mAVStream to use my x264 frames - advice would be great.

    



    Update 1 :
So I've tried to set the H264 codec, so the codec's meta-data is available. I seem to hit 2 newer issues now.
1) It cannot find the device and therefore cannot configure the encoder.
2) I get the "dimensions not set".

    



    mAVOutputFormat = av_guess_format("gen_vid.mp4", NULL, NULL);
printf("Guessed format\n");

// MUST allocate the media file format context. 
int ret = avformat_alloc_output_context2(&mAVFormatContext, NULL, NULL, "gen_vid.mp4");
printf("Created context = %d\n", ret);
printf("Format = %s\n", mAVFormatContext->oformat->name);

// Even though we already have encoded the H264 frames using x264,
// we still need the codec's meta-data.
const AVCodec *mAVCodec;
mAVCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
if (!mAVCodec) {
    fprintf(stderr, "Codec '%s' not found\n", "H264");
    exit(1);
}
mAVCodecContext = avcodec_alloc_context3(mAVCodec);
if (!mAVCodecContext) {
    fprintf(stderr, "Could not allocate video codec context\n");
    exit(1);
}
printf("Codec context allocated with defaults.\n");
/* put sample parameters */
mAVCodecContext->bit_rate = 400000;
mAVCodecContext->width = width;
mAVCodecContext->height = height;
mAVCodecContext->time_base = (AVRational){1, 30};
mAVCodecContext->framerate = (AVRational){30, 1};
mAVCodecContext->gop_size = 10;
mAVCodecContext->level = 31;
mAVCodecContext->max_b_frames = 1;
mAVCodecContext->pix_fmt = AV_PIX_FMT_NV12;

av_opt_set(mAVCodecContext->priv_data, "preset", "slow", 0);
printf("Set codec parameters.\n");

// Initialize the AVCodecContext to use the given AVCodec.
avcodec_open2(mAVCodecContext, mAVCodec, NULL);            

// Add a new stream to a media file. Must be called before
// calling avformat_write_header().
mAVStream = avformat_new_stream(mAVFormatContext, mAVCodec);
if (!mAVStream) {
    printf("Failed allocating output stream\n");
} else {
    printf("Allocated stream.\n");
}

// TODO How should codecpar be set?
mAVCodecParameters = mAVStream->codecpar;
if (mAVCodecParameters->codec_type != AVMEDIA_TYPE_AUDIO &&
    mAVCodecParameters->codec_type != AVMEDIA_TYPE_VIDEO &&
    mAVCodecParameters->codec_type != AVMEDIA_TYPE_SUBTITLE) {
    printf("Invalid codec?\n");
}

if (!(mAVFormatContext->oformat->flags & AVFMT_NOFILE)) {
    ret = avio_open(&mAVFormatContext->pb, "gen_vid.mp4", AVIO_FLAG_WRITE);
    if (ret < 0) {
      printf("Could not open output file '%s'", "gen_vid.mp4");
    }
  }
printf("Called avio_open()\n");

// MUST write a header.
ret = avformat_write_header(mAVFormatContext, NULL);
if (ret < 0) {
  printf("Error occurred when opening output file (writing header).\n");
}


    



    Now I am getting this output -

    



    Guessed format
Created context = 0
Format = mp4
Codec context allocated with defaults.
Set codec parameters.
[h264_v4l2m2m @ 0x556460344b40] Could not find a valid device
[h264_v4l2m2m @ 0x556460344b40] can't configure encoder
Allocated stream.
Invalid codec?
Called avio_open()
[mp4 @ 0x5564603442c0] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.
[mp4 @ 0x5564603442c0] dimensions not set
Error occurred when opening output file (writing header).


    


  • FFmpeg pauses the extraction of frames at 20% (but when closed, dumps all frames to disk)

    1er décembre 2019, par Nicke Manarin

    I’m trying to extract frames from a video using FFmpeg. I want to be able to control which frames to extract, by setting the start, end and FPS values.

    The problem is, that after the extraction begins, FFmpeg stops after 20% of the way. It always stops there, independently of the frame count.

    This is the code that I’m using :

    var start = TimeSpan.FromMilliseconds(SelectionSlider.LowerValue);
    var end = TimeSpan.FromMilliseconds(SelectionSlider.UpperValue);
    var fps = FpsIntegerUpDown.Value;
    var count = CountFrames(); //Duration x FPS
    var folder = Path.Combine(RootFolder, "Import");
    var path = Path.Combine(folder, $"%0{count.ToString().Length + 1}d.png");

    try
    {
       //Create temporary folder.
       if (Directory.Exists(folder))
           Directory.Delete(folder, true);

       Directory.CreateDirectory(folder);

       CaptureProgressBar.Value = 0;
       CaptureProgressBar.Maximum = count;

       var info = new ProcessStartInfo(UserSettings.All.FfmpegLocation)
       {
           Arguments = $" -i \"{VideoPath}\" -vsync 2 -progress pipe:1 -vf scale={VideoWidth}:{VideoHeight} -ss {start:hh\\:mm\\:ss\\.fff} -to {end:hh\\:mm\\:ss\\.fff} -hide_banner -c:v png -r {fps} -vframes {count} \"{path}\"",
           CreateNoWindow = true,
           ErrorDialog = false,
           UseShellExecute = false,
           RedirectStandardError = true,
           RedirectStandardOutput = true
        };

        _process = new Process();
        _process.OutputDataReceived += (sender, e) =>
        {
            Debug.WriteLine(e.Data);

            if (string.IsNullOrEmpty(e.Data))
                return;

            var parsed = e.Data.Split('=');

            switch (parsed[0])
            {
                case "frame":
                    Dispatcher?.InvokeAsync(() => { CaptureProgressBar.Value = Convert.ToDouble(parsed[1]); });
                    break;

                case "progress":
                    if (parsed[1] == "end" && IsLoaded)
                        GetFiles(folder); //Get all files from the output folder.

                    break;
             }
       };

    _process.ErrorDataReceived += (sender, e) =>
    {
       if (!string.IsNullOrEmpty(e.Data))
           throw new Exception("Error while capturing frames with FFmpeg.") { HelpLink = $"Command:\n\r{info.Arguments}\n\rResult:\n\r{e.Data}" };
    };

    _process.StartInfo = info;
    _process.Start();
    _process.BeginOutputReadLine();

    //Just to wait...
    await Task.Factory.StartNew(() => _process.WaitForExit());

    So, after starting the import process, FFmpeg will extract some frames, and after reaching around 20%, it will pause the extraction.

    frame=95
    fps=5.79
    stream_0_0_q=-0.0
    bitrate=N/A
    total_size=N/A
    out_time_us=1400000
    out_time_ms=1400000
    out_time=00:00:01.400000
    dup_frames=0
    drop_frames=0
    speed=0.0854x

    progress=continue
    frame=106
    fps=6.25
    stream_0_0_q=-0.0
    bitrate=N/A
    total_size=N/A
    out_time_us=1583333
    out_time_ms=1583333
    out_time=00:00:01.583333
    dup_frames=0
    drop_frames=0
    speed=0.0933x
    progress=continue

    frame=117
    fps=6.67
    stream_0_0_q=-0.0
    bitrate=N/A
    total_size=N/A
    out_time_us=1766667
    out_time_ms=1766667
    out_time=00:00:01.766667
    dup_frames=0
    drop_frames=0
    speed=0.101x
    progress=continue

    Something strange : if I close the app while is the extraction is paused, suddenly FFmpeg will dump all frames to the folder.

    Why would FFmpeg pause the extraction at all (But continue doing in memory) ?
    Is there any way for me to force FFmpeg to extract the frames normally ?

    PS : It does not happen while using FFmpeg via cmd, so it must be something in code.

  • x264 encoded frames into a mp4 container with ffmpeg API

    10 septembre 2019, par PJD

    I’m struggling with understanding what is and what is not needed in getting my already encoded x264 frames into a video container file using ffmpeg’s libavformat API.

    My current program will get the x264 frames like this -

    while( x264_encoder_delayed_frames( h ) )
    {
       printf("Writing delayed frame %u\n", delayed_frame_counter++);
       i_frame_size = x264_encoder_encode( h, &nal, &i_nal, NULL, &pic_out );
       if( i_frame_size < 0 ) {
               printf("Failed to encode a delayed x264 frame.\n");
               return ERROR;
           }
       else if( i_frame_size )
       {
           if( !fwrite(nal->p_payload, i_frame_size, 1, video_file_ptr) ) {
               printf("Failed to write a delayed x264 frame.\n");
               return ERROR;
           }
       }
    }

    If I use the CLI to the ffmpeg binary, I can put these frames into a container using :

    ffmpeg -i "raw_frames.h264" -c:v copy -f mp4 "video.mp4"

    I would like to code this function into my program using the libavformat API though. I’m a little stuck in the concepts and the order on which each ffmpeg function is needed to be called.

    So far I have written :

           mAVOutputFormat = av_guess_format("gen_vid.mp4", NULL, NULL);
           printf("Guessed format\n");

           int ret = avformat_alloc_output_context2(&mAVFormatContext, NULL, NULL, "gen_vid.mp4");
           printf("Created context = %d\n", ret);
           printf("Format = %s\n", mAVFormatContext->oformat->name);

           mAVStream = avformat_new_stream(mAVFormatContext, 0);
           if (!mAVStream) {
               printf("Failed allocating output stream\n");
           } else {
               printf("Allocated stream.\n");
           }

           mAVCodecParameters = mAVStream->codecpar;
           if (mAVCodecParameters->codec_type != AVMEDIA_TYPE_AUDIO &&
               mAVCodecParameters->codec_type != AVMEDIA_TYPE_VIDEO &&
               mAVCodecParameters->codec_type != AVMEDIA_TYPE_SUBTITLE) {
               printf("Invalid codec?\n");
           }

           if (!(mAVFormatContext->oformat->flags & AVFMT_NOFILE)) {
               ret = avio_open(&mAVFormatContext->pb, "gen_vid.mp4", AVIO_FLAG_WRITE);
               if (ret < 0) {
                 printf("Could not open output file '%s'", "gen_vid.mp4");
               }
             }

           ret = avformat_write_header(mAVFormatContext, NULL);
           if (ret < 0) {
             printf("Error occurred when opening output file\n");
           }

    This will print out :

    Guessed format
    Created context = 0
    Format = mp4
    Allocated stream.
    Invalid codec?
    [mp4 @ 0x55ffcea2a2c0] Could not find tag for codec none in stream #0, codec not currently supported in container
    Error occurred when opening output file

    How can I make sure the codec type is set correctly for my video ?
    Next I need to somehow point my mAVStream to use my x264 frames - advice would be great.

    Update 1 :
    So I’ve tried to set the H264 codec, so the codec’s meta-data is available. I seem to hit 2 newer issues now.
    1) It cannot find the device and therefore cannot configure the encoder.
    2) I get the "dimensions not set".

    mAVOutputFormat = av_guess_format("gen_vid.mp4", NULL, NULL);
    printf("Guessed format\n");

    // MUST allocate the media file format context.
    int ret = avformat_alloc_output_context2(&mAVFormatContext, NULL, NULL, "gen_vid.mp4");
    printf("Created context = %d\n", ret);
    printf("Format = %s\n", mAVFormatContext->oformat->name);

    // Even though we already have encoded the H264 frames using x264,
    // we still need the codec's meta-data.
    const AVCodec *mAVCodec;
    mAVCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
    if (!mAVCodec) {
       fprintf(stderr, "Codec '%s' not found\n", "H264");
       exit(1);
    }
    mAVCodecContext = avcodec_alloc_context3(mAVCodec);
    if (!mAVCodecContext) {
       fprintf(stderr, "Could not allocate video codec context\n");
       exit(1);
    }
    printf("Codec context allocated with defaults.\n");
    /* put sample parameters */
    mAVCodecContext->bit_rate = 400000;
    mAVCodecContext->width = width;
    mAVCodecContext->height = height;
    mAVCodecContext->time_base = (AVRational){1, 30};
    mAVCodecContext->framerate = (AVRational){30, 1};
    mAVCodecContext->gop_size = 10;
    mAVCodecContext->level = 31;
    mAVCodecContext->max_b_frames = 1;
    mAVCodecContext->pix_fmt = AV_PIX_FMT_NV12;

    av_opt_set(mAVCodecContext->priv_data, "preset", "slow", 0);
    printf("Set codec parameters.\n");

    // Initialize the AVCodecContext to use the given AVCodec.
    avcodec_open2(mAVCodecContext, mAVCodec, NULL);            

    // Add a new stream to a media file. Must be called before
    // calling avformat_write_header().
    mAVStream = avformat_new_stream(mAVFormatContext, mAVCodec);
    if (!mAVStream) {
       printf("Failed allocating output stream\n");
    } else {
       printf("Allocated stream.\n");
    }

    // TODO How should codecpar be set?
    mAVCodecParameters = mAVStream->codecpar;
    if (mAVCodecParameters->codec_type != AVMEDIA_TYPE_AUDIO &&
       mAVCodecParameters->codec_type != AVMEDIA_TYPE_VIDEO &&
       mAVCodecParameters->codec_type != AVMEDIA_TYPE_SUBTITLE) {
       printf("Invalid codec?\n");
    }

    if (!(mAVFormatContext->oformat->flags & AVFMT_NOFILE)) {
       ret = avio_open(&mAVFormatContext->pb, "gen_vid.mp4", AVIO_FLAG_WRITE);
       if (ret < 0) {
         printf("Could not open output file '%s'", "gen_vid.mp4");
       }
     }
    printf("Called avio_open()\n");

    // MUST write a header.
    ret = avformat_write_header(mAVFormatContext, NULL);
    if (ret < 0) {
     printf("Error occurred when opening output file (writing header).\n");
    }

    Now I am getting this output -

    Guessed format
    Created context = 0
    Format = mp4
    Codec context allocated with defaults.
    Set codec parameters.
    [h264_v4l2m2m @ 0x556460344b40] Could not find a valid device
    [h264_v4l2m2m @ 0x556460344b40] can't configure encoder
    Allocated stream.
    Invalid codec?
    Called avio_open()
    [mp4 @ 0x5564603442c0] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.
    [mp4 @ 0x5564603442c0] dimensions not set
    Error occurred when opening output file (writing header).