Подтвердить что ты не робот

Как использовать libavcodec/ffmpeg для поиска продолжительности видеофайла

Мне нужна библиотека для выполнения основных функций, таких как длина, размер и т.д. видеофайла (я угадываю метаданные или теги), поэтому я выбрал ffmpeg. Допустимыми форматами видео являются, прежде всего, распространенные в видеофайлах, а именно: wmv, wmvhd, avi, mpeg, mpeg-4 и т.д. Если вы можете, пожалуйста, помогите мне с помощью метода (ов), который будет использоваться для обозначения продолжительности видеофайла. Я на платформе Linux.

4b9b3361

Ответ 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