Здесь так же считаю нужным оговориться, что это не "тот самый" вариант, где на ПК в фоновом режиме обработчик передает данные на ардуинку, которая с некоторой задержкой подсвечивает фон монитора. Здесь все работает практически синхронно, с обработкой «на лету» HDMI сигнала и его обработки на одноплатнике Raspberry Pi, который так же выполняет роль мощного и функционального домашнего медиацентра на базе всеядного плеера Kodi 18.5-Leia.
Реализация «Soft»
Это более простой, возможно - самый простой вариант с минимальными затратами на железо и упрощенной реализацией.
Использовать буду этот же одноплатник - Raspberry Pi 3 B+ 1Gb, только в качестве ОС разверну LibreElec, поверх которой будет крутиться мощный медиацентр Kodi.
На тот момент (декабрь 2019г) была доступна версия LE 9.2.0 с версией плеера Kodi 18.5-Leia, сборка от 2019-11-23.
Сейчас же доступна версия 19.3, наверняка имеющая свои костыли и грабли, как и более продвинутая реализация малины - 4B и Compute Module 4 на 1,5 ГГц чипе Cortex-A72 (ARM v8)
Я не интересовался более свежими версиями программного и аппаратного обеспечения, так как меня до сих пор устраивает имеющаяся конфигурация. Хотя она имеет ограничение по максимальному разрешению Full HD 1080p (разрешение 1920×1080 точек) и не умеет воспроизводить контент с более высокой четкостью. Кому этого мало, курите доки на четвертую малину и последние версии Kodi, принцип построения системы будет тем же, что и здесь.
Для питания всего оборудования буду использовать более мощный блок питания от какого-то устройства Samsung (имеющий на выходе 14.5V и рассчитанный на 63W нагрузки), к которому подключен преобразователь на 5V с четырьмя USB гнездами на борту. Суммарная нагрузка такого преобразователя – 8А, т.е. около 40W, чего мне должно хватить для питания малины и 91 пикселя ленты WS2812B, которую уже смонтировал на заднюю крышку телевизора в первом опыте. Подключать подсветку и Raspberri Pi можно от разных источников, обеспечив для ленты рассчитанный по количеству пикселей максимальный ток потребления. Один цвет каждого пикселя на максимальной яркости потребляет 18.5 мА. Три цвета – 55,5 х 91 пиксель = 5 050,5 мА. На практике лента никогда не светится чистым белым светом и в динамике ток потребления будет меньше, однако лучше обеспечить расчётный ток, т.е. в моем случае - 5А. Для Raspberri Pi производитель рекомендует адаптер с выходным током 2,5 – 3А. При раздельном питании нужно не забыть объединить земли источников питания как можно ближе к самим источникам проводом минимальной длины.
OS на Raspberry Pi разворачивается все так же с использованием NOOBS – архив NOOBS_v3_2_1.zip распаковывается на microSD карту, карта вставляется в Raspberry Pi, запуск, следование инструкциям на мониторе (я подключал к Raspberry Pi монитор, мышь и клавиатуру для удобства) и несложная настройка – включение SSH, SPI, назначение статического IP:
В настройках системы в службах нужно включить SSH и включить авторизацию по паролю, так же поставить минимальную версию протокола SMB2, максимальную – SMB3.
SMB понадобится для того, чтобы видеть каталоги Raspberry Pi и подключенные к ней флеш-накопители с ПК. В настройках ищем и добавляем русскую раскладку клавиатуры. С физической клавиатурой ничего не произойдет, будет только ввод на английском, зато в виртуальной экранной клавиатуре появится возможность ввода текста на русском. Еще я отключил обновления системы, беспроводную сеть и синий зуб.
Настройка соединения SSH
На ПК для удобства работы с PuttY и WinSCP сделаем авто логин по ключу. Соответственно подразумевается, что Raspberry Pi подключена к роутеру, чтобы в последствии на нее можно было скинуть файл конфига hyperion (hyperion.config.json) и иметь возможность работать с консолью через программу Putty. Для этого запускаем генератор ключей puttygen.exe, жмем Generate и водим мышкой по области ниже прогресс-бара:
По окончании процесса генерации в окнах приложения будут находиться сгенерированные приватный и публичный ключи. Публичный должен находиться в файле
/storage/.ssh/authorized_keys
Нажав соответствующие кнопки, сохраняем в файлы на ПК приватный и публичный ключ, а также копируем строку с поля «Key fingerprint» и так же сохраняем в текстовый файл.
Создаем соединение с IP Raspberry Pi, порт 22, сохраняем его с любым именем, входим в консоль PuttY – логин/пароль по умолчанию - (root:libreelek). Копируем весь текст публичного ключа из области в окне программы в буфер обмена, в консоли пишем:
cat >> .ssh/authorized_keys "Административные шаблоны" > "Сеть" > "Рабочая станция Lanmann". В правой панели двойным кликом на "Включить небезопасные гостевые входы" открыть параметры строки. Поставить "Включено".
Если после этих действий и перезагрузки систем проблема осталась, стоит проверить и включить поддержку общего доступа к файлам SMB.
Для этого так же с командной строки - «Win + R» запустить optionalfeatures.exe
В появившемся окне пролистать список до пункта "Поддержка общего доступа к файлам SMB 1.0/CIFS" и отметить указанные на скриншоте чекбоксы, после чего перезагрузить ПК.
Проблема с протоколом SMB существует видимо только на системах с OS Windows 10, т.к. доступ по этому протоколу на Windows 8 у меня никаких проблем не вызывал.

