Проверка на mp4-контейнер по расширению

Модератор: Модераторы разделов

Ответить
Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Проверка на mp4-контейнер по расширению

Сообщение alkesta »

Нужна пердварительная проверка на наличие расширения : m4a, M4A, mpeg4, MP4 и т.п.

Проверяю на наличие цифры 4:

Код: Выделить всё

gboolean is_mp4_extension (gchar* uri) {

    gchar *ext = strrchr(uri, '.');
    gshort i;

    for( i = 0; ext[i] != '\0'; i++ ) {
        if (ext[i] == '4')
                return TRUE;
    }
    return FALSE;
}

или есть более элегантное и простое решение?
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Проверка на mp4-контейнер по расширению

Сообщение Bizdelnick »

Полагаться на «расширение» — последнее дело. Используйте libmagic.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
frp
Сообщения: 1445
ОС: Debian Squeeze

Re: Проверка на mp4-контейнер по расширению

Сообщение frp »

----
Последний раз редактировалось frp 13.08.2021 19:44, всего редактировалось 1 раз.
Спасибо сказали:
Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Re: Проверка на mp4-контейнер по расширению

Сообщение alkesta »

Как-то так получилось:

Код: Выделить всё

gboolean is_mp4_container (gchar* uri) {

    const gchar mp4header[8] = {0x00, 0x00, 0x00, 0x1C, 0x66, 0x74, 0x79, 0x70};
    gchar header[8];
    gshort i = 0;
    FILE *file = NULL;

    file = fopen (
        g_filename_from_uri ( uri, NULL, NULL ),
        "rb" );

    if (file) {
        for ( i = 0; i < 8; i++ ) {
            fread ( &header[i], 1, 1, file );
            if ( mp4header[i] != header[i] ) {
                fclose ( file );
                return FALSE;
            }
        }
        fclose ( file );
        return TRUE;
    }
    return FALSE;
}
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Проверка на mp4-контейнер по расширению

Сообщение Bizdelnick »

alkesta писал(а):
12.12.2016 01:17

Код: Выделить всё

    const gchar mp4header[8] = {0x00, 0x00, 0x00, 0x1C, 0x66, 0x74, 0x79, 0x70};

А Вы уверены, что таким образом выявите все нужные контейнеры? MPEG4 — весьма упоротый формат, меджика как такового в нём не предусмотрено. В libmagic для его определения читают строки со смещением 4 и 8 байт, и возможных комбинаций довольно много.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
s.xbatob
Сообщения: 1139
ОС: Fedora

Re: Проверка на mp4-контейнер по расширению

Сообщение s.xbatob »

У mp4 есть обязательный заголовок? Он же формально потоковый формат и должен декодироваться с любой точки.
В любом случае это медиаконтейнер, внутри которого может если не что попало, но много разных каналов в разных форматах.
Спасибо сказали:
Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Re: Проверка на mp4-контейнер по расширению

Сообщение alkesta »

Bizdelnick писал(а):
12.12.2016 12:28
alkesta писал(а):
12.12.2016 01:17

Код: Выделить всё

    const gchar mp4header[8] = {0x00, 0x00, 0x00, 0x1C, 0x66, 0x74, 0x79, 0x70};

А Вы уверены, что таким образом выявите все нужные контейнеры? MPEG4 — весьма упоротый формат, меджика как такового в нём не предусмотрено. В libmagic для его определения читают строки со смещением 4 и 8 байт, и возможных комбинаций довольно много.

На сколько я понял, первые 8 как раз и определяют quicktime-контейнер, что мне и нужно, а следующие уже определяют конкретные подвиды - m4v, m4a, 3gp и т.п. Или я ошибаюсь?

пс
проверка нужна для избежания скармливания не mp4-файла библиотеке libmp4v2.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Проверка на mp4-контейнер по расширению

Сообщение Bizdelnick »

Ошибаетесь. Первые 4 байта вообще не проверяются и фиг знает, что там может быть. Следующие 4 "ftyp" соответствуют ISO base media file format, то есть MPEG-4 Part 12, или Apple QuickTime.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Re: Проверка на mp4-контейнер по расширению

