При проведении занятий и семинаров, да и при размещении нескольких экранов в больших залах возникает желание транслировать на них одну и ту же картинку. Конечно, для этого существуют готовые решения, но когда в загашнике есть Raspberry Pi, хочется побольше простору и гибкости. Поскольку для планирования трансляции можно написать какой угодно скрипт или даже программу, открываются следующие возможности:
- проигрывать плейлист по расписанию, в зависимости от времени дня и дня недели;
- делать рекламные вставки в паузах между видео, в том числе включающие трансляцию с собственных камер;
- автоматически менять программу в зависимости от посетителей;
- и многое, многое другое.
Поскольку RPi содержит только один HDMI выход, нам понадобится разветвитель, или сплиттер. Я ограничился двумя выходами и установил коробочку, которую купил на AliExpress (хвала Поднебесной!). К коробочке не предъявляется никаких особенных требований, за исключением того что сплиттер должен быть активным, т.е. обеспечивать усиление сигнала для компенсации потерь при разветвлении.
Плюс к коробочке — два десятиметровых HDMI кабеля, которые будут подключаться к ТВ экранам. Любой из современных плоских ТВ сейчас имеет HDMI вход, так что с этим проблем нет.
Раздача сигнала по Wi-Fi представляется мне плохой идеей, поскольку во-первых требует от ТВ наличия Smart модуля, что удорожает девайс, а во-вторых — забивает локальную сеть непрерывно идущим видеотрафиком. Поэтому все делаем строго по кабелям.
С точки зрения общего замысла все это выглядит так. RPi проигрывает медиа-файлы, расположенные на флешке, и направляет поток на HDMI выход. К нему подключен сплиттер, который формирует два идентичных выходных потока из входного для двух экранов. Вот и все. Дальше — детали, связанные с тем как всем этим управлять, то есть плавно переходим к программной начинке RPi.
Настройка софта Raspberry Pi
Начнем сначала — с флешки. В качестве таковой используем накопитель на 64Гб, который отформатируем в NTFS:
1 |
user@ubuntu:~ $ sudo mkntfs -f -L MEDIA /dev/sdb1 |
Флешка на моей машине опознается как sdb1, не перепутайте со своим жестким диском!
Почему NTFS? Чтобы иметь возможность записывать фильмы большого размера (>4Гб) и чтобы иметь возможность использовать флешку отдельно вместе с ТВ, поскольку Linux-файловые системы телевизор не понимает.
Далее, дадим RPi возможность автоматически монтировать флешку на старте (поскольку она все время будет вставлена в разъем), для чего добавляем строчку в /etc/fstab:
1 |
/dev/sda1 /mnt ntfs defaults,ro,umask=022 0 0 |
На RPi флешка опознается уже как sda1: в общем, смотрите внимательно, чтобы не потерять свой основной накопитель. Здесь есть несколько нюансов: файловая система монтируется как доступная только для чтения (read only), ведь нам ничего не нужно записывать туда, верно? И это страхует нас от необходимости чистить файловую систему ntfs после отключений питания. И кроме этого задаем маску, которая позволяет читать файловую систему всем, иначе доступ к ней будет только из под root.
Уже в этой точке вы можете полюбоваться одновременной трансляцией на два экрана, запустив плеер:
1 |
pi@rpi:~ $ omxplayer /mnt/film.mkv |
Почему именно omxplayer? Потому что он использует API чипов RPi, которые содержат аппаратные кодеки видео. Поэтому медиа-трансляция не нагружает АРМ процессор — декодирование потока из h.264 выполняется аппаратным кодеком. Запустите на RPi top и увидите, что загрузка CPU редко превышает 30%.
Если вы запустите обычный плеер, то перегруз процессора за 100% при воспроизведении видео вам гарантирован.
Далее, нужно сделать процесс удобоваримым для участников, которые не разбираются в удаленном доступе через ssh и работой в командной строке. Для этого на компе администратора (Ubuntu) я сварганил следующий Питоновский скрипт.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#!/usr/bin/python3 # -*- coding: utf-8 -*- from PyQt4.QtGui import * from PyQt4.QtCore import * import sys import os import time class myListWidget(QListWidget): def Clicked(self,item): cmd = "ssh -t pi@rpi.local pkill omxplayer" os.system(cmd) time.sleep(2) cmd = "nohup ssh -t pi@rpi.local /usr/bin/omxplayer /mnt/Films/%s > /dev/null 2> /dev/null &" % item.text() os.system(cmd) def main(): app = QApplication(sys.argv) listWidget = myListWidget() os.system('ssh -t pi@rpi.local "ls /mnt/Films" 1>/tmp/out.txt 2>/dev/null') string = open('/tmp/out.txt', 'r').read() #Resize width and height listWidget.resize(600,240) listWidget.addItems(string.split("\n")) listWidget.setWindowTitle('PyQT QListwidget Demo') listWidget.itemDoubleClicked.connect(listWidget.Clicked) listWidget.show() sys.exit(app.exec_()) if __name__ == '__main__': main() |
Скрипт показывает окошко на машине админа, в котором содержится список фильмов (точнее, видеофайлов). Двойным кликом на имени файла админ запускает трансляцию этого видео, после чего все могут смотреть кино сразу на двух экранах.
Чтобы скрипт работал, нужно обеспечить беспрепятственный доступ к RPi с машины админа, а именно — однократно запустить команду
1 |
user@ubuntu:~ $ ssh-copy-id rpi.local |
где rpi.local — адрес малышки RPi. В результате будут сформированы ключи и не нужно будет каждый раз вводить пароль при запуске скрипта.
При запуске скрипт заходит на RPi по ssh и командой ls /mnt формирует список видео, который сохраняется в локальном файле /tmp/out.txt. Мы же помним, что после автомонтирования на /mnt у нас теперь файловая система NFTS флешки? Далее, из этого файла формируется список, который выводится в окне.
При двойном клике на имени файла из списка, опять таки через ssh запускается omxplayer с заданным именем файла в качестве аргумента. Чтобы избежать повторных запусков разных видео, каждый раз перед запуском плеера все его процессы убиваются.
Если взять скрипт за основу, то можно делать все эти вещи, которые я привел в начале статьи. Да, и чуть не забыл: доступ к RPi обеспечивается через Wi-Fi свисток (донгл), который находится в локальной сети. Если назначение системы — просто непрерывно крутить плейлист, тогда и связь по Wi-Fi не нужна.
Когда будете воспроизводить систему, убедитесь в этом что источник питания RPi содержит достаточный запас по мощности: все таки два занятых USB порта и работающий Wi-Fi это хорошая нагрузка.
Ответить