Существует еще несколько инструментов для проверки и включения этих протоколов. Для проверки версий установленных протоколов SMB нужно запустить PowerShell.
Доступны следующие команды:
Для SMB1 –
Обнаружение:
Get-WindowsOptionalFeature –Online –FeatureName SMB1Protocol
Отключение:
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol
Включение:
Enable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol
Для SMB2 –
Get-SmbServerConfiguration | Select EnableSMB2Protocol
Set-SmbServerConfiguration –EnableSMB2Protocol $false
Set-SmbServerConfiguration –EnableSMB2Protocol $true
Для SMB3 –
Get-SmbServerConfiguration | Select EnableSMB3Protocol
Get-SmbServerConfiguration | Select EnableSMB3Protocol
Set-SmbServerConfiguration –EnableSMB3Protocol $false
И рекомендации MicroSoft (https://support.microsoft.com/ru-ru/help/2696547.) для командной строки:
Для SMB версии 1 на SMB-клиенте
Обнаружение:
sc.exe query lanmanworkstation
Отключение:
sc.exe config lanmanworkstation depend= bowser/mrxsmb20/nsi
sc.exe config mrxsmb10 start= disabled
Включение:
sc.exe config lanmanworkstation depend= bowser/mrxsmb10/mrxsmb20/nsi
sc.exe config mrxsmb10 start= auto
SMB версий 2 и 3 на SMB-клиенте
Обнаружение:
sc.exe query lanmanworkstation
Отключение:
sc.exe config lanmanworkstation depend= bowser/mrxsmb10/nsi
sc.exe config mrxsmb20 start= disabled
Включение:
sc.exe config lanmanworkstation depend= bowser/mrxsmb10/mrxsmb20/nsi
sc.exe config mrxsmb20 start= auto
Эти команды следует вводить в командной строке с повышенными привилегиями. После внесения этих изменений компьютер необходимо перезагрузить.

После этих действий должно появится сетевое устройство с внутренней структурой каталогов в /storage и подключенными к USB портам накопителями. У меня при проводном соединении 100 Мбит/сек через роутер максимальная скорость загрузки файлов с ПК на USB накопитель в малине составила около 12 Мбайт/сек, что примерно соответствует пропускной способности для проводного соединения моего роутера.

Настройка Hyperion
Поскольку виртуальная машина Java под мою ОС на ПК уже установлена (jre-8u231-windows-x64.exe), остается запустить и переконфигурировать HiperCon (HyperCon.jar). Логин/пароль по умолчанию для этой ОС – root/libreelec. В этот раз мне не нужно возиться с аппаратным граббером и форматами аналогового видео, главное – выполнить соединение и проверить работу с той же лентой на чипах WS2812B - на этот раз чекбокс Grabber V4L2 отключен:В оставшихся вкладках выбираем нашу ОС на Raspberry Pi, сохраняем конфиг HyperCon, создаем новый файл конфигурации Hyperion, отправляем конфиг на Raspberry Pi, стартуем и пробуем в ColorPicker проверить соответствие цветов.
Все совпадает, теперь любой воспроизводимый плеером Kodi контент будет управлять фоновой подсветкой. Сигнальный вывод GPIO остается прежним – 18 (физический пин гребенки – 12)
Автозапуск в этот раз я никак не настраивал, демон запускается одновременно с началом работы плеера. Однако было так, что подсветка все равно не включалась. Тогда пробуем проверить, прописался ли автозапуск демона в «/storage/.config/ autostart.sh» и пробуем переустановить демон, чтобы снова отправить на Raspberry Pi его конфиг. Сам конфиг программа отправляет в директорию Raspberry Pi –
«/storage/.config/ hyperion.config.json».
Проверить работу демона можно так же, отправляя цвет на вкладке SSH HyperCon, поставив галочку «Autoupdate» и нажав кнопки стоп-старт для его перезапуска.
Если демон не стартует после перезагрузки Raspberry Pi, пробуем изменить автостарт в файле
/storage/.config/autostart.sh
//-------------
#!/bin/sh
sleep 5
/storage/hyperion/bin/hyperiond.sh /storage/.config/hyperion.config.json > /storage/logfiles/hyperion.log 2>&1
//-------------
Тем самым дав задержку перед выполнением запуска демона.
Содержимое файла конфигурации демона Hyperion – «hyperion.config.json» находится в аттаче в текстовом файле «hyperion.config.json.soft.exemple.txt» -
Настройка ИК пульта дистанционного управления
Осталось прикрутить и настроить пульт ДУ. Я взял тот, что был с TV-приставкой на андроид:Приемник ИК нашелся в корпусе, от какой-то китайского контроллера, в который он подключался через удлинитель с джеком 3,5 мм. Джек с кабелем был заменен на короткие выводы с мамами для подключения к GPIO Raspberry. +5V, земля и сигнал на GPIO23 (физический пин – 16), поскольку GPIO18 (физический пин – 12), который настроен для IR девайсов по умолчанию – уже занят выводом пакетов на подсветку. Получилось так:
Для подключения драйвера ИК-приемника нужно отредактировать файл /flash/config.txt, в самый конец добавить строку:
dtoverlay=gpio-ir,gpio_pin=23
Если пин под приемник остается GPIO18 (физический пин – 12), то часть после запятой не нужна. Он и так сконфигурирован по умолчанию. Иначе пишем свой пин, на который повесили ИК приемник, как в моем случае - gpio_pin=23. Вот только файл /flash/config.txt находится на разделе, смонтированном с параметром «только чтение», поэтому просто так его отредактировать не выйдет. В консоли Putty вводим:
mount -o remount,rw /flash
после чего файл можно править (до следующей перезагрузки Raspberry Pi)

После редактирования нужно сохранить изменения, перезагрузить Raspberry Pi. Следующим этапом пишем в консоль по очереди –
systemctl stop kodi
systemctl stop eventlircd
ir-keytable
Последняя команда должна вывести список доступных протоколов:
Вбиваем в консоль по очереди команды, заменяя только перечисленные выше протоколы и тыркаем пультом в ИК приемник. Если нет реакции, жмем ctrl+C, перебираем дальше.
ir-keytable -p lirc –t
ir-keytable -p rc-5 –t
ir-keytable -p rc-5-sz –t
ir-keytable -p nec -t
Пока не увидим что-то похожее на:
В моем случае подошел протокол NEC, посыпались скан-коды команд.
Список команд нужно привязать к скан-кодам клавиш. Скан-коды как на скрине выше получаем, нажимая нужные кнопки на пульте ДУ. А команды можно получить из файла /usr/share/kodi/system/Lircmap.xml в секции [/b] или набрав в другом окне консоли PuttY
irrecord -l | grep ^KEY
Далее в блокноте создаю текстовый файл, например – ireltex и сопоставляя нужные команды из списка со скан-кодами из консоли делаю следующее:
Первая строка обязательно должна присутствовать и будет такой:
table ireltex, type: NEC
За ней следуют по порядку разделенные пробелом скан-коды и привязанные к ним команды, которые берем по наитию из тегов в Lircmap.xml, в секции [b]
Скан-коды и команды разделены пробелом, кроме того - каждая строка должна заканчиваться пробелом, иначе считываться будет только последняя строка, т.е. на пульте будет работать одна кнопка, прописанная последней в таблице.
После опроса всех кнопок пульта получил такой список:
table ireltex, type: NEC
0x8f64d KEY_0
0x8f642 KEY_1
0x8f641 KEY_2
0x8f640 KEY_3
0x8f646 KEY_4
0x8f645 KEY_5
0x8f644 KEY_6
0x8f64a KEY_7
0x8f649 KEY_8
0x8f648 KEY_9
0x8f61a KEY_AUDIO
0x8f616 KEY_CHANNELDOWN
0x8f614 KEY_CHANNELUP
0x8f64e KEY_UP
0x8f65e KEY_DOWN
0x8f608 KEY_LEFT
0x8f604 KEY_RIGHT
0x8f615 KEY_OK
0x8f65d KEY_RED
0x8f659 KEY_GREEN
0x8f607 KEY_YELLOW
0x8f651 KEY_BLUE
0x8f61e KEY_MENU
0x8f623 KEY_EXIT
0x8f622 KEY_HOME
0x8f650 KEY_INFO
0x8f647 KEY_MUTE
0x8f654 KEY_PLAYPAUSE
0x8f6f1 KEY_SLEEP
0x8f643 KEY_WAKEUP
0x8f64f KEY_RECORD
0x8f61d KEY_VOLUMEDOWN
0x8f611 KEY_VOLUMEUP
0x8f61f KEY_ZOOM
И так, сопоставив кнопки их описаниям и скан-кодам, у меня вышло 34 команды:
Полученную таблицу сохраняю как ireltex и помещаю в папку rc_keymaps:
/storage/.config/rc_keymaps/ireltex
Создаю файл rc_maps.cfg:
/storage/.config/rc_maps.cfg
Пишу в «rc_maps.cfg» эту строку:
* * ireltex
Загружаю через консоль Putty полученную таблицу в драйвер:
ir-keytable -c -w /storage/.config/rc_keymaps/ireltex
Перезагружаю Raspberry Pi.
Размонтировав раздел, как делал до этого –
mount -o remount,rw /flash
изменяю последнюю строчку в файле /flash/config.txt
Теперь она выглядит так:
dtoverlay=gpio-ir,gpio_pin=23,rc-map-name=ireltex
В файл
/storage/.config/autostart.sh
нужно добавить автозагрузку протокола пульта, так чтобы запись выглядела так:#!/bin/sh
(
sleep 5
ir-keytable -p nec
)&
sleep 5
/storage/hyperion/bin/hyperiond.sh /storage/.config/hyperion.config.json > /storage/logfiles/hyperion.log 2>&1 &
Снова перезагружаю Raspberry Pi и теперь Kodi откликается на команды с пульта.
Если повесить выход ИК приемника кроме GPIO 23 так же на вход GPIO3 – Raspberry Pi будет включаться по команде с пульта.
Минус такого метода в том, что сигнал на включение будет приниматься любой и с любого ИК пульта, но других способов дистанционно включать малину я не нашел. Есть только возможность сделать дополнительный детектор, принимающий одну команду и передающий только этот сигнал на вход GPIO3 Raspberry Pi.
Чтобы не было чудес с самопроизвольным хаотичным мерцанием пикселей, земля ленты кроме пина GND GPIO должна соединяться непосредственно с минусовой клеммой внешнего источника питания проводом соответствующего току сечения, а сигнальный провод D-IN иметь минимальную длину.
Необходимо помнить, что различные ИК приемники могут имеют разное напряжение питания (3,3 или 5V) и назначение выводов. Чтобы не вывести из строя приемник или порты Raspberry Pi, подключение нужно делать в соответствии с документацией на используемый приемник!
В итоге все соединения на выводах GPIO Raspberry Pi:
Осталось настроить сам KODI - установить все нужные вам эддоны, настроить IPTV и расшарить контент с домашнего ПК. Не возьмусь судить, насколько оправданной будет замена андроид-приставки коробкой с Kodi, но для меня здесь основной фишкой была фоновая подсветка. Все равно TV как таковое я не смотрю, а контент с ПК по сети или с подключенной к Raspberry Pi флешки - идет на ура.
В любом случае можно использовать два варианта, включив устройства в разные HDMI входы на TV, благо их там как правило - несколько.
Если сравнивать с хардварным вариантом, описанным в другой статье – реакция на обработку кадров мне показалась более четкой, нет ощущения небольшой задержки в доли секунды.
Для тех, кто смотрит ТВ каналы – придется повозиться с плейлистами IPTV, эддонами и настройками плеера, или же остановиться на варианте с аппаратным граббером, который будет работать с любым HDMI источником.
Самым оптимальным вариантом был бы аналоговый сигнал со SCART разъема самого TV, но у меня как-то не вышло скормить его имеющемуся скейлеру).
Можно было бы так же настроить пульт от TV для управления интерфейсом Kodi через интерфей HDMI-CEC, но у меня этот ДУ несколько специфичный - с тачпадом и не очень удобный в использовании, поэтому ниже я покажу, как решить эту проблему кардинально
Некоторые полезные моменты по самому плееру KODI.
Для повседневного использования плеера я захотел избавиться от неубирающегося меню OSD, вызванного для перемотки или паузы. Для этого отлично пришелся эддон - Hide Video OSD
Скачиваем zip архив, кладем в удобное доступное малине место, в интерфейсе эддонов выбираем установку из архива, ставим, включаем эддон в настройках, задаем время в секундах, по истечении которого OSD уберется с экрана. Очень удобная штука.
Правильное включение Raspberry Pi с ИК пульта ДУ
Делаем правильное включение Raspberry Pi от назначенной кнопки на ИК пульте ДУ. Сейчас устройство загружается при поступлении любого сигнала на пин GPIO3 (пятый физический пин), а так как приемнику нет разницы, что принимать в этом ИК диапазоне, загрузка происходит от сигнала с любого пульта, иногда даже при включении освещения в комнате, что не есть удобно. Для решения этой проблемы между GPIO3 и сигнальным пином ИК приемника нужен посредник, который будет декодировать сигнал, и только при совпадении команды с заранее назначенной - включать Raspberry Pi. Кроме того, нужно иметь возможность использовать разные пульты или же кнопки одного пульта.Для этой задачи подойдет недорогой и компактный контроллер Arduino Nano. Плата будет постоянно работать в дежурном режиме и контролировать все входящие сигналы от любых ИК пультов. И только при декодировании одного из определенных заранее сигналов - давать команду на включение Raspberry Pi. Можно, конечно, сделать более простое устройство на Attiny, но это снизит повторяемость шилда и затруднит перепрошивку при необходимости смены пульта для Raspberry Pi.
Запитываться Arduino Nano будет не совсем стандартно - от пина +5V GPIO RPi – на пин +5V Arduino. Ничего страшного в таком включении нет – со стороны USB в плате Arduino будет вход внутреннего стабилизатора, со стороны пина Vin – катод диода Шоттки. Никакой нагрузки, кроме ИК приемника к выводам Arduino nano подключаться не будет.
Таблица соединений Arduino-Raspberry будет такой -
Кроме того, ИК приемник подключится к пинам питания на плате Arduino - (GND, +5V или 3.3V), а вывод выходного сигнала - через резисторы номиналом 100R – к пину D7 Arduino и через 510R к пину 16(GPIO23) Raspberry Pi. Таким образом ИК приемник будет напрямую передавать все команды на вход GPIO23, а на GPIO3 будет появляться короткий импульс только при получении заранее прописанных в скетче команд.
Схема подключения IR приемника, Arduino nano и адресной ленты к Raspberry Pi:
Верхний по схеме джампер «5V External» позволяет питаться Arduino и Raspberry от внешнего источника питания вместе с подсветкой от разъема XS1 «Power», если, например количество пикселей небольшое и не создает большой нагрузки.
Нижним по схеме джампером можно выбрать напряжение питания ИК приемника – 3.3 или 5V.
Устройство оформлено в виде внешнего, подключаемого к разъему GPIO шилда, в который подключена плата Arduino nano, ИК приемник и все разъемы.
Для его проверки достаточно предварительно считать и внести в скетч коды любых кнопок, например “OK” и “ENTER”, можно от разных пультов. При желании можно сделать массив команд, чтобы запускать приставку нажатием любой из определенной группы кнопок, кроме кнопок включения питания – их я использовать не стал, чтобы избежать отслеживания текущего статуса системы Raspberry Pi и не определять, какое действие необходимо выполнять – включение, или наоборот..
В скетче использована библиотека iarduino_IR-master, архив которой вместе со скетчем __IR_RPi.zip прилагаю -
В архиве библиотеки есть скетчи-примеры, используя один из них, например - receiver_GetProtokolAll, можно получить коды команд любых кнопок используемого пульта. В последующем эти коды нужно записать в заливаемый на Arduino Nano скетч:
//********************************************************************************************************
#include // Подключаем библиотеку для работы с ИК-приёмником
iarduino_IR_RX IR(7); // Объявляем объект IR, с указанием вывода к которому подключён ИК-приёмник
const int Out_GPOI_3 = 8; // Объявляем пин выхода на GPIO RPi
uint32_t Code_001 = 0xFF708F; // RX code опрошенных ранее кнопок
uint32_t Code_002 = 0x106FA857;
void setup()
{
pinMode(Out_GPOI_3, OUTPUT);
Serial.begin(9600); // Инициируем передачу данных в монитор последовательного порта, на скорости 9600 бит/сек
IR.begin(); // Инициируем работу с ИК-приёмником
}
void loop()
{
if(IR.check()) // Если была принята команда от какого либо ДУ
{
// Проверяем совпадение кодов на включение, дергаем вывод
if(IR.data == Code_001 or IR.data == Code_002)
{
digitalWrite(Out_GPOI_3, HIGH); // Передаем команду на RPi
delay(5);
digitalWrite(Out_GPOI_3, LOW); // Возвращаем выход в исходное состояние
delay(5);
digitalWrite(Out_GPOI_3, HIGH); // Передаем команду на RPi
delay(5);
digitalWrite(Out_GPOI_3, LOW); // Возвращаем выход в исходное состояние
delay(5);
}
}
}
//********************************************************************************************************
Поскольку библиотека iarduino_IR-master использует тот же таймер, что и некоторые стандартные «wiring» функции среды Arduino - в этом скетче нельзя использовать micros(), millis(), tone() и возможно некоторые другие, иначе попытка компиляции приведет к невнятной ошибке. Несмотря на такой подход авторов к написанию кода - свои функции библиотека исправно выполняет и четко определяет ИК посылки, их тайминги, структуру и используемые протоколы, а возможность быстро считать коды команд любого пульта сводят его настройку к простой замене переменных в скетче.
Собственно это было заключительной доработкой проекта, результатом которого стал домашний медиацентр с функцией фоновой подсветки экрана телевизора.
Вышеприведенная схема была разведена в виде шилда, к которому подключался модуль ардуино, а сам шилд – к малине на выводы GPIO. Также подоспели из Китая корпуса в виде радиаторов в двух вариантах цвета.
Несколько фотографий итогового результата в виде ТВ-приставки:
Бонус №1 - бесшовное цикличное воспроизведение рекламы с таймером.
Raspberry Pi с Kodi можно успешно использовать в проектах, где нужно постоянно и циклично воспроизводить контент. Для этого нужно немного подправить конфигурацию плеера.Вся проблема заключается не в том, чтобы заставить плеер воспроизводить видеоролики из конкретного каталога, а в том, что при старте каждого клипа отображается OSD с информацией – название, длительность, системное время итд.
Кроме того, при воспроизведении из плей-листа между роликами в любом случае возникает пауза и пустой экран.
Если первый вопрос как-то решаем, то с переходами между клипами я ничего придумать не смог.
Для начала избавляемся от назойливого OSD-инфо и OSD-меню. Так как скин я использую тот, что стоит в этой версии LibreElec по-умолчанию – нужно редактировать файлы по пути
/usr/share/kodi/addons/skin.estuary
Эти файлы находятся в разделе, защищенном от записи. Единственный доступный выход – создать клона скина здесь:
/storage/.kodi/addons/skin.estuary_2
То есть нужно перенести весь каталог skin.estuary из каталога addons, находящегося по первому пути в каталог addons, находящийся по второму пути, и переименовать его.
Например как в этом примере – каталог с клоном шкуры называется «skin.estuary_2».
Для всех операций я использовал WinSCP. Открываем файл конфигурации эддонов нового скина -
/storage/.kodi/addons/skin.estuary_2/addon.xml
и исправляем во второй строке ID и старое название эддона на новое. Строка будет теперь такой –
Сохраняем
addon.xml
и в интерфейсе Kodi после перезагрузки ищем появившийся новый скин Estuary_2 в «Мои дополнения», затем включаем его, выбираем эту обложку в настройках интерфеса, снова перезагружаемся. Потом через WinSCP баним скрипты, выводящие OSD во время проигрывания видео. Они находятся тут же, в каталоге
/storage/.kodi/addons/skin.estuary_2/xml
Их имена начинаются как «Dialog_LA_LA_LA. Переименовываем следующие файлы (я просто добавил # в начало каждого имени), чтобы вышло так:
#DialogBusy.xml, #DialogExtendedProgressBar.xml, #DialogPlayerProcessInfo.xml, #DialogSeekBar.xml
По-хорошему стоило бы, конечно, изучить-понять-найти и исправить нужные параметры в этих файлах, но с другой стороны – если плеер будет с автозапуска круглосуточно крутить зацикленный рекламный ролик или плей-лист – это не имеет никакого значения. Чтобы контент не нуждался в ручном запуске, нужно организовать автозапуск плеера при загрузке LibreElec. Файлы лежат на microSD в каталоге
«/storage/videos»
. Для этого создаем файл autoexec.py по следующему пути: /storage/.kodi/userdata/autoexec.py
В этот файл пишем взятый мной на одном из форумов скрипт –
#------------------------------------------------------------------------------------------------------------
# coding: utf-8
import os
import xbmc
import xbmcvfs
VIDEOS = '/storage/videos' # Folder with videofiles
VIDEO_EXTS = ('.avi', '.mp4', '.mkv')
DURATION = 28800.0 # time to play in seconds
monitor = xbmc.Monitor()
if monitor.waitForAbort(2.0):
raise SystemExit
playilst = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
dirs, files = xbmcvfs.listdir(VIDEOS)
files.sort()
for file_ in files:
if os.path.splitext(file_)[1].lower() in VIDEO_EXTS:
playilst.add(os.path.join(VIDEOS, file_))
player = xbmc.Player()
player.play(playilst)
xbmc.executebuiltin('PlayerControl(RepeatAll)')
monitor.waitForAbort(DURATION)
player.stop()
if not monitor.abortRequested():
xbmc.shutdown()
#------------------------------------------------------------------------------------------------------------
Здесь после импорта библиотек указывается путь к контенту на microSD карте, расширения видеофайлов, общая продолжительность воспроизведения файлов в циклах (28800 секунд – это 8 часов), задержка 2 секунды перед стартом плеера, создание плейлиста и воспроизведение.
Все файлы будут крутиться по кругу в течении 8 часов, один за другим. Но в этом есть один существенный минус – между роликами неизбежно возникает пауза, во время которой около секунды на экране ничего нет – он просто черный. Я решил немного модифицировать этот полезный скрипт. Чтобы избавиться от пауз, нужно крутить всего один файл до конца, а потом перематывать в начало. Так как обращение к монитору внутри цикла неизбежно его прерывает, для ограничения времени петли пришлось организовать простой счетчик времени.
Если в таком таймере нет необходимости, цикл можно сделать «вечным» - while True, удалив из скрипта все связанные со счетом общего времени строки.
С таймером это выглядит так -
#------------------------------------------------------------------------------------------------------------
# coding: utf-8
import os
import xbmc
import xbmcvfs
import time
VIDEOS = '/var/media/KINGSTON/content' # Folder with videofiles
VIDEO_EXTS = ('.avi', '.mp4', '.mkv')
DURATION = 5400.0 # time to play in seconds
TimeCounter = 0
time.sleep(3)
playilst = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
dirs, files = xbmcvfs.listdir(VIDEOS)
files.sort()
for file_ in files:
if os.path.splitext(file_)[1].lower() in VIDEO_EXTS:
playilst.add(os.path.join(VIDEOS, file_))
player = xbmc.Player()
player.play(playilst)
xbmc.executebuiltin('PlayerControl(RepeatAll)')
xbmc.sleep(1500) # ожидание начала воспроизведения ролика
PlayTotalTime = int (player.getTotalTime()) # получение длительности ролика
PlayTime = int(player.getTime()) # получение текущего времени воспроизведения
TimeToSleep = (PlayTotalTime - PlayTime)*1000 # время до конца ролика
while TimeCounter < DURATION: # в секундах
xbmc.sleep(TimeToSleep) # ожидание времени для перемотки – в миллисекундах
player.seekTime(0.1) # переход в начало – в секундах
if TimeCounter == 0: # состояние счетчика, первый проход
TimeToSleep = TimeToSleep + 1000 # корректировка времени ожидания для последующих циклов
TimeCounter = TimeCounter + PlayTotalTime # увеличение счетчика секунд
player.stop()
time.sleep(5)
xbmc.shutdown()
#------------------------------------------------------------------------------------------------------------
Здесь другой путь к файлу –
«/var/media/KINGSTON/content»
(просто для проверки). KINGSTON – обычная флешка в USB Raspberry Pi. Добавил строку «import time» для организации паузы после загрузки системы, и в конце скрипта загнал в бесконечный цикл перемотку на начало файла. В этом скрипте строка «DURATION = 5400.0 # time to play in seconds» так же задает общее время работы плеера, по истечении которого система выключается.
«TimeCounter = 0» – переменная для хранения времени воспроизведенных секунд, которые суммируются в процессе. После начала воспроизведения «player.play(playilst)» делается задержка, подбираемая опытным путем – «xbmc.sleep(1500) # ожидание начала воспроизведения ролика». Она нужна для гарантированного выполнения запросов «player.getTotalTime()» и «player.getTime()», которые вернут ошибку, если в этот момент плеер не начал воспроизведение файла. Возвращаемые в секундах значения имеют тип double, поэтому для дальнейшей работы их необходимо преобразовать к типу int, который принимает в качестве аргумента «xbmc.sleep», но уже в миллисекундах, поэтому нужно умножать секунды на 1000.
После получения текущего и общего времени строка «TimeToSleep = (PlayTotalTime - PlayTime)*1000» определяет необходимое время задержки для первого воспроизведения, и затем следует цикл, в условии которого сравнивается накопленное время воспроизведения с заданным.
После первой перемотки в цикле происходит корректировка времени ожидания - «TimeToSleep = TimeToSleep + 1000», добавляющая время (+1000 = +1 сек), неучтенное во втором и последующем воспроизведении за счет ранее выполненного ожидания «xbmc.sleep(1500)» Величина подбирается опытным путем так, чтобы перед перемоткой оказаться как можно ближе к концу файла, при этом не допустив окончания воспроизведения. Перемотка выполняется строкой «player.seekTime(0.1)», начиная повторное воспроизведения с 0,1-й секунды файла.
Когда TimeCounter превысит заданное время в DURATION, произойдет остановка плеера и отключение системы.
В результате получаем абсолютно бесшовный loop одного ролика без появления OSD после перемотки и задаваемым временем работы плеера в таком режиме!!!!!!!.
Это может быть удобным решением для рекламы чего-либо в течении дня с последующим отключением, а утром следующего дня специально обученному человеку достаточно включить малину - и процесс снова пойдет до вечера.
Бггг.. Неужели кто-то дочитал до этого места? Тогда держите -
Бонус №2 - небольшой ремонт USB портов Raspberry Pi B3+.
В процессе всех этих плясок успел столкнуться с ремонтом одной из купленных не задорого на известном ресурсе-барахолке Raspberry Pi B+. Случай частный, но не исключительный.На Raspberry Pi не работал ни один USB порт. Совсем. В общем-то на борту он всего один, а контроллер LAN7515 кроме сетевого интерфейса Gigabit Ethernet выполняет функции USB хаба, деля всю пропускную способность между 4 гнёздами USB и Ethernet. По идее, при выходе из строя LAN7515 - не будет ни того, ни другого. А у меня соединение LAN отлично работало, но на контрольной точке PP27 отсутствовало напряжение +5V.
В интернете много чего написано по поводу 7515, но практически нет информации по управлению питанием на USB выходах. Поиск привел только к такой вот картинке со схемой включения. LAN7515 управляет питанием через токоограничивающий ключ AP2553. Ключ способен пропускать ток до 2,36A, ограничение по току задается внешним резистором R41, при номинале по схеме максимальный ток составит 1,2A. Схема включения ключа (не факт, что в Raspberry Pi), если верить найденной картинке должна быть такой:
Вот это место на плате Raspberry Pi B, если не смотреть на не соответствующие позиции элементов найденной схемы и шелкографии на фото ниже:
А это распиновка ключа AP2553:

Нога 1 – вход, 2 – земля, 3 – управляющий сигнал высокого уровня, 4 – выход открытого на землю ключа при лимите тока, 5 – подключение токоограничивающего резистора, 6 – выход питания.
На всех досках Raspberry Pi B+, фотографии которых нашел (и на купленной мной) это место выглядит вот так:

Т.е. включение сильно упростили, убрав почти всю обвязку - диодную сборку, С30, подтягивающий R30 (по схеме выше). Неизвестно для чего, но оставили R29. И хотя измерения показали, что управляющий сигнал на вывод 3 после загрузки не приходит – решил на всякий случай подтянуть этот вход к 4-й ноге, установив резистор 1К на отмеченные желтым цветом точки. И тут все завелось. Порты заработали, причем 5V появились не тупо на постоянку, а именно управляемые, как и должно быть. Почему на этой Raspberry Pi было так, а на других все работает без подтяжки – я не знаю.