Привет, хабра гиктаймс-читатель! Сегодня я научу тебя как из бесполезного функционала получить полезный. Получать будем на примере умного дома от небезызвестной компании Xiaomi и её продукта в виде ZigBee-шлюза.
Владельцы компонентов умного дома от Xiaomi знают, что большая часть их делится на умеющие общаться по zigbee или bluetooth. Нас будет ��нтересовать шлюз для zigbee девайсов версии 2, т.к. именно там появился функционал радио, который по дефолту может воспроизводить только китайские интернет-радиостанции.

Конечно, в интернете есть проект, с помощью которого можно не хитро добавить различные другие радиостанции, но мы пойдем другим путем и будем делать из шлюза беспроводную колонку.
Для успешного осуществления операции нужно:
Для того, чтобы сделать из нашего шлюза беспроводную колонку нужно прикинуться интернет-радио потоком и обучить шлюз, что стучаться за списком станций нужно именно к нам, а не на китайское API.
Для того, чтобы понять, как приложение на телефоне общается с китайскими серверами, можно поснифить трафик, но я избавлю вас от этого геморроя :) Желающие расширить свой кругозор — можете заняться этим факультативно.
Итак, нас будут интересовать три запроса и, соответственно, ответа к китайскому API, которое живет по адресу api.ximalaya.com:
Слово openapi в пути намекает на что-то открытое, но публичной спецификации я не нашел. Запрос идет с параметрами, которые для наших целей не нужны, поэтому отбрасываем их.
Я использовал в качестве вебсервера nginx, вот конфиг:
Создайте в корне вашего вебсервера такую же иерархию. Дополнительно создайте в корне вебсервера папки radio и hls. Все обращения по этим путям должны выводить один и тот же JSON, поэтому есть смысл сделать их ссылками на файл, который назовем stations.json
Вот его содержимое:
Как можно видеть, тут всё просто — мы отдаем массив радио с указанием, где искать поток. Если у вас несколько шлюзов — можете сделать несколько каналов. Важное замечаение — указываемый тут адрес должен быть доступен со шлюза!
Для того, чтобы приложение увидело ваши изменения необходимо отредактировать hosts на смартфоне и прописать туда соответствие api.ximalaya.com адресу вашего вебсервера.
Теперь о том, как получить поток. Я решил выводить всё со своей звуковой карты с ПК, на котором развернут веб-сервер. Для этого будем использовать ffmpeg:
Обратите внимание на пути и адрес веб-сервера — подставьте ваши.
В принципе, это всё для успешной работы — запустите скрипт ffmpeg, он начнет создавать сегменты со звуком с вашей звуковой карты, запустите приложение на телефоне и выберите вашу станцию — через секунду-две должен пойти звук с ПК.
Владельцы компонентов умного дома от Xiaomi знают, что большая часть их делится на умеющие общаться по zigbee или bluetooth. Нас будет ��нтересовать шлюз для zigbee девайсов версии 2, т.к. именно там появился функционал радио, который по дефолту может воспроизводить только китайские интернет-радиостанции.

Конечно, в интернете есть проект, с помощью которого можно не хитро добавить различные другие радиостанции, но мы пойдем другим путем и будем делать из шлюза беспроводную колонку.
Что нужно?
Для успешного осуществления операции нужно:
- Собственно, сам ZigBee шлюз версии не менее 2 (в ней появилось радио)
- Любой веб-сервер
- Смартфон на котором есть рут и установленная софтина MiHome c выбранной страной China Mainland
Что будем делать?
Для того, чтобы сделать из нашего шлюза беспроводную колонку нужно прикинуться интернет-радио потоком и обучить шлюз, что стучаться за списком станций нужно именно к нам, а не на китайское API.
Для того, чтобы понять, как приложение на телефоне общается с китайскими серверами, можно поснифить трафик, но я избавлю вас от этого геморроя :) Желающие расширить свой кругозор — можете заняться этим факультативно.
Итак, нас будут интересовать три запроса и, соответственно, ответа к китайскому API, которое живет по адресу api.ximalaya.com:
- /openapi-gateway-app/live/radios
- /openapi-gateway-app/live/get_radios_by_ids
- /openapi-gateway-app/search/radios
Слово openapi в пути намекает на что-то открытое, но публичной спецификации я не нашел. Запрос идет с параметрами, которые для наших целей не нужны, поэтому отбрасываем их.
Я использовал в качестве вебсервера nginx, вот конфиг:
server {
listen *:80;
server_name api.io.mi.com ximalaya.com www.ximalaya.com api.ximalaya.com mobile.ximalaya.com open.ximalaya.com ximiraga.ru www.ximiraga.ru;
root /opt/xiaomiradio/www;
index index.php index.html index.htm;
access_log /var/log/nginx/radio_access.log;
error_log /var/log/nginx/radio_error.log;
location @ximalaya {
proxy_pass http://api.ximalaya.com;
}
}
Создайте в корне вашего вебсервера такую же иерархию. Дополнительно создайте в корне вебсервера папки radio и hls. Все обращения по этим путям должны выводить один и тот же JSON, поэтому есть смысл сделать их ссылками на файл, который назовем stations.json
Вот его содержимое:
{
"total_page":1,
"total_count":1,
"current_page":0,
"radios":[
{
"id":527782023,
"kind":"radio",
"program_name":"AirSound1",
"radio_name":"AirSound1",
"radio_desc":"",
"schedule_id":0,
"support_bitrates":[
64
],
"rate24_aac_url":"",
"rate64_aac_url":"http://<ваш адрес в локальной сети>/hls/live1.m3u8",
"rate24_ts_url":"",
"rate64_ts_url":"",
"radio_play_count":1,
"cover_url_small":"http://<ваш адрес в локальной сети>/radio/527782023/cover_small.png",
"cover_url_large":"http://<ваш адрес в локальной сети>/radio/527782023/cover_big.png",
"updated_at":0,
"created_at":0
}
]
}
Как можно видеть, тут всё просто — мы отдаем массив радио с указанием, где искать поток. Если у вас несколько шлюзов — можете сделать несколько каналов. Важное замечаение — указываемый тут адрес должен быть доступен со шлюза!
Для того, чтобы приложение увидело ваши изменения необходимо отредактировать hosts на смартфоне и прописать туда соответствие api.ximalaya.com адресу вашего вебсервера.
Теперь о том, как получить поток. Я решил выводить всё со своей звуковой карты с ПК, на котором развернут веб-сервер. Для этого будем использовать ffmpeg:
#!/bin/bash
ffmpeg -f alsa -i hw:Loopback,1,0 -c:a libfdk_aac -b:a 64k -f ssegment -segment_list /opt/xiaomiradio/hls/live1.m3u8 -segment_list_flags +live -segment_time 1 -segment_list_size 1 -segment_wrap 5 -segment_list_entry_prefix http://<ваш адрес в локальной сети>/hls/ /opt/xiaomiradio/hls/64%03d.aac
Обратите внимание на пути и адрес веб-сервера — подставьте ваши.
В принципе, это всё для успешной работы — запустите скрипт ffmpeg, он начнет создавать сегменты со звуком с вашей звуковой карты, запустите приложение на телефоне и выберите вашу станцию — через секунду-две должен пойти звук с ПК.