how to use libavcodec/ffmpeg to find duration of video file
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. Valid video formats are primarily those prevalent in movie files viz. wmv, wmvhd, avi, mpeg, mpeg-4, etc. If you can, please help me with the method(s) to be used for knowing the duration the video file. I'm on a Linux platform.
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
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.
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.
AVFormatContext* pFormatCtx = avformat_alloc_context();
will cause memory leak.
it should be AVFormatContext* pFormatCtx = NULL
精彩评论