Мне нужна библиотека для выполнения основных функций, таких как длина, размер и т.д. видеофайла (я угадываю метаданные или теги), поэтому я выбрал ffmpeg. Допустимыми форматами видео являются, прежде всего, распространенные в видеофайлах, а именно: wmv, wmvhd, avi, mpeg, mpeg-4 и т.д. Если вы можете, пожалуйста, помогите мне с помощью метода (ов), который будет использоваться для обозначения продолжительности видеофайла. Я на платформе Linux.
Как использовать libavcodec/ffmpeg для поиска продолжительности видеофайла
Ответ 1
С 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);
Изменить:
- В примере кода добавлено распределение и перераспределение pFormatCtx.
- Добавлен
avformat_find_stream_info(pFormatCtx, NULL)
для работы с типами видео, которые не имеют заголовков, таких как MPEG
Ответ 2
Мне пришлось добавить вызов
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, чтобы получить секунды.
Ответ 3
использовал эту функцию свою работу:
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), продолжительность этого видео становится неправильной.
Ответ 4
AVFormatContext* pFormatCtx = avformat_alloc_context();
приведет к утечке памяти.
он должен быть AVFormatContext* pFormatCtx = NULL