Онлайн радио для Android: пошаговое руководство

Рассказывает Николай Коломийцев, технический директор и Android-разработчик LevelTop.org 


Привет, типичные! В этом руководстве расскажу вам о том, как создать свое приложение в Android.

Начну сразу с сути, поэтому определимся с функционалом:

  1. Проигрывание потокового аудио с помощью ExoPlayer.
  2. Парсинг HTML страницы.
  3. Интеграция API Last.fm.
  4. Подключение сервиса для управления проигрыванием из «шторки».
  5. Работа с кастомными библиотеками.

С требованиями разобрались, теперь самое сложное интересное — реализация.

Весь код вы можете найти на GitHub, здесь же я уделю внимание только основным моментам.

Думаю, что SDK у вас установлено и новые проекты вы создавать умеете, поэтому создадим пустой (blank) проект и добавим библиотеки в build.gradle:

Теперь коротко пройдемся по классам:

  1. Player — класс для инициализации и управления нашим ExoPlayer.
  2. NotificationService — класс для проигрывания аудио в фоне и отображения уведомления в шторке.
  3. Const — класс для описания ссылок на аудио и прочего.
  4. CircularSeekBar — класс, который я позаимствовал на GitHub, добавляет нам изогнутый SeekBar.
  5. GetTrackInfo — здесь мы обращаемся к Last.fm, а также парсим HTML страницу.
  6. MainActivity — главный класс приложения, выполняющий функции отрисовки экрана и инициализации методов.

Также добавим пару layout-файлов для шторки и главного экрана, drawables можно найти здесь:

И добавим нашему Manifest несколько разрешений и служб:

Теперь давайте получим ключ Last.fm API, он нужен нам для того, чтобы по имени исполнителя найти его фотографию и показать ее на главном экране. Для этого нужно перейти на страницу создания аккаунта и войти или зарегистрироваться, после чего вам потребуется создать приложение. Эта операция займет 30 секунд, и мы наконец доберемся до API KEY, его вам нужно ввести в поле LAST_FM_KEY класса Const.java:

Далее предлагаю перейти к способу получения ссылки на прямую трансляцию, ее я беру отсюда. Для этого нам нужно запустить радио и, нажав правой кнопкой мыши в Chrome, выбрать пункт «посмотреть код», после чего выбрать вкладку Network и найти ссылку с самым длинным timeline. Это и будет наш стрим, он уже добавлен в класс Const — аналогичным способом я получил ссылку на HTML-страницу с именем исполнителя и названием трека. В этом коде много костылей, так как парсить HTML — это само по себе странное занятие, но все же я постараюсь его объяснить:

Здесь вы можете видеть получаемый мною нужный фрагмент HTML-страницы:

А это его парсинг, надеюсь, что комментарии будут информативны:

Этот пример кода, вполне возможно, не является лучшей практикой, но все приложение было написано ночью за несколько часов. Парсинг HTML — занятие сложное, и если есть возможность его не использовать, то нужно этой возможностью пользоваться. Надеюсь, мой опыт обработки HTML-страницы кому-то окажется полезным.

Далее парсинг JSON и получение фото пользователя.

Вот пример отправляемого Last.fm JSON-ответа для певицы Adele:

Все, что нас с вами здесь интересует — это изображение размера «mega», парсить мы его будем таким образом:

Теперь немного об ExoPlayer, и почему я не использовал стандартный MediaPlayer. MediaPlayer абсолютно не оптимизирован для таких нагрузок и частенько останавливал трансляцию. Также на старых (старше пятой) версиях Android перемотка, которую я собирался добавить позже, работает так, как будто плеер подгружает всю аудио дорожку между текущим положением и выбранным пользователем. После недолгих поисков выбор пал на ExoPlayer, сейчас коротко опишу его возможности, код ниже можно использовать как отдельный элемент в своем проекте:

Финальный этап урока — это уведомление в шторке, сервис и то, каким образом это работает.

Из главного Activity при начале проигрывания аудио мы запускаем сервис, и он берет всю работу на себя, освобождая работу в Activity. Выглядит это так:

Сервис управляется с помощью Intent. Когда пользователь нажимает на кнопку «play / pause» в шторке, сервис отправляет Intent сам себе и обрабатывает его, так мы отправляем Intent при нажатии:

А так обрабатываем в onStartCommand:

Поздравляю! Мы разработали клиент-серверное приложение с использованием дополнительных библиотек, воспроизведением аудио, а также работой с сервисами. В конечном итоге получится нечто подобное тому, что вы видите на скриншотах:

kolomiytsev_3 kolomiytsev_2 kolomiytsev_1

Николай Коломийцев, Работаю техническим директором и Android разработчиком в LevelTop.org