Чтение тегов ID3 ​​MP3, хранящихся в Интернете

Можно ли прочитать теги ID3 MP3, хранящиеся в Интернете, без фактической загрузки всего файла?

Я использовал TagLib Sharp, но, насколько мне известно, вам действительно нужно открыть файл, чтобы прочитать теги ID3.


person James Jeffery    schedule 13.05.2014    source источник
comment
Ну... всегда нужно открывать файл. В случае файла MP3, который хранится в сети... вам нужно будет создать веб-запрос, получить поток ответов и прочитать данные из потока ответов.   -  person Florian    schedule 14.05.2014
comment
@thefiloe Это должен быть весь файл? Я использую WebRequest для загрузки файла, но в идеале я хотел получить имя файла перед его сохранением. Единственное решение, которое у меня есть, это сохранить файл как: `random_string.tmp', дождаться его загрузки, а затем прочитать теги ID3. Что позволит мне изменить имя файла после завершения на правильное название.   -  person James Jeffery    schedule 14.05.2014
comment
Нет. Поскольку ID3v2 хранится в начале, вы сможете просто скачать нужную часть. Если вам повезет, библиотека тегов сделает это за вас. Если нет, вам придется самостоятельно разобрать заголовок ID3, получить длину ID3-тега, загрузить необходимые данные, создать поток памяти из загруженных данных и передать поток в свою библиотеку. Проанализировав заголовок, вы можете взглянуть на это: cscore .codeplex.com/SourceControl/latest#CSCore/Tags/ID3/   -  person Florian    schedule 14.05.2014


Ответы (1)


Как сказал Флориан выше, вы можете использовать диапазон HTTP, чтобы прочитать немного файла и посмотреть, есть ли ID3 или нет, а затем прочитать остальную часть тега (если он присутствует/необходим). Например:

Range: bytes=0-65535

Тег ID3 может включать изображение, поэтому он может быть очень большим (я видел некоторые из них размером 500 КБ). Однако большая часть полезной информации, такой как заголовок, описание и т. д., скорее всего, будет доступна в первых нескольких килобайтах. В зависимости от ваших подключений (или ожидаемых подключений клиента) я бы выбрал первое количество килобайт для загрузки. Для большинства подключений скорость 64 КБ сейчас будет очень высокой (возможно, в 2014 году было меньше).

Обратите внимание, что весь файл также может быть менее 64 КБ. Запрос Range все еще должен работать, только он вернет размер файла. В этом случае вы никогда не отправите второй запрос на получение дополнительных данных.

Файл MP3 с тегом ID3 начинается так:

0x49 0x44 0x33                 ID3
0x03 0x00                      major.revision (2.0 or 3.0)
0x00                           flags
0xSS 0xSS 0xSS 0xSS            size

Примечания к версии:

  1. Тег ID3, что 3 не является частью версии
  2. Первая версия — 2, потому что MP3 уже имел возможность TAG и считалась версией 11.1 при определенных условиях).
  3. На данный момент я не вижу никакой ревизии, кроме 0. Вот почему мы ссылаемся на теги как на ID3v1 (TAG), ID3v2 (ID3 + 0x02) и ID3v3 (ID3 + 0x03).

0xSS представляет размер. Это интересно, потому что в каждом байте используется только 7 бит, чтобы избежать 0xFF, который является кодом синхронизации для файлов MP3 (MPEG). Только они забывают что-то сделать с 0xFF в изображениях PNG и JPEG... В любом случае...

Способ расчета размера выглядит следующим образом:

size = (buffer[pos + 6] << 21) +
       (buffer[pos + 7] << 14) +
       (buffer[pos + 8] <<  7) +
       (buffer[pos + 9] <<  0)

ВАЖНО: вы должны убедиться, что бит 7 не установлен ни в одном из этих байтов. Если установлено, то это недействительный тег ID3. Вот почему я не делаю (buffer[pos + n] & 0x7F), часть & 0x7F не требуется, если вы заранее правильно проверили размер.

Обратите внимание, что это size не включает размер заголовка. Так что имейте в виду, что для заголовка есть 10 байтов.

Остальная часть буфера организована в виде кадров. Это либо 3 буквы, размер и данные этого фрейма, либо 4 буквы, размер, флаги и данные. Заголовок каждого кадра определяется версией (2 или 3).

В любом случае, если у вас есть этот size, если вы хотите прочитать весь ID3, вы можете выполнить еще один GET на HTTP-сервер и получить оставшиеся данные, если первые 64 КБ (или любой другой размер, который вы использовали первым) уже не больше или не равен необходимый размер.

Range: bytes=65536-<size + 10 - 1>

Размер - это данные в ID3. +10 для заголовка. Значение -1 связано с тем, что диапазон HTTP включает (не размер, а положение).

ВАЖНОЕ ПРИМЕЧАНИЕ. Все серверы не принимают заголовок Range. Если у вас все под контролем, а ваш сервер не поддерживает запросы диапазона, вы можете рассмотреть возможность добавления прокси-сервера перед сервером. nginx действительно хорош в этом. Он может кэшировать весь файл и возвращать только те диапазоны, которые запрошены в заголовке HTTP.

person Alexis Wilke    schedule 19.05.2020