Формат mp4-файла

Тема в разделе "WASM.BEGINNERS", создана пользователем Mikl___, 10 дек 2019.

  1. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.708
    Добрый вечер!
    Как и где в заголовке mp4 найти длительность видео?
     
  2. q2e74

    q2e74 Active Member

    Публикаций:
    0
    Регистрация:
    18 окт 2018
    Сообщения:
    988
    а разве мп4 не контейнер? наверно смещение до поля длинны в разных местах лежит, но это не точно. Наверно проще одно видео ffmpeg с разными кодеками mpeg2 или mpeg4 сделать и проверить заголовки.
    из рускоязычных вроде есть в эл.виде книга "цифровые видеоинформационные системы(теория и практика)" Дворкович. Там вроде было подробно расписано.
     
  3. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.953
    Установить в 010editor шаблон mp4 и посмотреть в шаблоне, либо порыться в тексте шаблона. Как я понял, там есть структуры sbox, если отпарсить среди них sbox'ы с нужной сигнатурой, одно из полей структуры будет duration.
    [​IMG]
    Код (Text):
    1. //------------------------------------------------
    2. //--- 010 Editor v6.0.2 Binary Template
    3. //
    4. //      File: MP4.bt
    5. //   Authors: Marian Denes
    6. //   Version: 2.2
    7. //   Purpose: Defines a template for parsing MP4 and MOV video files.
    8. //  Category: Video
    9. // File Mask: *.mp4,*.mov,*.m4v
    10. //  ID Bytes: [+4] 66 74 79 70, [+4] 6D 6F 6F 76, [+4] 6D 64 61 74
    11. //   History:
    12. //   2.2   2016-01-29 SweetScape: Updated header for repository submission.
    13. //   2.1   2015-06-04 M Denes: Public release.
    14. //------------------------------------------------
    15.  
    16. BigEndian();
    17.  
    18. local int64 pos;
    19. local int64 pos2;
    20.  
    21. typedef union {
    22.         /*uint number;*/
    23.         char text[4];
    24.     }  _typ;
    25.  
    26. string typeFullName(_typ& type) {
    27.     if (Memcmp(type.text, "ftyp", 4) == 0) return "File type compatibility box";
    28.     if (Memcmp(type.text, "mvhd", 4) == 0) return "Movie header box";
    29.     if (Memcmp(type.text, "iods", 4) == 0) return "Initial object descriptor box";
    30.     if (Memcmp(type.text, "trak", 4) == 0) return "Track box";
    31.     if (Memcmp(type.text, "udta", 4) == 0) return "Uset data box";
    32.     if (Memcmp(type.text, "mdat", 4) == 0) return "Movie (sample) data box";
    33.     if (Memcmp(type.text, "moov", 4) == 0) return "Moovie box";
    34.     if (Memcmp(type.text, "tkhd", 4) == 0) return "Track header box";
    35.     if (Memcmp(type.text, "mdia", 4) == 0) return "Media box";
    36.     if (Memcmp(type.text, "edts", 4) == 0) return "Edit box";
    37.     if (Memcmp(type.text, "elst", 4) == 0) return "Edit list";
    38.     return "I don't know the full name";
    39.     }
    40.  
    41. string typeString(_typ& type) {
    42.     return "Type of the box: \"" + type.text + "\"";
    43. }
    44.  
    45. // MessageBox(idOk, "", "GetCursorPos == %d", GetCursorPos());
    46.  
    47. while(FTell() < FileSize() - 1) {
    48.     struct _box {
    49.         uint size <hidden=true>;
    50.         _typ type <bgcolor=cLtRed, fgcolor=cWhite, name="Box Type", open=false,
    51.                    name   =typeString/*, comment=typeFullName*/>;
    52.         if (Memcmp(type.text, "ftyp", 4) == 0) {
    53.             char major_brand[4] <bgcolor=cDkGreen, fgcolor=cWhite, name="Major brand"> ;
    54.             char minor_ver  [4] <bgcolor=cDkBlue,  fgcolor=cWhite, name="Minor version"> ;
    55.             uint comp_brands[(size - sizeof(size)      - sizeof(type) - sizeof(major_brand) -
    56.                                     sizeof(minor_ver)) / 4] <name    = "Compatible brands",
    57.                                                              comment = brandName, open=true>;
    58.         } else if (Memcmp(type.text, "moov", 4) == 0) {
    59.             pos = FTell();
    60.             while(FTell() < pos + size - sizeof(size) - sizeof(type))
    61.                 struct _box2 {
    62.                     uint size <hidden=true>;
    63.                     _typ type <bgcolor=cLtRed, fgcolor=cWhite, name="Box Type", open=false,
    64.                                name   =typeString/*, comment=typeFullName*/>;
    65.                     if (Memcmp(type.text, "mvhd", 4) == 0) {
    66.                             char version  <hidden=true>;
    67.                             char flags[3] <hidden=true>;
    68.                             uint crTime   <bgcolor=cLtGreen, fgcolor=cBlack, name="Creation Time",     open=false>;
    69.                             uint mdTime   <bgcolor=cPurple,  fgcolor=cWhite, name="Modification Time", open=false>;
    70.                             uint tmScale  <name="Time scale",comment="Number of units per 1 second">;
    71.                             uint duration <name="Duration",  comment="In units defined in the previous field">;
    72.                             char rest[size - sizeof(size)    - sizeof(type)   - sizeof(version) -
    73.                                              sizeof(flags)   - sizeof(crTime) - sizeof(mdTime) -
    74.                                              sizeof(tmScale) - sizeof(duration)];
    75.                     } else if (Memcmp(type.text, "trak", 4) == 0) {
    76.                             pos2 = FTell();
    77.                             while(FTell() < pos2 + size - sizeof(size) - sizeof(type))
    78.                                 struct _box3 {
    79.                                     uint size <hidden=true>;
    80.                                     _typ type <bgcolor=cLtRed,   fgcolor=cWhite, name="Box Type", open=false,
    81.                                                name   = typeString/*, comment=typeFullName*/>;
    82.                                     if (Memcmp(type.text, "tkhd", 4) == 0) {
    83.                                             char version  <hidden=true>;
    84.                                             char flags[3] <hidden=true>;
    85.                                             uint crTime   <bgcolor=cLtGreen, fgcolor=cBlack, name="Creation Time",     open=false>;
    86.                                             uint mdTime   <bgcolor=cPurple,  fgcolor=cWhite, name="Modification Time", open=false>;
    87.                                             uint trkID    <                                  name="Track ID",          open=false>;
    88.                                             uint reserv   <hidden = true,                    name="Reserved">;
    89.                                             uint duration <                                  name="Duration",          open=false>;
    90.                                             char rest[size - sizeof(size)  - sizeof(type)   - sizeof(version) -
    91.                                                              sizeof(flags) - sizeof(crTime) - sizeof(mdTime)  -
    92.                                                              sizeof(trkID) - sizeof(reserv) - sizeof(duration)];
    93.                                     } else if (Memcmp(type.text, "edts", 4) == 0) {
    94.                                             struct _box4 {
    95.                                                 uint size <hidden=true>;
    96.                                                 _typ type <bgcolor=cLtRed,   fgcolor=cWhite, name="Box Type", open=false,
    97.                                                            name   = typeString>;
    98.                                                 char version  <hidden=true>;
    99.                                                 char flags[3] <hidden=true>;
    100.                                                 uint entrs<name   ="Number of entries">;
    101.                                                 struct {
    102.                                                     uint trDuration <name="Track duration">;
    103.                                                     uint mediaTime  <name="Media time">;
    104.                                                     uint mediaRate  <name="Media rate">;
    105.                                                 } entry[entrs] <open=true>;
    106.                                             } box <optimize=false, open=true, comment=boxName4>;
    107.                                     } else
    108.                                         char rest[size - sizeof(size) - sizeof(type)];
    109.                                 } box <optimize=false, open=true, comment=boxName3>;
    110.                     } else
    111.                         char rest[size - sizeof(size) - sizeof(type)];
    112.                     } box <optimize=false, open=true, comment=boxName2>;
    113.         } else
    114.             char rest[size - sizeof(size) - sizeof(type)];
    115.         } box <optimize=false, open=true, comment=boxName>;
    116. }
    117.  
    118. string boxName(_box& box) {
    119.     return box.type.text + " (" + typeFullName(box.type) + ")";;
    120. }
    121.  
    122. string boxName2(_box2& box) {
    123.     return box.type.text + " (" + typeFullName(box.type) + ")";
    124. }
    125.  
    126. string boxName3(_box3& box) {
    127.     return box.type.text + " (" + typeFullName(box.type) + ")";
    128. }
    129.  
    130. string boxName4(_box4& box) {
    131.     return box.type.text + " (" + typeFullName(box.type) + ")";
    132. }
    133.  
    134. string brandName(uint brand) {
    135.     local char text[4];
    136.     local int  i;
    137.  
    138.     for (i = 0; i < 4; ++i)
    139.         text[i] = brand >> 8 * (3 - i)  &  0xFF;
    140.     return text;
    141. }
    142.  
    143. // string boxName5(_box5& box) {
    144. //     return box.type.text + " (" + typeFullName(box.type) + ")";
    145. // }
    146.  
    147. // local int i;
    148.  
    149. // struct DATABLOCK {
    150. //     int dataID;
    151. //     uchar dataArray[16];
    152. // };
    153.  
    154.  
    155. // pos = FTell(); // save read position
    156. // for( i = 0; i < 4; i++ ) {
    157. //     DATABLOCK data <read=ReadDataBlock>;
    158. // }
    159. // FSeek( pos );  // restore read position
    160. //
    161. // // Custom read function
    162. // string ReadDataBlock( DATABLOCK &d )
    163. // {
    164. // //    string str;
    165. // //    SPrintf( str, "ID = '%d'", d.dataID );
    166. //     FTell( box[i].type] );
    167. //     return str;
    168. // }
    169.  
     
  4. q2e74

    q2e74 Active Member

    Публикаций:
    0
    Регистрация:
    18 окт 2018
    Сообщения:
    988
    f13nd, вопрос в сторону про редакторы и шаблоны.... какие самые богатые? какие наиболее полезные?(понимаю, что все относительно, но у ваших знакомых как? ведь у каждого человека при посещении психотерапевта появляется хорошо знакомый друг :) )
     
  5. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.953
    Ну я этот редактор выбрал, за то что это почти клон нех воркшопа, но больше функционалу и есть возможность скрипты для него писать. Шаблоны стандартных форматов файлов это так, бонус просто.
     
  6. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.708
    q2e74,
    да, мп4 это контейнер, но разрешение экрана находится всегда на одном и том же месте, за Дворковича, спасибо, попробую найти.
    f13nd,
    спасибо, если я правильно понял, duration нужно искать рядом с сигнатурой "tkhd"
     
  7. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.953
    Наверное правильней всего именно парсить файл, а не искать в нем 4байта.