Сообщение alkesta »

Bizdelnick писал(а):
12.12.2016 13:47
Ошибаетесь. Первые 4 байта вообще не проверяются и фиг знает, что там может быть. Следующие 4 "ftyp" соответствуют ISO base media file format, то есть MPEG-4 Part 12, или Apple QuickTime.


Можно подробнее про первые 4 байта.

Тут написано http://www.file-recovery.com/mp4-signature-format.htm
First block size is 28 (hex: 00 00 00 1C, big-endian, high byte first), size located at offset 0. At offset 28 (hex: 1C) is located the second chunk, which has a size of 8 and type mdat (hex: 6D 64 61 74) 

Т.е. там не может быть что угодно, как я понимаю.


4 байта ftyp сравнить будет достаточно?



Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Проверка на mp4-контейнер по расширению

Сообщение Bizdelnick »

alkesta писал(а):
12.12.2016 14:14
Можно подробнее про первые 4 байта.

Подробнее написать не могу, потому что доступа к спецификации у меня нет. Есть только rfc4337, где написано
Magic number(s): none
и есть libmagic, куда детекцию этого формата добавляли, я надеюсь, люди, спецификацию таки читавшие.

alkesta писал(а):
12.12.2016 14:14
Тут написано http://www.file-recovery.com/mp4-signature-format.htm
First block size is 28 (hex: 00 00 00 1C, big-endian, high byte first), size located at offset 0. At offset 28 (hex: 1C) is located the second chunk, which has a size of 8 and type mdat (hex: 6D 64 61 74)

Т.е. там не может быть что угодно, как я понимаю.

Процитированный Вами текст относится к конкретному образцу, а не к формату в целом. Из общего описания, несколько выше, следует, что первые 4 байта содержат размер первого фрагмента данных, и никто вроде не обещает, что он не может отличаться от приведённого в примере.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
alkesta
Сообщения: 345
ОС: Fedora

Re: Проверка на mp4-контейнер по расширению

Сообщение alkesta »

Bizdelnick писал(а):
12.12.2016 13:47
Ошибаетесь. Первые 4 байта вообще не проверяются и фиг знает, что там может быть. Следующие 4 "ftyp" соответствуют ISO base media file format, то есть MPEG-4 Part 12, или Apple QuickTime.

Посмотрел имеющиеся файлы:

Код: Выделить всё

00 00 00 20 | 66 74 79 70 | 69 73 6F 6D  ... ftypisom  # movie.mp4
00 00 00 1C | 66 74 79 70 | 6D 70 34 32  ....ftypmp42  # movie.mp4
00 00 00 18 | 66 74 79 70 | 6D 70 34 32  ....ftypmp42  # movie.3gp
00 00 00 20 | 66 74 79 70 | 71 74 20 20   ...ftypqt    # movie.mov
00 00 00 18 | 66 74 79 70 | 4D 34 41 20  ....ftypM4A   # music.m4a
00 00 00 1C | 66 74 79 70 | 4D 34 41 20  ....ftypM4A   # abook.m4b

FF FB A0 64 | 00 00 00 00 | 00 00 00 00  ...d........  # music.mp3
66 4C 61 43 | 00 00 00 22 | 12 00 12 00  fLaC..."....  # music.flac

Вы как всегда правы! :)

Код: Выделить всё

gboolean is_mp4_container (gchar* uri) {

    const gchar mp4ftyp[4] = {0x66, 0x74, 0x79, 0x70};
    gchar typ[4];
    gshort i = 0;
    FILE *file = NULL;

    file = fopen (
        g_filename_from_uri (uri, NULL, NULL),
        "rb" );

    if ( file ) {
        fseek ( file, 4, SEEK_SET );
        for ( i = 0; i < 4; i++ ) {
            fread ( &typ[i], 1, 1, file );
            if ( mp4ftyp[i] != typ[i] ) {
                fclose ( file );
                return FALSE;
            }
        }
        fclose ( file );
        return TRUE;

    }
    return FALSE;
}
Спасибо сказали:
Ответить