LINUX.ORG.RU

[libavformat]Иноформация о видеофайле


0

2

Всем доброго времени суток! Подскажите, как вытащить из видеофайла такую информацию, как разрешение, битрейт видео и аудио, кодеки, продолжительность, количество кадров в секунду с помощью libavformat? Пытался посмотреть документацию на офф сайте, но там черт ногу сломит.

★★★★★

В сорцах ffprobe посмотри.

anonymous
()

> разрешение, битрейт видео и аудио, кодеки, продолжительность, количество кадров в секунду

в метаданных кодеков и, тем более, в метаданных контейнера могут отсутствовать или быть некорректными.

const86 ★★★★★
()
Ответ на: комментарий от hippi90

Дык вот тот же ffprobe порой и показывает фигню, если файл неаккуратный попадётся. При этом всё может хорошо декодироваться, если таймстампы расставлены на пакетах правильно.

Более надёжный способ: тем же libavformat распарсить весь файл и посчитать суммарный размер пакетиков, максимальный таймстамп и дальше в том же духе.

const86 ★★★★★
()
Ответ на: комментарий от const86

А если где-нибудь нормальная документация по libavformat, а то на оффсайте нашел только описание сигнатур функций.

hippi90 ★★★★★
() автор топика
Ответ на: комментарий от hippi90

> нормальная документация по libavformat

Заголовочные файлы, исходники ffprobe, исходники самой либы. Разобраться можно, проверил на себе :)

const86 ★★★★★
()

> Пытался посмотреть документацию на офф сайте, но там черт ногу сломит.

и что же ты собрался писать с libav*, если даже такой мелочи не смог понять?

#include <stdio.h>

#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>

int main() {
    av_register_all();

    AVFormatContext *avc = NULL;
    if (av_open_input_file(&avc, "test.mkv", NULL, 0, NULL) < 0) {
        puts("av_close_input_file() failed.");
        return 1;
    }

    for (unsigned i = 0; i < avc->nb_streams; i++) {
        AVCodecContext *codec = avc->streams[i]->codec;
        AVCodec *dec = avcodec_find_decoder(codec->codec_id);
        if (!dec || avcodec_open(codec, dec) < 0)
            continue;

        switch (codec->codec_type) {
            case CODEC_TYPE_VIDEO:
                printf("%u. Video, %s, %dx%d\n", i, dec->name, codec->width, codec->height);
                break;

            case CODEC_TYPE_AUDIO:
                printf("%u. Audio, %s, %dx%d\n", i, dec->name, codec->sample_rate, codec->channels);
                break;

            default:
                break;
        }
        avcodec_close(codec);
    }

    av_close_input_file(avc);

    return 0;
}
arsi ★★★★★
()
Ответ на: комментарий от arsi

Увы, но я видимо избалован хорошей документацией, где всё по порядку и разложено по полочкам. Ни вменяемого туториала, ни какой-либо вменяемого мануала по основам библиотеки я не нашел. Структура AVCodecContext описана так: «main external API structure.», и всё, никаких пояснений, примеров, ничего. Описание струтуры представляет собой алфавитное перечисление её полей, отсутствует разбиение на функции, перечисления, поля данных. Описания к полям опять же состоят из двух-трех слов. По поводу поля AVCodecContext::codec_type в доках сказано буквально следующее (перечисление ссылок на полстраницы опущено):

enum AVMediaType AVCodecContext::codec_type
Definition at line 1149 of file avcodec.h.

Referenced by add_audio_stream(), add_av_stream()... and yuv4_read_header().
Это конечно очень многословно, и очень удобно за каждым определением лазить в заголовочные файлы.

При сборке вашего примера

gcc -o test test.c -std=c99 `pkg-config --cflags --libs libavformat libavcodec libavutil`
получается бинарник весом 30Мб, он что, статически линкует по умолчанию?

hippi90 ★★★★★
() автор топика
Ответ на: комментарий от hippi90

Структура AVCodecContext описана так: «main external API structure.», и всё, никаких пояснений, примеров, ничего. Описание струтуры представляет собой алфавитное перечисление её полей, отсутствует разбиение на функции, перечисления, поля данных.

В заголовочном файле описание этой структуры занимает почти две тысячи строк.

получается бинарник весом 30Мб, он что, статически линкует по умолчанию?

Зависит от содержимого `pkg-config --cflags --libs libavformat libavcodec libavutil`.

Deleted
()
Ответ на: комментарий от hippi90

> Структура AVCodecContext описана так: «main external API structure.», и всё, никаких пояснений, примеров, ничего.

как говорится, «кто хочет, тот ищет возможности, кто не хочет — ищет оправдания». ;)

AVCodecContext — имхо, более чем достаточное описание.

api-example.c — по названию ясно, что там внутри ;)

> При сборке вашего примера получается бинарник весом 30Мб, он что, статически линкует по умолчанию?

понятия не имею, что у вас за дистрибутив и кто для него собирал ffmpeg/libav. я под слаку64 собирал сам, динамическую. бинарник с такими либами весит 9355 байт (ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped). собирал мейкфайлом:

PREREQ = libavcodec libavformat

LIBS = $(shell pkg-config --libs $(PREREQ))
CFLAGS = -std=c99 -Wall -Wextra $(shell pkg-config --cflags $(PREREQ))

TARGET = fftest
OBJ = fftest.o

all: $(TARGET)

$(TARGET): $(OBJ)
        gcc $^ -o $@ $(LIBS)

clean:
        rm -f $(OBJ)

distclean: clean
        rm $(TARGET)
arsi ★★★★★
()
Ответ на: комментарий от arsi

С размерами бинарника разобрался. FFmpeg собирал сам из git, при сборке не указал --enable-shared, поэтому собраны были только статические библиотеки. Дальше я думаю, сам разберусь, спасибо всем за помощь!

hippi90 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.