展示会などでモニターに映像を流しておきたいですが、高価なスマホを繋ぎっぱなしにできないため、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
@lxpanel --profile LXDE-pi
@pcmanfm --desktop --profile LXDE-pi
@xscreensaver -no-splash
@point-rpi
@/home/pi/start.sh
sudo bluebutton -d="Shutter3" -c ~/.config/bluebutton &
sudo python /home/pi/demo.py
keyup=echo UP
keydown=sudo python /home/pi/nextimage.py
longup=echo LONG UP
longdown=sudo python /home/pi/shutdown.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
#!/usr/bin/python
# coding:utf-8
import os
os.system("sudo shutdown -h now")
# -*- 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を追加