11
21

More than 5 years have passed since last update.

raspberrypiでデジタルサイネージを作る!

Last updated at Posted at 2019-03-23

展示会などでモニターに映像を流しておきたいですが、高価なスマホを繋ぎっぱなしにできないため、raspberrypiならちょうどよさそうということでやってみました。

【概要】
動画や静止画を流す。
ダイソーの300円シャッターで画像を切り替える。

【苦労したところ】
動画を繰り返し出力すると動画が乱れたことへの対処
静止画を出力する方法を見つけるのに時間がかかった
動画、静止画のプレイヤーを終了させる方法を見つけること

【まだ未解決のところ】
プレイヤーを終了した時にraspiのデスクトップ画面や終了ログを表示してしまうこと

【詳細】
1.動画自動再生
raspi標準の動画プレイヤー、omxplayerを使用します。

自動実行の方法は何種類かありますが、今回は
/home/pi/.config/lxsession/LXDE-pi/autostart に以下を追加することにより自動再生にします。
omxplayer --no-osd --refresh --loop --blank -o both /home/pi/demo.mp4

参考にした記事:
映像展示の再生デバイスとしてRaspberry Piを使うと最高
http://nomolk.hatenablog.com/entry/2016/10/25/223000

2.静止画再生
静止画は高速に動作するfbiを使います。
sudo fbi -T 1 -d /dev/fb0 -noverbose /home/pi/demo.mpg

参考にした記事:
ラズパイカメラを使って連続撮影&fbiコマンドでCUI画面のフレームバッファに直接表示する方法。SSH経由でもOK!
https://iot-plus.net/make/raspi/raspistill-continuous-shooting-displays-on-cui-using-frame-buffer-with-ssh-connection/

3.ファイル一覧取得
raspi内の動画、静止画ファイル一覧を取得

files = os.listdir(path)
files_file = [f for f in files if os.path.isfile(os.path.join(path, f))]

参考にした記事:
Pythonでファイル名・ディレクトリ名の一覧をリストで取得
https://note.nkmk.me/python-listdir-isfile-isdir/

4.プレイヤーの停止方法
omxplayerは'q'を送信
fbiはプロセスをkill(sudo pkill fbi)
→qを送れば停止するらしいのだが上手くいかず。

参考にした記事:
OmxplayerをPythonコードから停止させる
https://qiita.com/goowaSystemTeam/items/95525dae25dee270087b

5.最新のraspbianではautostartファイルがない
結論としては、今までと同様の/home/pi/.config/lxsession/LXDE-pi/autostartファイルを作ればOK。

参考にした記事:
newest Raspbian Stretch LXDE not installed - how ot autostart now?
https://www.raspberrypi.org/forums/viewtopic.php?t=228199

6.ダイソーの300円シャッターボタンを認識させる
bluebuttonをインストールしてconfigファイルのlongdownイベント時にos.system("sudo shutdown -h now")を実行すればよい。

参考にした記事:
ABshutter3
Bluetoothシャットダウンボタンを作る #300円でIoTボタン
https://qiita.com/nori-dev-akg/items/96584d9591d329f9dcb2

7.シャッターボタンが押されたときに次の映像ファイルを再生する
bluebuttonはイベントを起こすだけであり、現在の表示ファイルの番号はわからない。
そこで、シャッターボタンが押されたときに値をインクリメントしてpikleで保存している。
映像再生側で保存した値を読み込んで次の映像を表示する。

ここでpikleのモードを読み込みrb、書き込みwbとしたところ、数回に1回pikle型で読めなかったエラーが発生。ボタン押下での読み書きと映像再生側の読みの2つの処理が同時に走っており、ボタン押下のwbで一度pikleが初期化されたタイミングで映像再生側で読んだためのエラーの模様。
rb+として書き込むことで(初期化がなくなり)エラーが発生しなくなった。

8.omxplayerの連続再生に対応する
連続再生させると画像が乱れるので以下を/boot/config.txtに追加
gpu_mem=128

参考記事:
RPi3 OmxPlayer / VLC Player 連続再生2回目から映像が乱れる問題
http://studio-geek.com/archives/1094

/home/pi/.config/lxsession/LXDE-pi/autostart
@lxpanel --profile LXDE-pi
@pcmanfm --desktop --profile LXDE-pi
@xscreensaver -no-splash
@point-rpi
@/home/pi/start.sh
/home/pi/start.sh
sudo bluebutton -d="Shutter3" -c ~/.config/bluebutton &
sudo python /home/pi/demo.py
/home/pi/.config/bluebutton
keyup=echo UP
keydown=sudo python /home/pi/nextimage.py
longup=echo LONG UP
longdown=sudo python /home/pi/shutdown.py
/home/pi/nextimage.py
#!/usr/bin/python
# coding:utf-8

import pickle
import os

path = '/home/pi/demo/'

files = os.listdir(path)
files_file = [f for f in files if os.path.isfile(os.path.join(path, f))]
file_num = len(files_file)

print(file_num)
print(files_file)

isCreated = os.path.exists('/home/pi/num.dat')
if (isCreated):
    f = open('num.dat','rb')
    num = pickle.load(f)
    f.close
else:
    num = 0

num = num +1
if (num >= file_num):
    num = 0
    print('roll over!!')

f = open('num.dat','rb+')
pickle.dump(num,f)
f.close
/home/pi/shutdown.py
#!/usr/bin/python
# coding:utf-8
import os

os.system("sudo shutdown -h now")
/home/pi/demo.py
# -*- coding: utf-8 -*-
#!/usr/bin/python

# import module
from time import sleep  # time module
import subprocess
from subprocess import call
import time
import pickle
import os

status = 1
num = 0

f = open('num.dat','wb')
pickle.dump(num,f)
f.close

path = '/home/pi/demo/'

files = os.listdir(path)
files_file = [f for f in files if os.path.isfile(os.path.join(path, f))]
file_num = len(files_file)

print(file_num)
print(files_file)

sleep(10)

last_num = num

while True:
    sleep(1)

    f = open('num.dat','rb')
    num = pickle.load(f)
    f.close

    if (last_num != num ):
        root, ext = os.path.splitext(files_file[last_num])
        if ( ext == '.mp4' ):
            proc.stdin.write("q")
        else:
            call (["sudo pkill fbi"], shell=True)
        status = 1
        last_num = num

    if ( status == 0 ):
        pass

    elif( status == 1 ):
        root, ext = os.path.splitext(files_file[num])
        if ( ext == '.mp4' ):
            command = 'omxplayer --no-osd --refresh --loop --blank -o both /home/pi/demo/'+files_file[num]
        else:
            command = 'sudo fbi -T 1 -d /dev/fb0 -noverbose demo/'+files_file[num]
        proc = subprocess.Popen(command,shell=True,stdin=subprocess.PIPE)
        status = 0

    else:
        pass

また、shファイルに実行権を与えておきましょう。

$ chmod +x start.sh

変更履歴:
2019.3.23 新規作成
2019.3.25 バグ修正(home.py)
再生最初のファイルがmp4でない場合に対応した(1回目のomxplayer固定をやめた)
 num.datがないときに新規作成するよう対応(rb+をwbに戻した)
 また、start.shの実行権付与を追加
2019.3.31 バグ修正(home.py)
 不足していたfrom subprocess import callを追加
 

11
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
21