【发布时间】:2011-09-21 01:30:59
【问题描述】:
我需要一个库来执行视频文件的长度、大小等基本功能(我是通过元数据或标签来猜测的),所以我选择了 ffmpeg。有效的视频格式主要是电影文件中流行的格式,即。 wmv、wmvhd、avi、mpeg、mpeg-4 等。如果可以,请帮助我了解视频文件的持续时间。我在 Linux 平台上。
【问题讨论】:
我需要一个库来执行视频文件的长度、大小等基本功能(我是通过元数据或标签来猜测的),所以我选择了 ffmpeg。有效的视频格式主要是电影文件中流行的格式,即。 wmv、wmvhd、avi、mpeg、mpeg-4 等。如果可以,请帮助我了解视频文件的持续时间。我在 Linux 平台上。
【问题讨论】:
libavcodec 很难编程,也很难找到文档,所以我感受到了你的痛苦。 This tutorial 是一个好的开始。 Here 是主要的 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【讨论】:
-lavformat -lavcodec 链接。您需要确保您的 C 文件出现在命令行上的链接器文件之前 -- this recently changed and I was bitten by it。如果这不起作用,请使用 objdump 找出函数是否真的在库中:objdump -T /usr/lib/libavformat.so | grep avformat_open_input.
我必须添加一个呼叫
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);
持续时间以 uSeconds 为单位,除以 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
【讨论】: