我需要一个库来执行基本函数,比如视频文件的长度、大小等(我猜是通过元数据或标签),所以我选择了ffmpeg。有效的视频格式主要是电影文件中常见的,例如wmv,wmvhd,avi,mpeg,mpeg-4等。如果可以,请帮我找到用于了解视频文件持续时间的方法。我是在Linux平台上操作。
libavcodec编程相当困难,而且查找文档也很困难,所以我理解你的痛苦。 这篇教程 是一个不错的开始。主要的API文档在 这里。
查询视频文件的主要数据结构是 AVFormatContext 。在教程中,它是使用 av_open_input_file
打开的第一件事--该函数已被弃用,应该使用 avformat_open_input 代替。
从那里,您可以从AVFormatContext中读取属性:duration
以某些秒分数表示(请参阅文档),file_size
以字节为单位,bit_rate
等。
因此,将它们整合起来应该看起来像:
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);
如果你有一个没有头文件的文件格式,比如MPEG,你可能需要在avformat_open_input
之后添加这行代码来读取数据包中的信息(这可能会更慢):
avformat_find_stream_info(pFormatCtx, NULL);
编辑:
avformat_find_stream_info(pFormatCtx, NULL)
,以便处理没有头文件的视频类型,例如MPEG。我不得不添加一个调用
avformat_find_stream_info(pFormatCtx,NULL)
在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);
持续时间以微秒为单位,除以AV_TIME_BASE可得到秒数。
使用了这个函数,它正常工作:
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);
}
当我使用 (jint) (duration / AV_TIME_BASE) 时,视频的持续时间会出错。
AVFormatContext* pFormatCtx = avformat_alloc_context();
会导致内存泄漏。
应该是 AVFormatContext* pFormatCtx = NULL
-lavformat -lavcodec
。您需要确保在命令行上将C文件放在链接器文件之前--最近发生了变化,我被咬了一口。如果这样不起作用,请使用objdump查找函数是否实际上在库中:objdump -T /usr/lib/libavformat.so | grep avformat_open_input
。 - mgiuca