Как на самом деле плохо запроектированы вокруг нас вещи, на примере формата MP3

Sep 19, 2013 00:57


В общем-то всего спроектировать и построить правильно нельзя с первого раза нельзя. Ну вот вообще ничего... Что там говорить о сложных конструкторских решениях двигателей или архитектурных сооружений, взять простейший пример: MP3 файлы, к которым мы уже привыкли как к родным и слушаем уже с десяток лет. MP3 тот самый злейший убийца AUDIO CD!

Нам кажется, что так просто кинул *.mp3 файл себе в плэйер (я не считаю мерзкий тунец плэйером) и тут же вместо 06-pope-burn-in-hell.mp3 становится для вас например: Slayer - Reign in Blood (thrash-metal). То есть "магическим" образом ваш плэйер узнает какая великая группа играет какую песню в каком году и на каком альбоме + даже стиль. Многие уже просекли слово "тэги", да это просто кто-то из цифровавших диск задал описание и теперь они лежат внутри файла. Где-то и как-то внутри, ну вы поняли.

Вот тут и подошли к самому интересному. Я тут немного попилил и думал, что закончу за пару часов одно дельце, но затянулось это на 2 дня с переменным успехом конечно на нормальную работу. Занимался я тем, что пытался восстановить как же внутри mp3 файла хранится эта самая информация, были проблемы что сайт id3.org лежит и пришлось читать его через вебархив.

И тут про "проектирование" формата мне открылись его больные места. Напомню, что еще Билл Гейтсу приписываемые слова при выпуске его MS-DOS звучали: "640 kb хватит всем".
Это как бы фэйл. Но видимо фэйлы никого не учат. Берем лопату в виде hex редактора и копаем в историю mp3 формата.

id3

Вот предумали гении формат сжатия, устроили ему контейнер и назвали mp3 пусть это возможно не исторически верно, но все же.
Решили положить туда информацию внутрь, тэги, это Артиста, Название песни, Альбом, Год, Жанр, Комментарий.
И тут решили, что 128 байт хватит, ну и выделили с конца файла те самые 128 байт, по 30 байт на текстовые а-ля Название, Артиста, Альбом, на Жанр числовой код в 2 байтика и Комментарию еще 30. Туда сюда, вот и 128 байтиков.
И ведь жеж понятно, ну что такое 30 байт? ОК, это 30 букв в стандартной например ASCII кодировке, а и но! Ведь весь мир не анлоязычен, есть море языков от самого распространенного испанского до русского, китайского и прочих. Сразу урезаем до 15 символов при UTF-8 и в худжем случае до 7-8 при UTF-16. 7 - букв (иерогливоф) на название песни вы представляете? Я тоже, считаю это мало, очень мало...

id3v1

Гениальные инженегры ничего более глупого не придумывают как ввести еще один блок, расширяющий предыдущий id3 и называют его id3v1 дают туда 227 байт и засовывают опять от конца файла перед тем блоком, итого fseek где-то -(227+128) выходит. И опять мало!
Да и ладно бы мало, появляется еще одна неучтенная при проектировании проблема - потоки! Да, музыку начинают слушать по сети и как вы пониманиете в нашем случае чтобы узнать какая это песня и кто поет, нам надо дождаться пока весь mp3 файл скачается и тогда можно будет заглянуть ему под "хвост". Это плохо, очень плохо.

id3v2.3 - id3v2.4

И тогда придумывают опять новый формат хранения тэгов внутри бедных mp3 файлов. Теперь это блок неограниченного размера, начинается сначала и подразумевает внутреннюю кодировку с запасом на японцев (UTF-16). Там все просто в общем-то в начале файла 10 байт заголовок, по нему мы определяем это тэговый блок (сигнатура ID3 в самом начале файла скорее всего говорит, что это mp3), дальше типа минорная и мажорная версия по байту, потом общий размер блока. А дальше пошли простые структурки фрэймов или тэгов: 4 байта на идиотские название, например APIC или TIT2 с ходу хрен догадаешься, но это attachment picture и title почему 2 я не знаю. Дальше 4 байта на размер текстового значения (V_SIZE), 2 байта на служебный флаг и 1 байт на указание кодировки текста, а потом уже сам текст размером V_SIZE байт. Все просто в общем-то, но...

Чем 2.3 от 2.4 отличается я не шибко уловил, только, что добавили возможность вкладывать в mp3 файл картинку - это раз (!!!) и лирику песни - это два.

Чем и тут я недоволен в проектировании?
- Может быть конечно это удобно когда скачал один файл mp3, а у тебя внутри и картинка и текст, текст ладно пусть будет. Но картинка?! Вы понимаете, что если у вас альбом лежит в папочке, а там 13 песен, а в каждой песне еще по 500кб. png картинка (а размер не редкость), то ведь это почти на 7 мб. больше пришлось бы качать по модему, трафик. Конечно винты большие, скорости дикие и "ВСЕМ ХВАТИТ", опять же на мой взгляд уж можно было решить проблему лучше, вынести файл в папку или сделать ссылку на мировой ресурс обложек и т.д.
Но не пихать все внутрь файла, похоже кстати на моду на nosql запилить внутрь и засунуть все в одно.
- Ну и второй момент, вы же уже поняли, что теперь внутри 1-го mp3 файла у вас будет лежать целых 3 версии как оформлены тэги! Это 128 байт с конца ID3 + 228 байт перед ними это ID3v1 и еще туева-хуча байт в начале это будет ваш ID3v2.x И все это надо уметь читать, конвертить, проверять и показывать. Потому и например некоторые плэйеры правильно показывают тэги файла, а кидаешь на другой уже нет, один умеет читать одну версию, другой нет.

Все это к чему?
Что конечно и я даже уверен, что взять и сразу спроектировать идеальную систему нельзя и даже почти невозможно, для этого нужно до идеальной сломать сотню других неидеальных, но хотя бы постараться сесть и уделить время на раздумия перед созданием нового формата данных нужно делать и желательно в несколько голов и скрежетащих мозгов.

p.s. Всем спасибо, а либу для более или менее работающего варианта получаения ID3 и ID3v2.x я написал, задача была на PHP потому и на PHP она, один простой класс, обязательно ее подчищу и доведу до красоты приемлимой и выложу на http://github.com/mpakus

p.p.s & upd: класс выложил, в целом более или менее сносно и приемлимо работает, брать тут https://github.com/mpakus/mp3meta

php, рабочее, mp3, програмирование

Previous post Next post
Up