уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

В продолжении темы о воспроизведении потокового аудио в Андроид сегодня рассмотрим небольшой пример того, как, используя только возможности ОС Android можно прочитать метаданные mp3-файла. Да, я в курсе, что есть замечательная библиотека «ID3v2 Library» (и даже активно её использую в одном проектике), но если есть «родной» способ прочитать теги, то почему бы им не воспользоваться?

Итак, в прошлый раз я рассмотрел два примера того как воспроизвести потоковое аудио. При этом, во втором случае для доступа к данным нам потребовалось передать в заголовках запроса ключ авторизации. Ключ может потребоваться, например, если вы захотите воспроизводить звук из Dropbox или ещё какого-нибудь сервиса. Естественно, если мы захотим написать свой собственный аудио-плеер для Андроид, то нам придётся также задуматься и о том, чтобы получить непосредственно из потока всю информацию о песне (исполнителя, название альбома, номер трека на диске и т.д. и т.п.). И здесь нам на помощь приходит Android SDK, а точнее класс MediaMetadataRetriever.

С помощью MediaMetadataRetriever мы можем получить довольно много полезной информации об аудио- или видео-файле, в т.ч.:

  • Название альбома
  • Исполнителя
  • Название песни
  • Номер песни на диске
  • Битрейт
  • Год выпуска альбома
  • Жанр
  • Имя композитора
  • и т.д.

Конечно, абсолютно всё, что можно затолкать в ID3v2 файла мы с помощью MediaMetadataRetriever вытащить не сможем, но наиболее часто используемые теги — вполне можем.

Как и  MediaPlayer (о котором я писал в прошлый раз) MediaMetadataRetriever имеет несколько переопределенных методов SetDataSource:

procedure setDataSource(path: JString); cdecl; overload;
  procedure setDataSource(uri: JString; headers: JMap); cdecl; overload;
  procedure setDataSource(fd: JFileDescriptor; offset: Int64; length: Int64); cdecl; overload;
  procedure setDataSource(fd: JFileDescriptor); cdecl; overload;
  procedure setDataSource(context: JContext; uri: Jnet_Uri); cdecl; overload;

Все эти методы задают источник данных для извлечения метаданных. Вторая, третья и четвертая реализация метода предназначены для работы с файлами, расположенными непосредственно на устройстве, а первая и пятая — для работы как раз-таки с потоковым аудио.
Для запроса данных предназначен метод:

function extractMetadata(keyCode: Integer): JString; cdecl;

здесь KeyCode — константа, определяющая какую информацию нам необходимо получить.
Запрос сведений о содержимом какого-либо тега в Delphi XE7, в самом простом случае, может выглядеть так:

var MediaMetadataRetriever: JMediaMetadataRetriever;
    Album: string;
begin
  MediaMetadataRetriever:=TJMediaMetadataRetriever.Create; 
  MediaMetadataRetriever.setDataSource(SharedActivityContext, StrToJURI('URL_ФАЙЛА_В_СЕТИ'));
  Album:=JStringToString(MediaMetadataRetriever.extractMetadata(TJMediaMetadataRetriever.JavaClass.METADATA_KEY_ALBUM));
  MediaMetadataRetriever.release;
  MediaMetadataRetriever:=nil;
end;

Однако на поверку оказалось, что именно при таком использовании метода setDataSource вылетает ошибка IllegalArgumentException, которая говорит о том, что URL задан неверно, несмотря на то, что как раз URL задан 100% верно, по всем правилам. И это тот самый случай, когда разработчики Embarcadero здесь вообще не при чём. Как оказалось, этот баг присутствует уже давно в Android, ещё с 2012 года и, по-моему, будет присутствовать ещё долго. Поэтому, чтобы запросить данные о содержимом ID3 из mp3-файла сейчас необходимо воспользоваться вот такой конструкцией:

uses Androidapi.Helpers, Androidapi.JNI.Net, Androidapi.JNI.Os, Androidapi.JNI.JavaTypes,Androidapi.JNIBridge;
var MediaMetadataRetriever: JMediaMetadataRetriever;
    Album: string;
    O: JHashMap;
    M: JMap;
begin
  MediaMetadataRetriever:=TJMediaMetadataRetriever.Create; 
  if TJBuild_VERSION.JavaClass.SDK_INT>=14 then
    begin
      O:=TJHashMap.Create;
      M:=TJMap.Wrap((O as ILocalObject).GetObjectID);
      MediaMetadataRetriever.setDataSource(StringToJString(FURL), M);
    end
  else
    MediaMetadataRetriever.setDataSource(SharedActivityContext, StrToJURI(FURL));
  Album:=JStringToString(MediaMetadataRetriever.extractMetadata(TJMediaMetadataRetriever.JavaClass.METADATA_KEY_ALBUM));
  MediaMetadataRetriever.release;
  MediaMetadataRetriever:=nil;
end;

То есть здесь мы воспользовались версией метода setDatasource в которой дополнительно передаются заголовки запроса, но список заголовков оставили пустым.
В качестве примера, я накидал небольшой проектик в Delphi XE7, который демонстрирует проигрывание файла из Сети и получение основных сведений о композиции. В дизайнере формы приложение выглядит так:
id3
В Edit’е задаем URL по которому расположен файл, жмем кнопочку «Play» и в запущенном приложении получаем:
id3_2

Видео-ролик, демонстрирующий работу приложения:

Скачать исходник: Исходники —> Интернет и Сети —> Прочие

Книжная полка

Описание Подробно рассматривается библиотека FM, позволяющая создавать полнофункциональное программное обеспечение для операционных систем Windows и OS X, а также для смартфонов и планшетных компьютеров, работающих под управлением Android и iOS
купить книгу delphi на ЛитРес
Автор: Юрий Магда
Описание: Описаны общие подходы к программированию приложений MS Office. Даны программные методы реализации функций MS Excel, MS Word, MS Access и MS Outlook в среде Delphi.
купить книгу delphi на ЛитРес

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
8 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
trackback

[…] Продолжение статьи о воспроизведении потокового аудио в Android — здесь […]

Ваня Борисов
Ваня Борисов
02/12/2014 10:46

Здравствуйте Большое Спасибо за пример, а можно воспроизводить потоковое видео если да то как, сделайте пример-проект

Ваня Борисов
Ваня Борисов
06/12/2014 01:17
Ответить на  Vlad

Посмотрите пожалуйста, и ещё кроме mp3 он может воспроизводить может кодеки надо подключать какието

Ваня Борисов
06/12/2014 17:12
Ответить на  Vlad

Пожалуйста посмотрите, и ещё как сделать поддержку других форматов кроме mp3

Ян
Ян
16/01/2015 20:53

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

PEHA
PEHA
30/10/2016 00:10

ftp сервер для потокового воспроизведения??? что надо изменять

Иван
Иван
19/06/2017 02:14

Как реализовать потоковое видео в формате hls?