
Парсинг метаданных файлов RealMedia на Ассемблере

Парсинг метаданных файлов RealMedia на Ассемблере
Формат RealMedia уже давно используется для потокового вещания. В свое время этот формат обеспечивал приемлемое качество звука и видео при сравнительно небольшом размере файла. Но главным плюсом RealMedia является возможность перемотки при воспроизведении файлов, находящихся на сервере. Это обеспечило не только популярность, но сделало RealMedia практически стандартом для трансляции медиапотоков по каналам связи.
RealMedia является закрытым форматом, но некоторую документацию по внутренней структуре файлов все-таки удалось найти. В природе есть как минимум два формата файлов RealMedia - это контейнеры старого образца только для аудио и более современные контейнеры для аудио и видео. Сегодня разберем парсинг обоих форматов, начнем с аудио. Файл начинается с 4-байтной сигнатуры, это строка ".ra" и символ 0xFD. За сигнатурой следует WORD с версией файла. В природе встречаются версии 3 и 4, а заявленная 5-я версия не успела выйти в релиз. 3-я версия встречается крайне редко, но все-таки есть. Для определения корректности файла достаточно будет проверить его сигнатуру и подтвердить версию. Метаданные начинаются по фиксированному смещению 0x16 от начала файла. Метаданные могут иметь разный размер, но при этом их количество и порядок строго регламентированы: название композиции, исполнитель, информация об авторских правах и комментарий.

Метаданные в файле
Сами метаданные представляют собой четыре блока в формате: 1 байт длины строки и сразу за ним строка. Если какой-то информации нет, то в качестве длины строки записывается нулевой байт, а самой строки вообще нет. Соответственно, максимальная длина строки может быть не более 255 символов. Парсинг метаданных аудиофайлов в формате RealMedia версии 3 будет примерно следующим:
Code (Assembler) : Убрать нумерацию
- ; Прочитать начало файла
- invoke _lopen,fname,OF_READ
- mov [desc],eax
- invoke _lread,[desc],buff,500h
- invoke _lclose,[desc]
- ; Проверка на соответствие формата
- cmp dword[buff],0xFD61722E
- ; Неизвестный формат файла
- jne .loc_exit
- ; Проверка версии
- cmp byte[buff+5],3
- ; Не поддерживаемая версия файла
- jne .loc_exit
- ; Указатель на начало метаданных
- mov esi,buff+0x16
- ; Прочитать метаданные
- lodsb
- or al,al
- jz @f
- movzx ecx,al
- mov edi,title
- rep movsb
- @@:
- lodsb
- or al,al
- jz @f
- movzx ecx,al
- mov edi,artist
- rep movsb
- @@:
- lodsb
- or al,al
- jz @f
- movzx ecx,al
- mov edi,cright
- rep movsb
- @@:
- lodsb
- or al,al
- jz @f
- movzx ecx,al
- mov edi,comm
- rep movsb
- @@:
- ; title -> название композиции
- ; artist -> исполнитель
- ; cright -> информация об авторских правах
- ; comm -> комментарий

Метаданные в файле
Формат метаданных в точности совпадает с версий 3, они имеют такую же структуру. Парсинг метаданных аудиофайлов в формате RealMedia версии 4 будет примерно следующим:
Code (Assembler) : Убрать нумерацию
- ; Прочитать начало файла
- invoke _lopen,fname,OF_READ
- mov [desc],eax
- invoke _lread,[desc],buff,500h
- invoke _lclose,[desc]
- ; Проверка на соответствие формата
- cmp dword[buff],0xFD61722E
- ; Неизвестный формат файла
- jne .loc_exit
- ; Проверка версии
- cmp byte[buff+5],4
- ; Не поддерживаемая версия файла
- jne .loc_exit
- ; Дополнительная проверка версии
- cmp dword[buff+8],'.ra4'
- ; Не поддерживаемая версия файла
- jne .loc_exit
- ; Указатель на начало метаданных
- mov esi,buff+0x45
- ; Прочитать метаданные
- lodsb
- or al,al
- jz @f
- movzx ecx,al
- mov edi,title
- rep movsb
- @@:
- lodsb
- or al,al
- jz @f
- movzx ecx,al
- mov edi,artist
- rep movsb
- @@:
- lodsb
- or al,al
- jz @f
- movzx ecx,al
- mov edi,cright
- rep movsb
- @@:
- lodsb
- or al,al
- jz @f
- movzx ecx,al
- mov edi,comm
- rep movsb
- @@:
- ; title -> название композиции
- ; artist -> исполнитель
- ; cright -> информация об авторских правах
- ; comm -> комментарий

Метаданные в файле
Метаданные содержатся в контейнере с заголовком "CONT". Как и в предыдущем примере, они представляют собой четыре блока в формате: 2 байта длины строки и сразу за ним строка. Аналогично, если какой-то информации нет, то в качестве длины строки записывается нулевой WORD, а самой строки нет. Парсинг метаданных для этого формата заключается в последовательном переборе контейнеров и обработкой контейнера с заголовком "CONT":
Code (Assembler) : Убрать нумерацию
- ; Прочитать начало файла
- invoke _lopen,fname,OF_READ
- mov [desc],eax
- invoke _lread,[desc],buff,8
- ; Проверка на соответствие формата
- cmp dword[buff],'.RMF'
- ; Неизвестный формат файла
- jne .loc_exit
- ; Перейти на следующий контейнер
- mov eax,dword[buff+4]
- bswap eax
- sub eax,8
- invoke _llseek,[desc],eax,FILE_CURRENT
- .loc_read:
- invoke _lread,[desc],buff,8
- cmp eax,8
- jne .loc_close
- ; Это контейнер с описанием?
- cmp dword[buff],'CONT'
- je @f
- ; Перейти к следующему контейнеру
- mov eax,dword[buff+4]
- bswap eax
- sub eax,8
- invoke _llseek,[desc],eax,FILE_CURRENT
- jmp .loc_read
- @@:
- ; Размер метаданных
- mov ebx,dword[buff+4]
- bswap ebx
- ; Выделить память под метаданные
- invoke GlobalAlloc,GMEM_ZEROINIT,ebx
- mov [hMem],eax
- invoke GlobalLock,[hMem]
- mov [pMem],eax
- ; Прочитать метаданные
- sub ebx,8
- invoke _lread,[desc],[pMem],ebx
- ; Указатель на начало метаданных
- mov esi,[pMem]
- lodsw
- ; Прочитать метаданные
- lodsw
- or ax,ax
- jz @f
- xchg al,ah
- movzx ecx,ax
- mov edi,title
- rep movsb
- @@:
- lodsw
- or ax,ax
- jz @f
- xchg al,ah
- movzx ecx,ax
- mov edi,artist
- rep movsb
- @@:
- lodsw
- or ax,ax
- jz @f
- xchg al,ah
- movzx ecx,ax
- mov edi,cright
- rep movsb
- @@:
- lodsw
- or ax,ax
- jz @f
- xchg al,ah
- movzx ecx,ax
- mov edi,comm
- rep movsb
- @@:
- ; title -> название композиции
- ; artist -> исполнитель
- ; cright -> информация об авторских правах
- ; comm -> комментарий
Просмотров: 393 | Комментариев: 2
Метки: Assembler, мультимедиа

Комментарии
Отзывы посетителей сайта о статье
ManHunter
(01.11.2024 в 20:34):
Класс, дополнил статью 3-й версией. фанат, спасибо!

фанат
(01.11.2024 в 06:58):

Добавить комментарий
Заполните форму для добавления комментария
