Initial commit
authorDmitry Shalnoff <dev@shalnoff.com>
Wed, 8 Jul 2020 23:25:57 +0000 (01:25 +0200)
committerDmitry Shalnoff <dev@shalnoff.com>
Wed, 8 Jul 2020 23:25:57 +0000 (01:25 +0200)
27 files changed:
.gitignore [new file with mode: 0644]
README.md [new file with mode: 0644]
dbuscontrol.sh [new file with mode: 0755]
early_init.sh [new file with mode: 0755]
freefont/FreeMono.ttf [new file with mode: 0644]
freefont/FreeMonoBold.ttf [new file with mode: 0644]
freefont/FreeMonoBoldOblique.ttf [new file with mode: 0644]
freefont/FreeMonoOblique.ttf [new file with mode: 0644]
freefont/FreeSans.ttf [new file with mode: 0644]
freefont/FreeSansBold.ttf [new file with mode: 0644]
freefont/FreeSansBoldOblique.ttf [new file with mode: 0644]
freefont/FreeSansOblique.ttf [new file with mode: 0644]
freefont/FreeSerif.ttf [new file with mode: 0644]
freefont/FreeSerifBold.ttf [new file with mode: 0644]
freefont/FreeSerifBoldItalic.ttf [new file with mode: 0644]
freefont/FreeSerifItalic.ttf [new file with mode: 0644]
leds.sh [new file with mode: 0755]
playlist.sh [new file with mode: 0755]
playmovie.sh [new file with mode: 0755]
reboot.sh [new file with mode: 0755]
remoteir.sh [new file with mode: 0755]
renewplaylist.sh [new file with mode: 0755]
splash.png [new file with mode: 0644]
splash_loading.png [new file with mode: 0644]
splash_loading_new.png [new file with mode: 0644]
splash_loading_pause.png [new file with mode: 0644]
start.babooshka.sh [new file with mode: 0755]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..e2c3fa5
--- /dev/null
@@ -0,0 +1,5 @@
+playlist
+currentpos
+currenttrack
+VIDEO/
+YOUTUBE/
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..1ebec86
--- /dev/null
+++ b/README.md
@@ -0,0 +1,379 @@
+# [babooshka.tv](https://babooshka.tv) old-school tv-box video player
+
+This simple and lightweight package could turn your RPi into a video player. The package is designed primarily for your grandparents, for whom the use of a computer is a difficult task. You can upload your home kittens-kids videos or add videos from Youtube/Vimeo that you like. 
+
+The package is fully written in bash. 
+
+![babooshka.tv RPi based prototype](https://repository.interplaymedium.org/babooshka.tv/babooshka.tv.rpi.jpeg)  
+
+## Wiring
+
+[Pi Zero IO Pinout](https://pinout.xyz/pinout/io_pi_zero)
+
+The yellow LED connected to +3,3v via 470R 
+
+    GPIO 0     BCM17   LED green, booting  
+    GPIO 2     BCM27   LED red, video status  
+
+Lowering resistors are required for all diodes (Red LEDs normally brighter, so I would recommend ~470R for yellow and green and about 1K for red)
+
+### Infrared interface
+
+    GPIO 3     BCM22   IR TX  
+    GPIO 4     BCM23   IR RX  
+
+        38kHz -- most popular 
+
+        +-----------------------+ 3
+        |               data -> +---------------------o +3.3V
+        |      ______________   |
+        |     /                 |
+        |    (                  | 2  
+        |     \______________ + +---------------------o GND
+        |                       |
+        |                       | 1
+        |                     - +---------------------o GPIO 4 (BCM23)
+        +-----------------------+
+
+
+        950nm emitting diode (e.g. TSUS5400)
+
+                         +5V
+                          o
+                          |
+                         | | 51 Ohm (depending on MOSFET maybe not required)
+                         |_|
+                          |
+                         _|_
+                         \ / 
+                         ---  --> IR LED
+                          |
+           MOSFET         |
+             ___      |---'
+      o-----|___|-----|
+             10K      |->--
+        GPIO 3 (BCM22)     |
+                           |
+                        ----- GND
+                         ---
+                          - 
+
+### Analog Audio 
+
+    GPIO 1     BCM18   R AUDIO
+    GPIO 23    BCM13   L AUDIO
+
+![RPi Zero Audio](https://repository.interplaymedium.org/babooshka.tv/pi-zero-audio_bb.jpg)  
+Picture taken [from here](https://shallowsky.com/blog/hardware/pi-zero-audio.html), thanks :)  
+
+### Analog video pin
+
+![RPi TV out](https://repository.interplaymedium.org/babooshka.tv/RPi_TV_out.jpeg)  
+Picture taken [from here](https://magpi.raspberrypi.org/articles/rca-pi-zero), thanks :)  
+
+## Setup
+
+Download, copy to microSD and install oficial [Raspberry Pi OS Lite image](https://www.raspberrypi.org/downloads/raspberry-pi-os/)
+
+The procedure of adding a login and password for your access point, as well as the ssh configuration is omitted. It is assumed that you know how to do so :)  
+If you not sure, [ddg it](https://duckduckgo.com/?q=RPi+headless+how+setup+and+ssh).
+
+Further operations are performed on device.
+
+    ssh <your RPi device>
+
+Update repository list and install dependencies 
+
+    apt update  
+    apt install mc fbi omxplayer sox
+
+Try to install freefonts (required by omxplayer)
+
+    apt install freefonts
+
+By some reason recently *freefonts* package has been removed from official RPi repository. So in case of unsuccess just copy included freefonts to /usr/share/fonts/truetype/...  
+do it with *sudo*
+
+    cp -r freefont /usr/share/fonts/truetype/freefont  
+    chown root:root /usr/share/fonts/truetype/freefont  
+    chown root:root /usr/share/fonts/truetype/freefont/*
+
+### IR interface setup
+
+    apt install lirc
+
+edit /etc/lirc/hardware.conf
+
+    # Run "lircd --driver=help" for a list of supported drivers.  
+    DRIVER="default"
+
+    # usually /dev/lirc0 is the correct setting for systems using udev  
+    DEVICE="/dev/lirc1"  
+    MODULES="gpio_ir_recv"
+
+edit /etc/lirc/lirc_options.conf
+NOTE! add new line in the end of the file !!!! [known bug](https://forum.odroid.com/viewtopic.php?t=32181)
+
+    driver          = default  
+    device          = /dev/lirc1
+
+First try to find you device using 
+
+    irdb-get find YOUR_DEVICE  
+
+In case of unsiccess try to find and copy YOUR_DEVICE.conf for your remote controller to */etc/lirc/lircd.conf.d/* 
+Here is a [list of devices](http://lirc-remotes.sourceforge.net/remotes-table.html) supported by Lirc 'from the box'. However, you always can record your own, see below... 
+
+Copy template lircd.conf
+
+    cp /etc/lirc/lircd.conf.dist /etc/lirc/lircd.conf
+
+Make changes in */boot/config.txt* to set up PAL video output and run appropriate kernel overlays for IR interface:
+
+    disable_splash=1
+    
+    # disable_overscan=1
+
+    framebuffer_width=720
+    framebuffer_height=576
+
+    # enable PWM audio (add this line)
+    dtoverlay=pwm-2chan,pin=18,func=2,pin2=13,func2=4
+
+    # uncomment for composite PAL
+    sdtv_mode=2
+
+    # uncomment if hdmi display is not detected and composite is being output
+    # hdmi_force_hotplug=1
+
+    # Uncomment this to enable the gpio-ir module
+    dtoverlay=gpio-ir,gpio_pin=23,gpio_pull=up
+    dtoverlay=gpio-ir-tx,gpio_pin=22
+
+### Make IR works as TX and RX simultanoiously
+
+This part taken from [this GitHub comment](https://github.com/raspberrypi/linux/issues/2993#issuecomment-497420228) thank you [@elmicha](https://github.com/elmicha) :)
+
+Add these rules in */etc/udev/rules.d/71-lirc.rules* to get stable */dev/lirc-rx* and */dev/lirc-tx* device names:
+
+    ACTION=="add", SUBSYSTEM=="lirc", DRIVERS=="gpio_ir_recv", SYMLINK+="lirc-rx"
+    ACTION=="add", SUBSYSTEM=="lirc", DRIVERS=="gpio-ir-tx", SYMLINK+="lirc-tx"
+    ACTION=="add", SUBSYSTEM=="lirc", DRIVERS=="pwm-ir-tx", SYMLINK+="lirc-tx"
+
+Change the device and listening address in /etc/lirc/lirc_options.conf:
+
+    device          = /dev/lirc-rx
+    listen          = 0.0.0.0:8766
+
+Copy lirc_options.conf to lirc_tx_options.conf and edit these lines:
+
+    device          = /dev/lirc-tx
+    output          = /var/run/lirc/lircd-tx
+    pidfile         = /var/run/lirc/lircd-tx.pid
+    listen          = 0.0.0.0:8765
+    connect         = 127.0.0.1:8766
+
+Create */etc/systemd/system/lircd-tx.service* (from the output of *systemctl cat lircd*) and edit it like this:
+
+    [Unit]  
+    Documentation=man:lircd(8)  
+    Documentation=http://lirc.org/html/configure.html  
+    Description=Second lircd, the transmitter  
+    Wants=lircd-setup.service  
+    After=network.target lircd-setup.service lircd.service  
+    
+    [Service]  
+    Type=simple  
+    ExecStart=/usr/sbin/lircd --nodaemon --options-file /etc/lirc/lirc_tx_options.conf  
+    
+    [Install]  
+    WantedBy=multi-user.target  
+    Create /etc/systemd/system/lircd-tx.socket (from the output of systemctl cat lircd.socket) and edit it:  
+    
+    [Socket]  
+    ListenStream=/run/lirc/lircd-tx  
+    
+    [Install]  
+    WantedBy=sockets.target  
+    Also=lircd-tx.service  
+
+
+Create /usr/local/bin/irsend and make it executable
+
+    #! /bin/sh  
+    exec /usr/bin/irsend --device=/var/run/lirc/lircd-tx "$@"
+
+Start lircd-tx (with *sudo*)
+
+    systemctl daemon-reload
+    systemctl start lircd-tx
+    systemctl enable lircd-tx
+
+Enable RX (with *sudo*)
+    systemctl enable lircd.service
+    systemctl enable lircd.socket
+
+    systemctl restart lircd
+
+NOTE: there maybe the Warning of duplication of "begin remote .. end remote", it is fine. Ignore it. 
+
+Reboot and check status :)
+
+    systemctl reboot
+
+    systemctl status lircd.service
+    systemctl status lircd.socket
+
+### Test IR 
+
+Send some command. replace vendor and command with your
+
+    irsend SEND_ONCE SONY-TV KEY_1
+
+Read RX 
+    irw
+
+Record your own (if you have no compatible remote control or incomplete config)
+
+    systemctl stop lircd.socket
+    systemctl stop lircd.service
+    
+    record with own key names
+    irrecord --disable-namespace
+
+    systemctl start lircd.socket
+    systemctl start lircd.service
+
+Force raw record mode (normally not required)
+    
+    irrecord -f -d /dev/lirc0 ~/lirc.conf
+
+## Main package installation
+
+    cd /home/pi/
+    git clone <this repo> (see above)
+    cd BABOOSHKA.TV/
+
+Make sure that all .sh files inside are executable (have x flag)
+
+    ls --all 
+
+if required make them *chmod +x *.sh*
+
+### Early stage systemd service (launching led driver and creating splash image)
+
+Create */etc/systemd/system/splash.service* file and add there
+
+    [Unit]  
+    DefaultDependencies=no  
+    After=local-fs.target  
+    
+    [Service]  
+    StandardInput=tty  
+    StandardOutput=tty  
+    ExecStart=/home/pi/BABOOSHKA.TV/early_init.sh  
+      
+    [Install]  
+    WantedBy=sysinit.target  
+
+Activate the service 
+
+    sudo systemctl enable splash.service
+
+### On boot launcher
+
+Add this line to */etc/rc.local*
+
+   sudo -H -u pi /home/pi/babooshka.tv/start.babooshka.sh > /dev/null &
+
+reboot and test :)
+
+       systemctl reboot
+
+if everything has been done properly, you will see the splash babooshka.tv logo
+
+- add testing video in *~/BABOOSHKA.TV/VIDEO/* directory
+- check playlist (that the video link has been added)
+- click PLAY on your remote 
+- if something went wrong, see Debug section below
+
+## Cosmetic polishing 
+
+Edit */boot/cmdline.txt*. Make sure that you have *console=tty3 quiet consoleblank=0* and *logo.nologo*, this is my cmdline: 
+
+    console=serial0,115200 console=tty3 quiet consoleblank=0 loglevel=1 root=PARTUUID=6c586e13-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait logo.nologo
+
+Disable blinking cursor (probably not required)
+
+    vt.global_cursor_default=0
+
+Remove tty login service to eliminate blinking cursor
+    
+    sudo systemctl disable getty@tty1 
+
+## Additional software 
+
+If' you're going to watch videos from YouTube, Vimeo and so on, this packages would be required. Most porbably probably would beed to install youtube-dl globally. So do that with *sudo -H ...*. It would be recommended wor futher compatibility. 
+
+    apt install mkvtoolnix python-pip
+    pip install -U youtube-dl
+
+## Usage
+
+converting video (note -level 3.0 option! it is required for RPi HW codec)
+
+    ffmpeg -i FILEIN -vcodec libx264 -preset slow -level 3.0 -b 700k -s 720x404 FILEOUT
+
+upload new video from local PC 
+
+    scp <your_super_cool_kitten_flick.mp4>  <babooshka>:BABOOSHKA.TV/VIDEO/
+
+download new video from youtube (on device)
+
+    youtube-dl -f 'bestvideo[vcodec=avc1][height<=720]+bestaudio/best[abr<=120]' --merge-output-format mp4 -o '%(playlist_index)s - %(title)s.%(ext)s' <youtube link>
+
+click PLAY button and enjoy :)
+
+## Debug
+
+    tail -F /tmp/babooshka.log
+
+## Known bugs
+
+- Not changing the state on finish (WATCHED) if video has been resumed (time of resuming is disregarded)
+
+## Todo
+
+- WiFi auto-reconnect, probably *sudo iw dev wlan0 set power_save off* would be helpful
+- youtube-dl, autoupdate
+- youtube-dl download from downloadlist
+- check free storage space
+- auto removing of old videos + commenting in playlist
+- splash info, Nth video from COUNT videos
+- Make a single package
+
+## Extras 
+
+Download this nice babooshka.tv [sticker and logo](https://repository.interplaymedium.org/babooshka.tv/babooshka_sticker.svg)
+
+![babooshka.tv found enclosure and cool sticker](https://repository.interplaymedium.org/babooshka.tv/babooshka.tv.enclosure_front.jpeg)
+
+## License
+
+Copyright © 2020 Dmitry Shalnov [interplaymedium.org]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this files except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+
+
diff --git a/dbuscontrol.sh b/dbuscontrol.sh
new file mode 100755 (executable)
index 0000000..48d792a
--- /dev/null
@@ -0,0 +1,176 @@
+#!/bin/bash
+
+#set -x
+
+OMXPLAYER_DBUS_ADDR="/tmp/omxplayerdbus.${USER:-root}"
+OMXPLAYER_DBUS_PID="/tmp/omxplayerdbus.${USER:-root}.pid"
+
+# OMXPLAYER_DBUS_ADDR="/tmp/omxplayerdbus.pi"
+# OMXPLAYER_DBUS_PID="/tmp/omxplayerdbus.pi.pid"
+
+export DBUS_SESSION_BUS_ADDRESS=`cat $OMXPLAYER_DBUS_ADDR`
+export DBUS_SESSION_BUS_PID=`cat $OMXPLAYER_DBUS_PID`
+
+[ -z "$DBUS_SESSION_BUS_ADDRESS" ] && { echo "Must have DBUS_SESSION_BUS_ADDRESS" >&2; exit 1; }
+
+case $1 in
+       status)
+               duration=`dbus-send --print-reply=literal --session --reply-timeout=500 --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:"org.mpris.MediaPlayer2.Player" string:"Duration"`
+               [ $? -ne 0 ] && exit 1
+               duration="$(awk '{print $2}' <<< "$duration")"
+
+               position=`dbus-send --print-reply=literal --session --reply-timeout=500 --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:"org.mpris.MediaPlayer2.Player" string:"Position"`
+               [ $? -ne 0 ] && exit 1
+               position="$(awk '{print $2}' <<< "$position")"
+
+               playstatus=`dbus-send --print-reply=literal --session --reply-timeout=500 --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:"org.mpris.MediaPlayer2.Player" string:"PlaybackStatus"`
+               [ $? -ne 0 ] && exit 1
+               playstatus="$(sed 's/^ *//;s/ *$//;' <<< "$playstatus")"
+
+               paused="true"
+               [ "$playstatus" == "Playing" ] && paused="false"
+               echo "Duration: $duration"
+               echo "Position: $position"
+               echo "Paused: $paused"
+               ;;
+
+       volume)
+               volume=`dbus-send --print-reply=double --session --reply-timeout=500 --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set string:"org.mpris.MediaPlayer2.Player" string:"Volume" ${2:+double:}$2`
+               [ $? -ne 0 ] && exit 1
+               volume="$(awk '{print $2}' <<< "$volume")"
+               echo "Volume: $volume"
+               ;;
+
+       list)   # list dbus interfaces
+
+               dbus-send --session --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.ListNames
+#              dbus-send --print-reply=literal --type=method_call --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2  org.freedesktop.DBus.Introspectable.Introspect
+               ;;
+
+       pause)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:16 >/dev/null
+               ;;
+
+       info)   # doesn't work IMHO
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:5
+               ;;
+
+       action) # universal  
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:$2 >/dev/null
+               ;;
+
+#      -----------------------------------------------
+
+       subslist)
+               subslist=`dbus-send --print-reply --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.ListSubtitles`
+#              [ $? -ne 0 ] && exit 1
+               echo "$subslist" | grep string
+               ;;
+
+       togglesubtitles)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:12 >/dev/null
+               ;;
+               
+       hidesubtitles)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:30 >/dev/null
+               ;;
+
+       showsubtitles)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:31 >/dev/null
+               ;;
+       subsnext)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:11 >/dev/null
+               ;;
+       subsprev)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:10 >/dev/null
+               ;;
+
+#      -----------------------------------------------
+
+       audiolist)
+               audiolist=`dbus-send --print-reply --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.ListAudio`
+#              [ $? -ne 0 ] && exit 1
+               echo "$audiolist" | grep string
+               ;;
+
+       audiom)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:6 >/dev/null
+               ;;
+
+       audiop)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:7 >/dev/null
+               ;;
+
+#      -----------------------------------------------
+
+       seekfl) # seek forward large step
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:22 >/dev/null
+               ;;
+
+       seekbl) # seek backward large step
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:21 >/dev/null
+               ;;
+
+       seekf)  # seek forward large step
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:20 >/dev/null
+               ;;
+
+       seekb)  # seek backward large step
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:19 >/dev/null
+               ;;
+
+#      -----------------------------------------------
+
+       stop)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:15 >/dev/null
+               ;;
+
+       seek)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Seek int64:$2 >/dev/null
+               ;;
+
+       setposition)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.SetPosition objpath:/not/used int64:$2 >/dev/null
+               ;;
+
+       setalpha)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.SetAlpha objpath:/not/used int64:$2 >/dev/null
+               ;;
+
+       setvideopos)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.VideoPos objpath:/not/used string:"$2 $3 $4 $5" >/dev/null
+               ;;
+
+       setvideocroppos)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.SetVideoCropPos objpath:/not/used string:"$2 $3 $4 $5" >/dev/null
+               ;;
+
+       setaspectmode)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.SetAspectMode objpath:/not/used string:"$2" >/dev/null
+               ;;
+
+       hidevideo)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:28 >/dev/null
+               ;;
+
+       unhidevideo)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:29 >/dev/null
+               ;;
+
+       volumeup)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:18 >/dev/null
+               ;;
+
+       volumedown)
+               dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Action int32:17 >/dev/null
+               ;;
+               
+       getsource)
+               source=$(dbus-send --print-reply=literal --session --reply-timeout=500 --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.GetSource)
+               echo "$source" | sed 's/^ *//'
+               ;;
+       *)
+               echo "usage: $0 status|pause|stop|seek|volumeup|volumedown|setposition [position in microseconds]|hidevideo|unhidevideo|togglesubtitles|hidesubtitles|showsubtitles|setvideopos [x1 y1 x2 y2]|setvideocroppos [x1 y1 x2 y2]|setaspectmode [letterbox,fill,stretch,default]|setalpha [alpha (0..255)]|getsource" >&2
+               exit 1
+               ;;
+esac
diff --git a/early_init.sh b/early_init.sh
new file mode 100755 (executable)
index 0000000..56e186b
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+export BABOOSHKA_HOME=/home/pi/BABOOSHKA.TV/
+
+# run booting led and led daemon 
+$BABOOSHKA_HOME/leds.sh 2>&1 >/dev/null &
+
+# show splash image
+/usr/bin/fbi -d /dev/fb0 --once --noverbose --autozoom $BABOOSHKA_HOME/splash.png
+
+exit 0
diff --git a/freefont/FreeMono.ttf b/freefont/FreeMono.ttf
new file mode 100644 (file)
index 0000000..61d8263
Binary files /dev/null and b/freefont/FreeMono.ttf differ
diff --git a/freefont/FreeMonoBold.ttf b/freefont/FreeMonoBold.ttf
new file mode 100644 (file)
index 0000000..2212613
Binary files /dev/null and b/freefont/FreeMonoBold.ttf differ
diff --git a/freefont/FreeMonoBoldOblique.ttf b/freefont/FreeMonoBoldOblique.ttf
new file mode 100644 (file)
index 0000000..16d9cd7
Binary files /dev/null and b/freefont/FreeMonoBoldOblique.ttf differ
diff --git a/freefont/FreeMonoOblique.ttf b/freefont/FreeMonoOblique.ttf
new file mode 100644 (file)
index 0000000..7a11773
Binary files /dev/null and b/freefont/FreeMonoOblique.ttf differ
diff --git a/freefont/FreeSans.ttf b/freefont/FreeSans.ttf
new file mode 100644 (file)
index 0000000..81b0509
Binary files /dev/null and b/freefont/FreeSans.ttf differ
diff --git a/freefont/FreeSansBold.ttf b/freefont/FreeSansBold.ttf
new file mode 100644 (file)
index 0000000..a1ec0a3
Binary files /dev/null and b/freefont/FreeSansBold.ttf differ
diff --git a/freefont/FreeSansBoldOblique.ttf b/freefont/FreeSansBoldOblique.ttf
new file mode 100644 (file)
index 0000000..5d2acfe
Binary files /dev/null and b/freefont/FreeSansBoldOblique.ttf differ
diff --git a/freefont/FreeSansOblique.ttf b/freefont/FreeSansOblique.ttf
new file mode 100644 (file)
index 0000000..f5521bc
Binary files /dev/null and b/freefont/FreeSansOblique.ttf differ
diff --git a/freefont/FreeSerif.ttf b/freefont/FreeSerif.ttf
new file mode 100644 (file)
index 0000000..21609e1
Binary files /dev/null and b/freefont/FreeSerif.ttf differ
diff --git a/freefont/FreeSerifBold.ttf b/freefont/FreeSerifBold.ttf
new file mode 100644 (file)
index 0000000..c3254c8
Binary files /dev/null and b/freefont/FreeSerifBold.ttf differ
diff --git a/freefont/FreeSerifBoldItalic.ttf b/freefont/FreeSerifBoldItalic.ttf
new file mode 100644 (file)
index 0000000..49669fd
Binary files /dev/null and b/freefont/FreeSerifBoldItalic.ttf differ
diff --git a/freefont/FreeSerifItalic.ttf b/freefont/FreeSerifItalic.ttf
new file mode 100644 (file)
index 0000000..fd06aab
Binary files /dev/null and b/freefont/FreeSerifItalic.ttf differ
diff --git a/leds.sh b/leds.sh
new file mode 100755 (executable)
index 0000000..8783eca
--- /dev/null
+++ b/leds.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+echo "leds on"
+
+LEDS_CONTROL=/tmp/bbshk_leds
+LED_BOOT=2
+LED_VIDEO=0
+
+# touch $LEDS_CONTROL
+# gpio write $LED_BOOT 1
+
+gpio mode 0 out                # II    green
+gpio mode 2 out                # III   red
+
+while [ 1 ]; do
+
+       LEDS_STATE=$(cat $LEDS_CONTROL)
+
+       case "$LEDS_STATE" in
+               "BOOTCOMPLETE")
+                       gpio write $LED_BOOT 1
+               ;;
+
+               "NEWVIDEO")
+                       if [ -z $ONOFF ]; then 
+                               gpio write $LED_VIDEO 0
+                               ONOFF=1
+                       else 
+                               gpio write $LED_VIDEO 1
+                               ONOFF=''
+                       fi 
+               ;;
+
+               "VIDEOSTARTED")
+                       gpio write $LED_VIDEO 1
+               ;;
+
+               "VIDEOCOMPLETE")
+                       gpio write $LED_VIDEO 0
+               ;;
+
+               *) # booting
+                       echo $LEDS_STATE
+                       if [ -z $ONOFF ]; then 
+                               gpio write $LED_BOOT 0
+                               ONOFF=1
+                       else 
+                               gpio write $LED_BOOT 1
+                               ONOFF=''
+                       fi 
+               ;;
+       esac 
+
+       sleep 0.5s
+done
diff --git a/playlist.sh b/playlist.sh
new file mode 100755 (executable)
index 0000000..b7c5643
--- /dev/null
@@ -0,0 +1,365 @@
+#!/bin/bash
+
+if [ $# -lt 1 ]; then
+
+       echo "IM Playlist Player. Created for BABOOSHKA.TV™ project (https://babooshka.tv)"
+       echo "Copyright © 2020 Dmitry Shalnov [interplaymedium.org]"
+       echo "Licensed under the Apache License, Version 2.0"
+
+       echo "Usage: $0 -p <playlist> [options]"
+       echo "-v <arg>  volume amp in dB>" 
+       echo "-f <arg>  play from Nth file in the playlist"
+       echo "-a <erg>  set audio track"
+       echo "-m <arg>  video mode in WxH format"
+       echo "-t <arg>  subtitle track number"
+       echo "-s                stop after"
+       echo "-o                play list once (make sence if you're not using -s option)"
+       echo "Dependences: omxplayer, ttf-freefont"
+       echo "Playlist format (using TAB delimiter): <file with path (no escapes)> [comment] [additional options] [position] [state]"
+       echo "Use ';' symbol to comment playlist lines if needed"
+       exit 1
+fi
+
+# BABOOSHKA_HOME=/home/pi      # assigned in start.babooshka.sh
+
+SAVE_PATH=$BABOOSHKA_HOME
+DBUS_CTRL_FILE=/tmp/dbuscontrol_command
+VOLUME=0
+LEDS_CONTROL=/tmp/bbshk_leds
+CNT=1
+
+# ------------------- parse commandline ----------------------
+
+parserCnt=0
+
+while [ "$#" -gt 0 ] && [ "$parserCnt" -lt 20 ] ; do
+       case "$1" in
+#              -i) MEDIAPATH="$2"; shift 2;;           # media file
+               -p) PLAYLIST="$2"; shift 2;;            # media file
+               -v) VOLUME="$2"; shift 2;;              # volume amp
+               -f) START_FROM="$2"; shift 2;;                  # from Nth file, 0 is random order
+               -a) PREF_LANG="$2"; shift 2;;           # audio track prefered language pattern, e.g. ":ру|:ru"
+               -m) VIDEOMODE="$2"; shift 2;;           # video mode
+               -t) SUBTITLES="$2"; shift 2;;           # volume amp
+               -s) PLAYSINGLE=1; shift 1;;             # play file by file with stops (no parameter required)
+               -o) PLAYLISTONCE=1; shift 1;;           # play list once (no parameter required)
+
+               -*) echo "unknown option: $1" >&2; exit 1;;
+#              *) handle_argument "$1"; shift 1;;
+               *) sleep 0; shift 1;;
+       esac
+       parserCnt=$(( $parserCnt + 1 ))
+done
+
+if [ "$SUBTITLES" != "" ]; then SUBTITLES_SET="-t $SUBTITLES"; fi
+
+if [ -z "$PLAYLIST" ]; then
+       echo "Playlist is not assigned. Please use -p option."
+       exit 0
+fi
+
+# -------------------------------------------------------------------
+
+killCCONTROL() {       # function called by trap (Ctrl-C handler)
+
+       kill -9 $WAIT1_PID 2>/dev/null
+       kill -9 $WAIT2_PID 2>/dev/null
+       kill -9 $WAIT3_PID 2>/dev/null
+       kill -9 $PLAYLIST_CHANGE_PID 2>/dev/null
+       echo "Have a nice day..."
+       exit 0
+}
+
+trap 'killCCONTROL' 2
+
+waiting_for_press_play() {
+       echo "waiting for PLAY button press... "; 
+       while [ "$DBUS_COMMAND" != "PLAY" ]; do
+               DBUS_COMMAND=$(cat $DBUS_CTRL_FILE)
+#              echo -n "."
+               sleep 1
+       done
+#      echo ''
+}
+
+waiting_for_player_start() {
+       echo "waiting for playback starting... "; 
+       while ! ./dbuscontrol.sh status 1>/dev/null 2>/dev/null ; do 
+#              echo -n "+"
+               sleep 1
+       done
+#      echo ''
+}
+
+# check for unwatched / not completed video and turn RED LED on
+
+check_video_complete(){
+
+       if grep -v -P "\tPLAY|\tWATCHED" "$1" | grep "^[^#;]" >/dev/null ; then 
+
+               lastLedState=$(cat $LEDS_CONTROL)
+               currentPos=$(cat $SAVE_PATH/currentpos)
+
+               # make new video current (if previous one has not been paused and all videos has been watched)
+
+               if [ "$lastLedState" == "VIDEOCOMPLETE" ] && [ "$currentPos" == '' ]; then 
+                       newVideo=$(grep -v -P "\tPLAY|\tWATCHED" "$1" | grep "^[^#;]" | head -1 | awk '{split($0,a,"\t"); print a[1]}')
+                       echo $newVideo > $SAVE_PATH/currenttrack
+                       echo "Playlist changed: $newVideo"
+               fi 
+
+#              echo 'NEWVIDEO'
+               echo "NEWVIDEO" > "$LEDS_CONTROL"
+       else 
+               if grep -P "\tPLAY" "$1" | grep "^[^#;]" >/dev/null ; then
+#                      echo 'VIDEOSTARTED'
+                       echo "VIDEOSTARTED" > "$LEDS_CONTROL"
+               else 
+#                      echo 'VIDEOCOMPLETE'
+                       echo "VIDEOCOMPLETE" > "$LEDS_CONTROL"
+               fi
+       fi
+}
+
+# check_video_complete "$PLAYLIST"
+
+# background checking for external playlist changes
+
+{      
+       while [ 1 ]; do 
+               check_video_complete "$PLAYLIST"
+               sleep 10
+       done
+} &
+PLAYLIST_CHANGE_PID=$!
+
+# ----------------------- crash / reboot handler --------------------
+
+touch "$DBUS_CTRL_FILE"
+touch $SAVE_PATH/currenttrack
+touch $SAVE_PATH/currentpos
+
+currentTrack=$(cat $SAVE_PATH/currenttrack)
+currentPos=$(cat $SAVE_PATH/currentpos)
+
+echo "Saved track: $currentPos, $currentTrack"
+
+if [ "$START_FROM" == '' ]; then 
+
+       if [ "$currentTrack" != '' ]; then 
+
+               currentTrackNum=$( cat $PLAYLIST | grep "^[^#;]" | grep -Fn "$currentTrack" | cut -f1 -d: )     # looking for current track in playlist and return number of it
+
+               if [ "$currentTrackNum" != "" ]; then   # playlist has been updated
+                       CNT=$currentTrackNum; 
+                       echo "Current track number: $CNT"
+               fi
+
+               if [ "$currentTrackNum" != '' ] && [ "$currentPos" != '' ]; then 
+
+                       currentPos=$(( $currentPos / 60 ))
+                       echo "restarting from $currentPos min : $CNT : $currentTrack"
+                       POSITION_SET="-s $currentPos"
+
+                       {
+                               echo "waiting for player start.."
+                               waiting_for_player_start
+                               
+                               # trick to make still picture visible 
+
+                               ./dbuscontrol.sh pause 
+                               echo "paused"
+                               sleep 10
+                               ./dbuscontrol.sh pause 
+                               sleep 0.1
+                               ./dbuscontrol.sh pause
+
+                       } &
+                       WAIT1_PID=$!
+               else 
+                       waiting_for_press_play
+               fi
+       else 
+               waiting_for_press_play
+       fi 
+else 
+       CNT=$START_FROM
+       waiting_for_press_play
+fi
+
+# --------------------- main loop start -----------------------------
+
+while [ 1 ]; do
+
+       totalLines=$(cat $PLAYLIST | grep "^[^#;]" | wc -l)
+       playlistLine=$(cat $PLAYLIST | grep "^[^#;]" | head -$CNT | tail -1)
+
+       echo "playlistLine: $CNT, $playlistLine"
+
+       if echo $playlistLine | grep "^[^#;]" >/dev/null; then 
+
+               fileState=$(echo "$playlistLine" | awk '{split($0,a,"\t"); print a[5]}')
+
+               # show splash 
+
+               case "$fileState" in 
+                       "PLAY") 
+                               sudo fbi -T 3 -d /dev/fb0 --once -noverbose splash_loading_pause.png &>/dev/null
+                       ;;
+                       '')
+                               sudo fbi -T 3 -d /dev/fb0 --once -noverbose splash_loading_new.png &>/dev/null
+                       ;;
+                       *) 
+                               sudo fbi -T 3 -d /dev/fb0 --once -noverbose splash_loading.png &>/dev/null
+                       ;;
+               esac
+
+               file=$(echo "$playlistLine" | awk '{split($0,a,"\t"); print a[1]}')
+               fileComment=$(echo "$playlistLine" | awk '{split($0,a,"\t"); print a[2]}')
+               fileOptions=$(echo "$playlistLine" | awk '{split($0,a,"\t"); print a[3]}')
+
+               echo "Loading: $CNT/$totalLines : $file"
+               echo "Commentary: $fileComment"
+               echo "Additional options: $POSITION_SET $fileOptions"
+
+               echo $file > $SAVE_PATH/currenttrack
+
+               if [ "$PREF_LANG" != "" ]; then
+                       {
+                               echo "prefered language (pattern): $PREF_LANG"
+                               waiting_for_player_start
+                               audioTracks=$( $BABOOSHKA_HOME/dbuscontrol.sh audiolist 2>/dev/null )
+                               prefAudioTrackNum=$( echo "$audioTracks" | awk -v var=$PREF_LANG 'tolower($0) ~ var {print NR; exit }' )
+
+                               if [ "$prefAudioTrackNum" != "" ]; then 
+                                       i=1
+                                       while [ "$i" -lt "$prefAudioTrackNum" ] ; do
+                                               i=$(( $i + 1 ))
+                                               $BABOOSHKA_HOME/dbuscontrol.sh audiop
+                                       done 
+                                       targetTrackName=$(echo "$audioTracks" | head -$prefAudioTrackNum | tail -1 )
+                                       echo "audio track $prefAudioTrackNum : $targetTrackName"
+                               else 
+                                       echo "probably single audiotrack detected:"
+                                       echo "$audioTracks"
+                               fi 
+                       } &
+                       WAIT2_PID=$!
+               fi
+
+               {
+                       waiting_for_player_start
+                       sudo fbi -T 3 -d /dev/fb0 --once -noverbose splash.png &>/dev/null
+               } &
+               WAIT3_PID=$!
+
+               # set playlist marker before playing
+
+               if cat "$PLAYLIST" | grep "^[^#;]" | grep "$file" | grep -v -P "\tWATCHED" >/dev/null; then 
+
+                       sed -i "s|\tPLAY||g" "$PLAYLIST"
+                       newPlaylistLine=$(cat "$PLAYLIST" | grep "^[^#;]" | grep "$file" | awk -F"\t" -v pbState="PLAY" '{print $1"\t"$2"\t"$3"\t"$4"\t"pbState}')
+                       sed -i "s|^$file.*|${newPlaylistLine}|g" "$PLAYLIST"
+               fi 
+
+               # playing
+
+               echo "VIDEOSTARTED" > "$LEDS_CONTROL"
+               echo 'playing...'
+
+               playerOutput=$(./playmovie.sh -i "$file" -v $VOLUME -a 1 -m "$VIDEOMODE" $POSITION_SET $SUBTITLES_SET -r letterbox $fileOptions)
+
+               # set playlist markers after playing
+
+               if cat "$PLAYLIST" | grep "^[^#;]" | grep "$file" | grep -v -P "\tWATCHED" >/dev/null; then 
+
+                       playbackPos=$(echo "$playerOutput" | grep "Playback duration" | awk -F: '{print $2}' | xargs)   # whether it was stopped and what time
+
+                       ct=$(echo $playbackPos | awk -F'/' '{print $1}')
+                       tt=$(echo $playbackPos | awk -F'/' '{print $2}')
+
+                       if [ "$ct" -ge "$tt" ]; then watched='WATCHED'; else watched=''; fi
+
+                       newPlaylistLine=$(cat "$PLAYLIST" | grep "^[^#;]" | grep "$file" | awk -v pbPos="$playbackPos" -v pbState="$watched" -F"\t" '{print $1"\t"$2"\t"$3"\t"pbPos"\t"pbState}')
+                       sed -i "s|^$file.*|${newPlaylistLine}|g" "$PLAYLIST"
+
+                       echo "playlist line updated: $newPlaylistLine"
+               fi 
+
+               # check for unwatched / not completed video and turn RED LED on
+               
+               check_video_complete "$PLAYLIST"
+
+               : > $SAVE_PATH/currentpos
+               POSITION_SET=''
+
+               DBUS_COMMAND=$(cat "$DBUS_CTRL_FILE")
+
+               if [ "$PLAYSINGLE" != "" ] && [ "$DBUS_COMMAND" != "NEXT" ]; then 
+                       echo "play single STOP"
+                       echo "STOP" > "$DBUS_CTRL_FILE";
+                       DBUS_COMMAND="STOP"
+                       CNT=$(( $CNT + 1 ));
+               fi
+
+       else 
+#              if [ "$DBUS_COMMAND" == "PLAY" ]; then  CNT=$(( $CNT + 1 )); fi 
+               DBUS_COMMAND="NEXT"
+       fi 
+
+       # check playlist for finishing
+
+       echo "DBus command: $DBUS_COMMAND"
+
+       totalLines=$(cat $PLAYLIST | grep "^[^#;]" | wc -l)
+
+       if [ "$PLAYLISTONCE" != '' ] && [ "$CNT" -ge "$totalLines" ] && [ "$DBUS_COMMAND" != "PREV" ]; then 
+               echo "play once STOP"
+               echo "STOP" > "$DBUS_CTRL_FILE"
+               DBUS_COMMAND="STOP"
+               CNT=$(( $CNT + 1 ));
+       fi
+
+       # handle and pass dbus command (original or assigned forcibly)
+
+       echo "DBus command: $DBUS_COMMAND"
+
+       if [ "$DBUS_COMMAND" != "" ]; then 
+               case "$DBUS_COMMAND" in
+                       "NEXT")
+                               CNT=$(( $CNT + 1 ));
+                       ;;
+                       "STOP")
+                               waiting_for_press_play
+                               
+                               # check for possibly new video in playlist
+
+                               currentLEDState=$(cat $LEDS_CONTROL)
+
+                               if [ "$currentLEDState" == "NEWVIDEO" ]; then
+                                       newVideo=$(grep -v -P "\tPLAY|\tWATCHED" "$PLAYLIST" | grep "^[^#;]" | head -1 | awk '{split($0,a,"\t"); print a[1]}')
+                                       echo $newVideo > $SAVE_PATH/currenttrack
+
+                                       CNT=$( cat "$PLAYLIST" | grep "^[^#;]" | grep -Fn "$newVideo" | cut -f1 -d: )
+                                       totalLines=$(cat "$PLAYLIST" | grep "^[^#;]" | wc -l)
+                                       echo "New track detected: $CNT, $newVideo"
+                               fi 
+                               
+                       ;;
+                       "PREV")
+                               CNT=$(( $CNT - 1 ));
+                       ;;
+               esac
+               : > "$DBUS_CTRL_FILE"
+       else 
+               CNT=$(( $CNT + 1 ))
+       fi 
+
+       # playlist next line counter
+
+       if [ "$CNT" -gt "$totalLines" ]; then CNT=1; fi
+       if [ "$CNT" -lt "1" ]; then CNT=$totalLines; fi
+done 
+
+exit 0
+
diff --git a/playmovie.sh b/playmovie.sh
new file mode 100755 (executable)
index 0000000..b879614
--- /dev/null
@@ -0,0 +1,338 @@
+#!/bin/bash
+
+if [ $# -lt 1 ]; then
+       echo "IM Media Player. Created for Interplaymedium™ project (https://interplaymedium.org)"
+       echo "Copyright © 2013 Dmitry Shalnov [interplaymedium.org]"
+       echo "Licensed under the Apache License, Version 2.0"
+
+       echo "Usage: $0 -i <media url or file> [-m <video mode>] [-s <shift in min>] [-v <volume amp in dB>] [-c <crop vertically in px>] [-r <aspect mode>] [-d <deinterlace mode>]"
+       echo "Dependences: omxplayer, youtube-dl, ttf-freefont, [bc]"
+       exit 1
+fi
+
+# ------------------ settings ----------------------------------------------
+
+# set screen resolution
+
+# media box
+#WIDTH=1024
+#HEIGHT=580 # 620
+#VERTICAL_COEFF="1.3"  # my screen
+
+# IMAX edition TODO: stratching the image, need to be improved
+# HEIGHT=720
+
+# babooshka.tv
+
+WIDTH=720
+HEIGHT=576
+VERTICAL_COEFF="1.12"  # babooshka SONY TV
+
+# other default settings 
+
+SHIFTTIME=0
+VOLUME=0
+AUDIOTRACK=2
+SUBTITLES_SET=''
+DEINTERLACE_SET=''
+WINMODE_SET=''
+timeTotal=0
+
+# ------------ set environment ------------------------------------------------
+
+# if [ "$VIDEOMODE" != "0" ]; then
+#      ./lght.sh 3
+#      ./prjctr.sh 1
+# fi
+
+# ------------ parse commandline ----------------------------------------------
+
+while [ "$#" -gt 0 ]; do
+       case "$1" in
+               -i) MEDIAFILE="$2"; shift 2;;   # media file
+               -m) VIDEOMODE="$2"; shift 2;;   # video mode
+               -s) SHIFTTIME="$2"; shift 2;;   # shift in minutes
+               -v) VOLUME="$2"; shift 2;;      # volume amp
+               -a) AUDIOTRACK="$2"; shift 2;;  # number fo track
+               -t) SUBTITLES="$2"; shift 2;;   # number fo track
+               -c) CROP="$2"; shift 2;;        # pixels froms all sides
+               -r) ASPECTMODE="$2"; shift 2;;  # aspect mode   (stretch, letterbox...)
+               -d) DEINTERLACE="$2"; shift 2;; # deinterlace
+
+               -*) echo "unknown option: $1" >&2; exit 1;;
+#              *) handle_argument "$1"; shift 1;;
+       esac
+done
+
+# VIDEOMODE="720x576"
+
+VOLUME=$(( $VOLUME * 100 ))
+
+echo Audiotrack: $AUDIOTRACK
+
+# ------------ preliminary calculation ---------------------------------------
+
+# set aspect move 
+
+if [ "$ASPECTMODE" != "" ]; then ASPECTMODE_SET=$ASPECTMODE; else ASPECTMODE_SET="stretch"; fi
+
+# set deinterlace move 
+
+if [ "$DEINTERLACE" != "" ]; then DEINTERLACE_SET="-d --advanced $DEINTERLACE"; fi
+
+# set subtitles
+
+if [ "$SUBTITLES" != "" ]; then 
+       SUBTITLES_SET="-t $SUBTITLES"
+       echo Subtitles: $SUBTITLES
+fi
+
+SHIFT=$(($SHIFTTIME*60))
+
+echo "Time shift: $SHIFT"
+
+startTime=$(date +%s)
+#interruptTime=$(($bt+$SHIFT))
+interruptTime=$(($bt))
+
+# ---------- helpful functions ----------------------------------------------
+
+round() {
+       echo $1 | awk '{split($0,a,"."); print a[1]}'
+}
+
+calc() {
+       # echo "$1" | bc -l
+       EXPR=$(echo "$1" | sed 's/ //g')
+       awk 'BEGIN { print ('$EXPR') }'
+}
+
+getMode () {
+
+#      --- zona test workaround ---
+#      width=720
+#      height=360
+
+       if [ "$VIDEOMODE" != "" ]; then
+               width=$( echo $VIDEOMODE | awk '{split($0,a,"x"); print a[1]}')
+               height=$( echo $VIDEOMODE | awk '{split($0,a,"x"); print a[2]}')
+       else 
+               width=$1
+               height=$2
+       fi
+
+#      zoomCoeff=1
+#      VERTICAL_COEFF="1.3"    # my screen
+
+       vShift=0
+       hShift=0
+
+       height=$( calc "$VERTICAL_COEFF * $height" )
+       
+       comp=$( calc " $width/$height > $WIDTH/$HEIGHT" )
+
+       if [ "$comp" == "1" ]; then
+#              echo "calculate by width" >&2
+
+               zoomCoeff=$( calc "$WIDTH / $width" )
+               height=$( calc "$zoomCoeff * $height" )
+#              width=1024
+               width=$WIDTH
+
+               vShift=$( calc "($HEIGHT - $height) / 2")
+               height=$( calc "$height + $hShift")
+       else 
+#              echo "calculate by height" >&2
+
+               zoomCoeff=$( calc "$HEIGHT / $height" )
+               width=$( calc "$zoomCoeff * $width" )
+#              height=620
+               height=$HEIGHT
+
+               hShift=$( calc "($WIDTH - $width) / 2")
+               width=$( calc "$width + $hShift")
+
+       fi 
+
+       vShift=$( round $vShift )
+       hShift=$( round $hShift )
+
+       height=$( round $height )
+       width=$( round $width )
+
+#      echo "$hShift, $vShift, $width, $height" >&2
+
+       echo "--win $hShift,$vShift,$width,$height"
+}
+
+getTotalDuration(){
+               totalDuration=$( echo "$metaData" | grep 'Duration:' | head -1 | awk '{gsub(/\([^\)]*\)/, "");$1=$1}1' | awk '{split($0,a,","); print a[1]}' | awk '{split($0,a," "); print a[2]}' )
+               totalDurationInSec=$(echo "$totalDuration" | awk -F. '{print $1}' | awk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }')
+
+#              echo "metaData :: \"$metaData\"" >&2
+#              echo "$metaData" | grep 'Duration:' | head -1 >&2
+               echo $totalDurationInSec
+}
+
+getModeByMedia(){
+
+               metaData=$1
+
+               res=$( echo "$metaData" | grep 'Video:' | head -1 | awk '{gsub(/\([^\)]*\)/, "");$1=$1}1' | awk '{split($0,a,","); print a[3]}' | awk '{split($0,a," "); print a[1]}' )
+
+               width=$( echo $res | awk '{split($0,a,"x"); print a[1]}' | tr -d -c 0-9 )
+               height=$( echo $res | awk '{split($0,a,"x"); print a[2]}' | tr -d -c 0-9 )
+
+#              echo ">>> $res, $width, $height" >&2
+
+               if [[ $CROP != "" ]]; then
+
+                       cX=$(( 0 ))
+                       cY=$(( $CROP ))
+                       cX2=$(( $width ))
+                       cY2=$(( $height - $CROP ))
+       
+                       cropMode=$(echo "--crop" $cX,$cY,$cX2,$cY2)
+
+                       width=$(( $width + $CROP * 4 ))
+
+               fi 
+
+               WINMODE_SET=$( getMode $width $height )
+
+               echo "$cropMode" "$WINMODE_SET"
+}
+
+# ---------------------- playback ----------------------------------------------
+
+       
+       if [[ $MEDIAFILE == *"youtu.be"* ]]; then
+
+               # -------------- extracting youtube URL ------
+
+               echo "Extracting: $MEDIAFILE"
+               MEDIAFILE=$(wget -qO- "$MEDIAFILE" | grep "canonical" | awk '{string = index($0, "canonical"); print substr($0, string + 17, index($0, "alternate") - string - 13 - 17) }')
+               title=$(wget -qO- "$MEDIAFILE" | grep "canonical" | awk '{string = index($0, "<title>"); print substr($0, string + 7, index($0, "</title>") - string - 8 - 9) }')       
+               echo "url:      $MEDIAFILE"
+               echo "title:    $title"
+       fi
+
+       if [[ $MEDIAFILE == *"vimeo"* ]]; then
+
+               # -------------- playing vimeo -------------
+
+               echo "Media file (vimeo): $MEDIAFILE"
+
+               vimeoID=$(echo "$MEDIAFILE" | awk -F '/' '{print $4}')
+
+               vimeoData=$( curl -k "https://player.vimeo.com/video/$vimeoID" )
+
+               # get video resolution and URL
+
+               widthHeight=$( echo $vimeoData | sed -e 's/[{}]/''/g' | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | grep "\"width\"\|\"height\"" )
+
+               width=$( echo $widthHeight | awk -F ' ' '{print $1}' | awk -F ':' '{print $2}' )
+               height=$( echo $widthHeight | awk -F ' ' '{print $2}' | awk -F ':' '{print $2}' )
+
+               if [ "$VIDEOMODE" != "0" ]; then
+                       WINMODE_SET=$( getMode $width $height )
+               fi
+                       
+               echo "URL: $myUrl"
+               echo "Video: $WINMODE_SET, $ASPECTMODE_SET, $timeTotal"
+
+               myUrl=$( echo $vimeoData | sed -e 's/[{}]/''/g' | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | grep ".mp4" | grep "url" | awk -F '"' '{print $4}' | tail -1)
+
+               # play file
+
+               curl -k "$myUrl" | omxplayer pipe:0 $DEINTERLACE_SET --no-keys -b -o local --amp 0 --vol $VOLUME $WINMODE_SET --aspect-mode $ASPECTMODE_SET
+
+       elif [[ $MEDIAFILE == *"youtube"* ]]; then
+
+               # -------------- playing youtube -------------
+
+               echo "Media file (youtube): $MEDIAFILE"
+               
+               if [ "$VIDEOMODE" != "0" ]; then
+                       myUrl=$(youtube-dl -f 'bestvideo[vcodec=avc1][height<=720]+bestaudio/best[abr<=120]' -g "$MEDIAFILE") # best video + audio
+                       metaData=$( omxplayer -i "$myUrl" 2>&1 )
+                       WINMODE_SET=$( getModeByMedia "$metaData" );
+               else 
+                       myUrl=$(youtube-dl -f 'bestaudio/best[abr<=120]' -g "$MEDIAFILE") # best audio only
+                       WINMODE_SET=''
+               fi 
+
+               timeTotal=$(getTotalDuration "$metaData")
+
+               echo "URL: $myUrl"
+               echo "Video: $WINMODE_SET, $ASPECTMODE_SET, $timeTotal"
+
+               # play file
+
+               omxplayer -l 0:0:0 -b $DEINTERLACE_SET --amp 0 --vol $VOLUME -n $AUDIOTRACK -o local "$myUrl" $WINMODE_SET --aspect-mode $ASPECTMODE_SET --align center $SUBTITLES_SET
+
+       elif [[ $MEDIAFILE == *"http"* ]]; then
+
+               # -------------- playing remote file via http(s) ---------------
+
+               echo "Media file (URL): $MEDIAFILE"
+
+               # get video resolution
+
+               metaData=$( omxplayer -i "$MEDIAFILE" 2>&1 )
+               timeTotal=$(getTotalDuration "$metaData")
+
+               if [ "$VIDEOMODE" != "0" ]; then
+                       WINMODE_SET=$( getModeByMedia "$metaData" )
+               fi 
+
+               echo "WINMODE_SET (http): $WINMODE_SET"
+
+               if [[ $MEDIAFILE != *"24video"* ]] || [[ $MEDIAFILE != *"vibio"* ]]; then
+                       MEDIAFILE="${MEDIAFILE/http:/https:}"
+               fi
+
+               echo "Video: $WINMODE_SET, $ASPECTMODE_SET, $timeTotal"
+       
+               # play file (loop is broken stream workaround)
+
+               for iter in {1..6}; do 
+                       SKIPSEC=$(( ($interruptTime - $startTime + $SHIFT) * 128000 ))  # ~128kbs ? TODO: get datarate from file
+                       curl -k "$MEDIAFILE" | tail -c +$SKIPSEC | omxplayer pipe:0 $DEINTERLACE_SET -b --no-keys -o local $WINMODE_SET --amp 0 --vol $VOLUME $WINMODE_SET --aspect-mode $ASPECTMODE_SET
+                       interruptTime=$(date +%s)
+               done    
+
+       else    
+
+               # -------------- playing local file ---------------
+
+               echo "Media file (local): $MEDIAFILE"
+
+               metaData=$( omxplayer -i "$MEDIAFILE" 2>&1 )
+               timeTotal=$(getTotalDuration "$metaData")
+
+               if [ "$VIDEOMODE" != "0" ]; then
+                       WINMODE_SET=$( getModeByMedia "$metaData" )
+               fi 
+
+               echo "Video: $WINMODE_SET, $ASPECTMODE_SET, $timeTotal"
+
+               # play file
+
+               omxplayer $DEINTERLACE_SET -l $SHIFT -b --amp 0 --vol $VOLUME -n $AUDIOTRACK -o local "$MEDIAFILE" $WINMODE_SET --aspect-mode $ASPECTMODE_SET --align center $SUBTITLES_SET
+       
+       fi 
+
+
+# -------------- environment  ----------------------------------------------
+
+# turn off projector if playback time > 60 min
+
+endTime=$(date +%s)
+timeDif=$(( $endTime - $startTime ))
+echo "Playback duration: $timeDif/$timeTotal"
+
+# if [ "$timeDif" -gt "3600" ]; then
+#      ./prjctr.sh 0
+# fi
+
diff --git a/reboot.sh b/reboot.sh
new file mode 100755 (executable)
index 0000000..9ba1ebe
--- /dev/null
+++ b/reboot.sh
@@ -0,0 +1 @@
+sudo systemctl reboot
\ No newline at end of file
diff --git a/remoteir.sh b/remoteir.sh
new file mode 100755 (executable)
index 0000000..6a2a2c9
--- /dev/null
@@ -0,0 +1,228 @@
+#!/bin/bash
+
+irw > /tmp/remote_command &
+
+CCONTROL_PID=$!
+
+# BABOOSHKA_HOME=/home/pi      # assigned in start.babooshka.sh
+
+DBUS_CTRL_FILE=/tmp/dbuscontrol_command
+SAVEPATH=$BABOOSHKA_HOME
+
+# --------------------------------------
+
+killCCONTROL() {       # function called by trap (Ctrl-C handler)
+
+       echo CCONTROL_PID $CCONTROL_PID
+
+       kill -9 $CCONTROL_PID 2> /dev/null
+       echo "Have a nice day..."
+       exit 0
+}
+
+trap 'killCCONTROL' 2
+
+# --------------------------------------
+
+beep (){
+       play -n synth sin %41 fade q 0.0 0.1 0.01 gain -25 &>/dev/null </dev/null &
+}
+
+prevData=0
+musicPlay=0
+pressCnt=0
+
+while [ 1 ]; do
+
+       data=$(stdbuf -i0 -o0 -e0 tail -1 /tmp/remote_command | awk -F' ' '{print $3; exit}' | xargs )
+
+       pressCnt=$(($pressCnt + 1))
+
+       # ---- note repeatable -----
+
+       if [ "$prevData" != "$data" ]; then
+       
+               case "$data" in
+                       "qqqq")
+                               $BABOOSHKA_HOME/dbuscontrol.sh stop
+                               echo qqqq
+                       ;;
+                       "wwww")
+                               echo wwww
+                       ;;
+               esac
+
+               prevData=$data
+       fi 
+
+       # ---- repeatable ---------
+
+       case "$data" in
+
+                       # next
+
+                       "ARR_DOWN")
+                               beep
+                               echo "NEXT" > "$DBUS_CTRL_FILE"
+                               $BABOOSHKA_HOME/dbuscontrol.sh stop
+                               echo "NEXT"
+                       ;;
+
+                       # prev
+
+                       "ARR_UP")
+                               beep
+                               echo "PREV" > "$DBUS_CTRL_FILE"
+                               $BABOOSHKA_HOME/dbuscontrol.sh stop
+                               echo "PREV"
+                       ;;
+
+                       # forward +10min
+
+                       "ARR_RIGHT")
+                               beep
+                               echo "NEXT" > "$DBUS_CTRL_FILE"
+                               $BABOOSHKA_HOME/dbuscontrol.sh seekfl
+                               echo ">>"
+                       ;;
+
+                       # backward -10min
+
+                       "ARR_LEFT")
+                               beep
+                               $BABOOSHKA_HOME/dbuscontrol.sh seekbl
+                               echo "<<"
+                       ;;
+
+                       # play/pause toggle
+
+                       "ARR_OK")
+                               beep
+                               status=$(./dbuscontrol.sh status 2>/dev/null)
+
+                               if [ "$status" != "" ]; then
+                                       position=$( echo "$status" | grep Position | awk '{split($0,a,":"); print a[2]}' )
+                                       position=$(( $position / (1000000) ))   # sec
+                                       echo $position > $SAVEPATH/currentpos
+                                       paused=$( echo "$status" | grep Paused | awk '{split($0,a,":"); print a[2]}' | xargs )
+                               fi
+
+                               if [ "$paused" == "true" ] || [ "$status" == "" ]; then # has been paused 
+                                       echo "PLAY"
+                                       if [ "$status" == "" ]; then echo "PLAY" > "$DBUS_CTRL_FILE"; fi
+                               else 
+                                       echo "PAUSE"
+                               fi
+                               $BABOOSHKA_HOME/dbuscontrol.sh pause
+                       ;;
+
+
+                       # pause on switching-off
+
+                       "EXT"|"ON_OFF") # AV or ON_OFF
+                               beep
+
+                               status=$(./dbuscontrol.sh status 2>/dev/null)
+
+                               if [ "$status" != "" ]; then
+                                       position=$( echo "$status" | grep Position | awk '{split($0,a,":"); print a[2]}' )
+                                       position=$(( $position / (1000000) ))   # sec
+                                       echo $position > $SAVEPATH/currentpos
+                                       paused=$( echo "$status" | grep Paused | awk '{split($0,a,":"); print a[2]}' | xargs )
+                               fi
+
+#                              paused=$( echo "$status" | grep Paused | awk '{split($0,a,":"); print a[2]}' | xargs )
+
+                               if [ "$paused" == "false" ]; then # not paused 
+                                       $BABOOSHKA_HOME/dbuscontrol.sh pause
+#                                      echo "$status" > status
+                                       echo "PAUSED"
+                               fi
+                               echo "AV or ON-OFF"
+                       ;;
+
+                       # stop
+
+                       "KEY_TEXT")
+                               beep
+
+                               status=$(./dbuscontrol.sh status 2>/dev/null)
+
+                               if [ "$status" != "" ]; then
+                                       position=$(echo "$status" | grep Position | awk '{split($0,a,":"); print a[2]}' )
+                                       position=$(( $position / (1000000) ))   # sec
+                                       echo $position > $SAVEPATH/currentpos
+
+                                       echo "STOP" > "$DBUS_CTRL_FILE"
+                                       $BABOOSHKA_HOME/dbuscontrol.sh stop
+                                       echo "STOP"
+                               else
+                                       echo "STOP / NOT PLAYING"
+                               fi
+
+                       ;;
+
+                       # audio track switch            
+
+                       "KEY_RED")
+                               audioTracks=$( $BABOOSHKA_HOME/dbuscontrol.sh audiolist 2>/dev/null ) 
+                               trackCnt=$( echo "$audioTracks" | sed '/^\s*$/d' | wc -l )
+                               currentTrack=$( echo "$audioTracks" | awk '/active/{ print NR; exit }' )
+                               beep
+                               if [ "$trackCnt" != "0" ]; then
+                                       if [ "$currentTrack" -lt "$trackCnt" ]; then 
+                                               $BABOOSHKA_HOME/dbuscontrol.sh audiop
+                                               echo "AUDIO CHANGE" 
+                                       else 
+                                               for var in $audioTracks; do
+                                                       $BABOOSHKA_HOME/dbuscontrol.sh audiom
+                                               done 
+                                               echo "AUDIO REVIND"
+                                       fi 
+                               fi
+                               echo "AUDIO: $trackCnt, $currentTrack"
+                       ;;
+
+                       # subtitles switch              
+
+                       "KEY_YELLOW")
+                               subsTracks=$( $BABOOSHKA_HOME/dbuscontrol.sh subslist 2>/dev/null ) 
+                               subsCnt=$( echo "$subsTracks" | sed '/^\s*$/d' | wc -l )
+                               currentSub=$( echo "$subsTracks" | awk '/active/{ print NR; exit }' )
+                               beep
+                               if [ "$subsCnt" != "0" ]; then
+                                       if [ "$currentSub" -lt "$subsCnt" ]; then 
+                                               $BABOOSHKA_HOME/dbuscontrol.sh subsnext
+                                               echo "SUBS CHANGE" 
+                                       else 
+                                               if [ "$subsOff" != "1" ]; then 
+                                                       $BABOOSHKA_HOME/dbuscontrol.sh hidesubtitles
+                                                       subsOff=1
+                                                       echo "SUBS HIDE"
+                                               else  
+                                                       $BABOOSHKA_HOME/dbuscontrol.sh showsubtitles
+                                                       for var in $subsTracks; do
+                                                               $BABOOSHKA_HOME/dbuscontrol.sh subsprev
+                                                       done 
+                                                       subsOff=0
+                                                       echo "SUBS REVIND"
+                                               fi
+                                       fi 
+                               fi
+                               echo "SUBS: $subsCnt, $currentSub"
+                       ;;
+
+                       *)
+#                              echo ------
+                       ;;
+       esac
+
+       : > /tmp/remote_command
+
+       sleep 0.5
+done
+
+
+
+
+
diff --git a/renewplaylist.sh b/renewplaylist.sh
new file mode 100755 (executable)
index 0000000..89b874b
--- /dev/null
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+if [ $# -lt 1 ]; then
+       echo "Usage: $0 <playlist>"
+       exit 0
+fi 
+
+PLAYLIST=$1
+
+VIDEO="VIDEO/"
+DOWNLOADED_VIDEO="YOUTUBE/"
+
+if [ ! -d "$VIDEO" ] || [ ! -d "$DOWNLOADED_VIDEO" ]; then 
+       mkdir "$VIDEO"
+       mkdir "$DOWNLOADED_VIDEO"
+       echo "$VIDEO and $DOWNLOADED_VIDEO directories has been created. Use them to upload video files to make playlist updated automatically."
+fi
+
+IFS=$'\n';
+
+while [ 1 ]; do
+
+       VIDEO=$(find "$VIDEO" -type f)
+       YOUTUBE=$(find "$DOWNLOADED_VIDEO" -type f | grep -v ".part")
+
+       for file in $VIDEO; do 
+
+               if ! grep "$file" "$PLAYLIST" >/dev/null; then 
+                       echo "$file" >> "$PLAYLIST"
+                       echo "VIDEO playlist updated: $file"
+               fi  
+       done 
+
+       for file in $YOUTUBE; do 
+
+               if ! grep "$file" "$PLAYLIST" >/dev/null; then 
+                       echo "$file" >> "$PLAYLIST"
+                       echo "YOUTUBE playlist updated: $file"
+               fi  
+       done 
+
+       sleep 60
+done 
diff --git a/splash.png b/splash.png
new file mode 100644 (file)
index 0000000..ea5ce61
Binary files /dev/null and b/splash.png differ
diff --git a/splash_loading.png b/splash_loading.png
new file mode 100644 (file)
index 0000000..4ff8aec
Binary files /dev/null and b/splash_loading.png differ
diff --git a/splash_loading_new.png b/splash_loading_new.png
new file mode 100644 (file)
index 0000000..f404dcf
Binary files /dev/null and b/splash_loading_new.png differ
diff --git a/splash_loading_pause.png b/splash_loading_pause.png
new file mode 100644 (file)
index 0000000..ad23f90
Binary files /dev/null and b/splash_loading_pause.png differ
diff --git a/start.babooshka.sh b/start.babooshka.sh
new file mode 100755 (executable)
index 0000000..b349cc4
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+export BABOOSHKA_HOME=/home/pi/BABOOSHKA.TV/
+
+cd "$BABOOSHKA_HOME"
+
+# ./leds.sh    # added to early_init.sh
+./remoteir.sh & # 2>&1 >/tmp/remoteir.log &
+./renewplaylist.sh playlist 2>&1 >/tmp/babooshka.log &
+
+sleep 1
+
+echo BOOTCOMPLETE > /tmp/bbshk_leds
+
+./playlist.sh -p playlist -m 720x576 -o 2>&1 >/tmp/babooshka.log
Contact me: dev (at) shalnoff (dot) com
PGP fingerprint: A6B8 3B23 6013 F18A 0C71 198B 83D8 C64D 917A 5717