C++ 如何使用 libavcodec/ffmpeg 查找视频文件的时长
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6451814/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to use libavcodec/ffmpeg to find duration of video file
提问by Kunal Vyas
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.
我需要一个库来执行视频文件的长度、大小等基本功能(我是通过元数据或标签猜测的),所以我选择了ffmpeg。有效的视频格式主要是电影文件中流行的格式。wmv、wmvhd、avi、mpeg、mpeg-4等。如果可以,请帮助我了解用于了解视频文件时长的方法。我在Linux平台上。
回答by mgiuca
libavcodec is pretty hard to program against, and it's also hard to find documentation, so I feel your pain. This tutorialis a good start. Hereis the main API docs.
libavcodec 很难编程,而且也很难找到文档,所以我觉得你很痛苦。本教程是一个良好的开端。这是主要的 API 文档。
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_inputinstead.
查询视频文件的主要数据结构是AVFormatContext。在本教程中,这是您打开的第一件事,使用av_open_input_file
-- 文档说它已弃用,您应该改用avformat_open_input。
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.
从那里,您可以从 AVFormatContext 中读取属性:duration
在几分之一秒内(参见文档),file_size
以字节为单位bit_rate
,等等。
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):
如果您的文件格式没有标头,例如 MPEG,则可能需要在之后添加此行avformat_open_input
以从数据包中读取信息(这可能会更慢):
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
- 在代码示例中添加了 pFormatCtx 的分配和取消分配。
- 添加
avformat_find_stream_info(pFormatCtx, NULL)
用于处理没有标头的视频类型,例如 MPEG
回答by seeseac
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)
在avformat_open_input
得到 mgiuca 的工作答案之后。(无法评论)
#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.
持续时间以 uSeconds 为单位,除以 AV_TIME_BASE 得到秒。
回答by axita.savani
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.
当我使用 (jint) (duration / AV_TIME_BASE) 时,此视频持续时间出错了。
回答by John Li
AVFormatContext* pFormatCtx = avformat_alloc_context();
will cause memory leak.
会导致内存泄漏。
it should be AVFormatContext* pFormatCtx = NULL
它应该是 AVFormatContext* pFormatCtx = NULL