Работа с метаданными MP3-файлов на Ассемблере
Работа с метаданными MP3-файлов на Ассемблере
Во многих файлах, в частности музыкальных и видео, присутствуют особые блоки данных, так называемые метаданные или теги. Метаданные содержат информацию о названии композиции и альбома, имени исполнителя, жанре, номере трека и т.п. Их используют программные и аппаратные проигрыватели, каталогизаторы и другие средства для работы с мультимедийными файлами. Давайте посмотрим, как можно получить теги из MP3-файла или изменить их средствами самой системы без ручного парсинга внутренней структуры файла.
Начиная с Windows Vista, для работы с метаданными файлов используется интерфейс IPropertyStore. Нам понадобится GUID и описание интерфейса, а также несколько структур и констант, о которых не знает FASM.
Code (Assembler) : Убрать нумерацию
- struct PROPVARIANT
- vt dw ?
- wReserved rw 3
- struct
- cbSize dd ?
- pBlobData dd ?
- ends
- ends
- struct PROPKEY
- fmtid rb 16
- pid dd ?
- ends
- GPS_READWRITE = 2
- VT_BSTR = 8
- ; GUID {886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99}
- IID_IPropertyStore dd 0886D8EEBh
- dw 08CF2h
- dw 04446h
- db 08Dh, 002h, 0CDh, 0BAh, 01Dh, 0BDh, 0CFh, 099h
- ; IID_IPropertyStore Interface
- struct IPropertyStore
- ; IUnknown
- QueryInterface dd ? ; 000h
- AddRef dd ? ; 004h
- Release dd ? ; 008h
- ; IPropertyStore
- GetCount dd ? ; 00Ch
- GetAt dd ? ; 010h
- GetValue dd ? ; 014h
- SetValue dd ? ; 018h
- Commit dd ? ; 01Ch
- ends
Code (Assembler) : Убрать нумерацию
- ; GUID {F29F85E0-4FF9-1068-AB91-08002B27B3D9}
- PKEY_Title dd 0F29F85E0h
- dw 04FF9h
- dw 01068h
- db 0ABh, 091h, 008h, 000h, 02Bh, 027h, 0B3h, 0D9h
- PKEY_Title_pid = 2
- ; GUID {56A3372E-CE9C-11D2-9F0E-006097C686F6}
- PKEY_Music_AlbumTitle dd 056A3372Eh
- dw 0CE9Ch
- dw 011D2h
- db 09Fh, 00Eh, 000h, 060h, 097h, 0C6h, 086h, 0F6h
- PKEY_Music_AlbumTitle_pid = 4
- ; GUID {56A3372E-CE9C-11D2-9F0E-006097C686F6}
- PKEY_Music_Artist dd 056A3372Eh
- dw 0CE9Ch
- dw 011D2h
- db 09Fh, 00Eh, 000h, 060h, 097h, 0C6h, 086h, 0F6h
- PKEY_Music_Artist_pid = 2
- ; GUID {64440490-4C8B-11D1-8B70-080036B11A03}
- PKEY_Media_Duration dd 064440490h
- dw 04C8Bh
- dw 011D1h
- db 08Bh, 070h, 008h, 000h, 036h, 0B1h, 01Ah, 003h
- PKEY_Media_Duration_pid = 3
Code (Assembler) : Убрать нумерацию
- invoke CoInitialize,0
- ; Получить полный путь к файлу
- invoke GetFullPathName,sample,MAX_PATH,fname,NULL
- ; Получить интерфейс IPropertyStore
- invoke SHGetPropertyStoreFromParsingName,fname,\
- NULL,GPS_READWRITE,IID_IPropertyStore,pStore
Code (Assembler) : Убрать нумерацию
- ; Исполнитель
- mov edi,prop.fmtid
- mov esi,PKEY_Music_Artist
- movsd
- movsd
- movsd
- movsd
- mov [prop.pid],PKEY_Music_Artist_pid
- mov eax,[pStore]
- mov eax,[eax]
- stdcall [eax+IPropertyStore.GetValue],[pStore],prop,variant
- ; [variant.cbSize] - количество строк в мультистроковом параметре
- ; или 0, если тег не заполнен
- ; [variant.pBlobData] - указатель на указатель на строку с названием
- ; исполнителя, но только если значение [variant.cbSize] больше 0
- cmp [variant.cbSize],0
- je @f
- mov eax,[variant.pBlobData]
- mov eax,[eax]
- ; EAX = указатель на строку с названием исполнителя
- @@:
- ; Название альбома
- mov edi,prop.fmtid
- mov esi,PKEY_Music_AlbumTitle
- movsd
- movsd
- movsd
- movsd
- mov [prop.pid],PKEY_Music_AlbumTitle_pid
- mov eax,[pStore]
- mov eax,[eax]
- stdcall [eax+IPropertyStore.GetValue],[pStore],prop,variant
- ; [variant.cbSize] - указатель на строку названия альбома
- ; или 0, если тег не заполнен
- ; Название трека
- mov edi,prop.fmtid
- mov esi,PKEY_Title
- movsd
- movsd
- movsd
- movsd
- mov [prop.pid],PKEY_Title_pid
- mov eax,[pStore]
- mov eax,[eax]
- stdcall [eax+IPropertyStore.GetValue],[pStore],prop,variant
- ; [variant.cbSize] - указатель на строку названия композиции
- ; или 0, если тег не заполнен
- ; Длительность
- mov edi,prop.fmtid
- mov esi,PKEY_Media_Duration
- movsd
- movsd
- movsd
- movsd
- mov [prop.pid],PKEY_Media_Duration_pid
- mov eax,[pStore]
- mov eax,[eax]
- stdcall [eax+IPropertyStore.GetValue],[pStore],prop,variant
- mov eax,[variant.cbSize]
- ; Длительность композиции возвращается в 100-наносекундных значениях
- ; ее надо преобразовать в обычные секунды
- xor edx,edx
- mov ecx,10000000
- div ecx
- ; EAX = длительность композиции в секундах
Code (Assembler) : Убрать нумерацию
- ; GUID {56A3372E-CE9C-11D2-9F0E-006097C686F6}
- PKEY_Music_Artist dd 056A3372Eh
- dw 0CE9Ch
- dw 011D2h
- db 09Fh, 00Eh, 000h, 060h, 097h, 0C6h, 086h, 0F6h
- PKEY_Music_Artist_pid dd 2
- ...
- ...
- mov eax,[pStore]
- mov eax,[eax]
- stdcall [eax+IPropertyStore.GetValue],[pStore],PKEY_Music_Artist,variant
Code (Assembler) : Убрать нумерацию
- ; Заменить тег
- mov edi,prop.fmtid
- mov esi,PKEY_Music_AlbumTitle
- movsd
- movsd
- movsd
- movsd
- mov [prop.pid],PKEY_Music_AlbumTitle_pid
- ; Заполнить структуру для обычной строки
- mov [variant.vt],VT_BSTR
- mov [variant.cbSize],szNew
- mov [variant.pBlobData],0
- ; Установить новое значение тега
- mov eax,[pStore]
- mov eax,[eax]
- stdcall [eax+IPropertyStore.SetValue],[pStore],prop,variant
- ; Сохранить изменения
- mov eax,[pStore]
- mov eax,[eax]
- stdcall [eax+IPropertyStore.Commit],[pStore]
После получения или изменения тегов не забываем освобождать задействованные ресурсы:
Code (Assembler) : Убрать нумерацию
- ; Прибраться за собой
- mov eax,[pStore]
- mov eax,[eax]
- stdcall [eax+IPropertyStore.Release],[pStore]
- invoke CoUninitialize
Просмотров: 1081 | Комментариев: 5
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(17.03.2022 в 13:07):
Как выяснилось еще, в некоторых случаях функция возвращает неправильное значение длительности композиции. Готовлю статью про ручной парсинг внутренней структуры MP3.
ManHunter
(02.02.2022 в 15:09):
Как выяснилось, функция некорректно работает в том случае, если в значении тега присутствует символ "/", например, группа "To/Die/For" возвращается как "To". Причина кроется где-то в глубине системы.
Вот статья про ручной парсинг метаданных: https://www.manhunter.ru/assem...emblere.html
Вот статья про ручной парсинг метаданных: https://www.manhunter.ru/assem...emblere.html
ManHunter
(24.11.2021 в 13:20):
Эпоха потребления, увы.
Grey
(24.11.2021 в 13:18):
140 просмотров и тишина..., блин да это шедевр.
Кэп, по моему, ты давно переплюнул уроки Iczelion'а. Этот раздел в твоем блоке просто бриллиант!!!
Спасибо тебе человеческое за твою огромную многолетнюю кропотливую работу!
Кэп, по моему, ты давно переплюнул уроки Iczelion'а. Этот раздел в твоем блоке просто бриллиант!!!
Спасибо тебе человеческое за твою огромную многолетнюю кропотливую работу!
Grey
(23.11.2021 в 08:56):
Аплодисменты!
Добавить комментарий
Заполните форму для добавления комментария