how to use libavcodec/ffmpeg to find duration of video file

前端 未结 4 2014
半阙折子戏
半阙折子戏 2020-12-28 17:31

I needed a library to perform basic functions such as length, size, etc of a video file (i\'m guessing through the metadata or tags) so I chose ffmpeg. Vali

相关标签:
4条回答
  • 2020-12-28 17:40

    libavcodec is pretty hard to program against, and it's also hard to find documentation, so I feel your pain. This tutorial is a good start. Here is the main API docs.

    The main data structure for querying video files is AVFormatContext. In the tutorial, it's the first thing you open, using av_open_input_file -- the docs for that say it's deprecated and you should use avformat_open_input instead.

    From there, you can read properties out of the AVFormatContext: duration in some fractions of a second (see the docs), file_size in bytes, bit_rate, etc.

    So putting it together should look something like:

    AVFormatContext* pFormatCtx = avformat_alloc_context();
    avformat_open_input(&pFormatCtx, filename, NULL, NULL);
    int64_t duration = pFormatCtx->duration;
    // etc
    avformat_close_input(&pFormatCtx);
    avformat_free_context(pFormatCtx);
    

    If you have a file format with no headers, like MPEG, you may need to add this line after avformat_open_input to read information from the packets (which might be slower):

    avformat_find_stream_info(pFormatCtx, NULL);
    

    Edit:

    • Added allocation and de-allocation of pFormatCtx in the code example.
    • Added avformat_find_stream_info(pFormatCtx, NULL) to work with video types that have no headers such as MPEG
    0 讨论(0)
  • 2020-12-28 17:44
    AVFormatContext* pFormatCtx = avformat_alloc_context();
    

    will cause memory leak.

    it should be AVFormatContext* pFormatCtx = NULL

    0 讨论(0)
  • 2020-12-28 17:55

    I had to add a call to

    avformat_find_stream_info(pFormatCtx,NULL)
    

    after avformat_open_input to get mgiuca's answer to work. (can't comment on it)

    #include <libavformat/avformat.h>
    ...
    av_register_all();
    AVFormatContext* pFormatCtx = avformat_alloc_context();
    avformat_open_input(&pFormatCtx, filename, NULL, NULL);
    avformat_find_stream_info(pFormatCtx,NULL)
    int64_t duration = pFormatCtx->duration;
    // etc
    avformat_close_input(&pFormatCtx);
    avformat_free_context(pFormatCtx);
    

    The duration is in uSeconds, divide by AV_TIME_BASE to get seconds.

    0 讨论(0)
  • 2020-12-28 17:57

    used this function its working :

    extern "C"
    JNIEXPORT jint JNICALL
    Java_com_ffmpegjni_videoprocessinglibrary_VideoProcessing_getDuration(JNIEnv *env,
                                                                          jobject instance,
                                                                          jstring input_) {
        av_register_all();
        AVFormatContext *pFormatCtx = NULL;
        if (avformat_open_input(&pFormatCtx, jStr2str(env, input_), NULL, NULL) < 0) {
            throwException(env, "Could not open input file");
            return 0;
        }
    
    
        if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
            throwException(env, "Failed to retrieve input stream information");
            return 0;
        }
    
        int64_t duration = pFormatCtx->duration;
    
        avformat_close_input(&pFormatCtx);
        avformat_free_context(pFormatCtx);
        return (jint) (duration / AV_TIME_BASE);
    }
    

    When I m using (jint) (duration / AV_TIME_BASE) this video duration is getting wrong.

    0 讨论(0)
提交回复
热议问题