Многие пользователи медиацентра KODI, входящего в состав RetroOrangePi, наверняка заметили, что там используется внешний плеер MPV, который, в отличии от штатного, имеет поддержку аппаратного декодирования. Это позволяет проигрывать контент 1080P без лагов, однако есть и большая проблема — единственный способ управлять плеером это клавиатура. Более того — у плеера нет даже минимального GUI, так что какой продолжительности фильм вы смотрите, и сколько еще осталось до конца — увы, не узнать.
Я, признаюсь, очень ленивый человек, и таскать за собой еще и клавиатуру, с учетом того, что сам KODI управляется с телефона — очень не удобно. Погуглив пару минут, я с удивлением узнал, что не существует готовых решений для удаленного управления MPV с смартфона. Ну что делать — придется написать самому. Кстати, как оказалось, в центре Витебска купить недорогую беспроводную клавиатуру за 1 час обеденного перерыва — тот еще квест.
MPV поддерживает несколько языков для написания скриптов, один из них Lua. На Гитхабе я нашел проект mpv-network-commands, написанный на Lua и позволяющий управлять минимум функций MPV, при помощи команд, передаваемых посредством UDP. Убедившись, что он работает, я во время обеденного перерыва написал простейшее приложение, которое реализовывало максимально примитивный функционал — по сути, оно позволяло поставить на паузу, запустить воспроизведение с паузы и закрыть плеер.
Выглядело оно примерно так.
Чтобы иметь возможность перематывать видео, а так же видеть прогресс-бар, пришлось модифицировать исходный скрипт, добавив следующую функцию:
function send_name()
local title =mp.get_property("media-title");
local length = math.floor(mp.get_property("length"));
local pos=math.floor(mp.get_property("time-pos"));
conn_up:sendto(title.."$"..length.."$"..pos, "192.168.100.168", 756);
end
Самое смешное — это то, что код, обрабатывающий входящие данные со стороны телефона, получился куда более громоздким:
thread {
// this thread receives incoming massages from MPV and updates views accordingly to received info
try {
chnl.socket().bind(InetSocketAddress(756))
chnl.configureBlocking(false)
var timerStarted: Boolean = false
var timer = Timer()
while (true) {
var buf = ByteBuffer.allocate(1024)
buf.clear()
var last_pos = ""
if (!timerStarted) {
timer = Timer()
timer.schedule(myTimerTask(textView5, textView6, textView4, seekBar3), 2000, 1000)
//this timer will clear views, if no info received in last 2 seconds
timerStarted = true
}
if (chnl.isOpen) {
if (chnl.receive(buf) != null) {
if (timerStarted) {
timer.cancel()
timerStarted = false
}
var data_length = buf.position()
buf.flip()
var str = String(buf.array(), 0, data_length, UTF_8)
Log.d("received data", str)
val arr = str.split("$")
if (arr.size >= 3) {
media_length = arr[1].toInt()
runOnUiThread {
if (textView4.text != arr[0]) textView4.text = arr[0]
if (last_pos != arr[1]) {
last_pos = arr[1]
textView6.text = convertSecsToFullTime(last_pos)
}
if (!blockview) {
textView5.text = convertSecsToFullTime(arr[2])
seekBar3.max = arr[1].toInt()
seekBar3.progress = arr[2].toInt()
}
}
}
}
}
}
} catch (e: Exception) {
runOnUiThread {
Toast.makeText(this, e.message, Toast.LENGTH_SHORT).show()
}
Log.d("In MPVremote", e.message.toString())
}
}
В результате получилось вот это:
Исходные коды, а также apk, лежат на Гитхабе.
Сразу предупреждаю — могут быть точно есть баги.
Основной недостаток — требуется фиксированный IP для телефона в вашей локальной сети, в которой работает OrangePi. Он необходим, что бы скрипт знал, куда ему отправлять инфу о воспроизводимом файле. Самый простой способ — в настройках DHCP сервера вашего роутера указать выдавать один и тот же IP устройствам с МАК-адресом телефона.
Также нет никаких элементов безопасности — любой пользователь в вашей сети сможет поставить видео на паузу или закрыть плеер, зная IP медиацентра. Правда, узнать что воспроизводится и воспроизводится ли вообще — нет.
Кстати, использование обмена данными через UDP безо всяких подтверждений порождает побочный эффект — поскольку прием входящих данных от плеера крутится в отдельном потоке, то вы можете ставить/снимать паузу и закрывать плеер, даже если не указали серверному скрипту правильный IP вашего телефона. Главное, что бы вы знали IP вашего медиацентра.
Установка
Перейдите в Desktop RetroOrangePi. Сначала надо установить Lua и LuaSocket.
sudo apt-get install lua5.1 luasocket
Затем перейдите в директорию /home/pi/.config/mpv/ и создайте там директорию lua.
В lua скопируйте server.lua.
Откройте server.lua тем же nano и в строке
conn_up:sendto(title.."$"..length.."$"..pos, "192.168.100.168", 756);
замените IP адрес на адрес вашего телефона.
Сохраните и перезагрузите OrangePi.
Установите приложение на телефон. Собранный apk лежит на Гитхабе. Запустите его, перейдите в Settings. Задайте там IP вашего медиацентра и порт 755. Нажмите Save.
Всё, можно пользоваться.
Автор: BiW