
序文
以下の投稿で今更kodi-send
を知る。
Kodiの操作コマンド - Qiita
面白そうだったので試してみた。
インストール
標準パッケージなので以下。
$ sudo apt install kodi-eventclients-kodi-send -y
使えそうなコマンド
# 戻る
$ kodi-send -a "Action(Back)"
# メニューカーソル上移動
$ kodi-send -a "Action(Up)"
# メニューカーソル下移動
$ kodi-send -a "Action(Down)"
# メニューカーソル左移動
$ kodi-send -a "Action(Left)"
# メニューカーソル右移動
$ kodi-send -a "Action(Right)"
# メニュー選択
$ kodi-send -a "Action(Select)"
# 動画一時停止/再開
$ kodi-send -a "Action(PlayPause)"
# 動画停止
$ kodi-send -a "Action(Stop)"
$ kodi-send -a "PlayerControl(Stop)"
# 再生音量を上げる
$ kodi-send -a "Action(VolumeUp)"
# 再生音量を下げる
$ kodi-send -a "Action(VolumeDown)"
# 再生音量パーセント指定
$ kodi-send -a "SetVolume(90, showvolumebar)"
# ミュート/解除
$ kodi-send -a "Action(Mute)"
$ kodi-send -a "Mute"
# kodi終了
$ kodi-send -a Quit
# スクリーンショット
$ kodi-send -a "TakeScreenshot"
# 次の動画
$ kodi-send -a "Action(SkipNext)"
# 前の動画
$ kodi-send -a "Action(SkipPrevious)"
# ダイアログ閉じる
$ kodi-send -a "Action(Close)"
# お気に入り画面表示
$ kodi-send -a "ActivateWindow(favourites)"
お気に入り画面表示、スクリーンショットが地味に便利かも。但し最新の Kodi on Raspberry Pi の動画再生はオーバーレイ表示なので原理的にスクリーンショットが撮れないけど。何とかならんかねぇ。
動画再生
対象がローカル環境の場合はフルパス指定で以下。NAS 等に保存してあるお気に入りの動画等を一発で再生できるのは便利かも。
# 組み込み WAVEファイル再生
$ kodi-send -a "PlayMedia(/usr/share/gui-pkinst/instcompr.wav)"
インターネット上の動画ファイル再生も同様に URL 指定で。
# インターネット上の動画ファイル再生
$ kodi-send -a "PlayMedia(https://mazwai.com/videvo_files/video/free/2019-12/small_watermarked/190915_B_01_Timelapse%20Danang_02_preview.webm)"

※ フリー動画サイトより引用
YouTube動画再生
YouTube動画となると URL指定ではダメ。以下の構文で。video_id=
で動画IDを指定れば良い。
サンプルは一時期日本語圏でも話題になったライブ配信。日本人が殺到し YouTubeコメントで日本語(英語以外)のコメントが問答無用で削除対象になったのは記憶に新しい。最近は落ち着いたのかな?
# Namibia: Live stream in the Namib Desert
$ kodi-send -a "PlayMedia(plugin://plugin.video.youtube/play/?video_id=ydYDqZQpim8)"

プレイリスト再生の場合は以下の構文で。「超」FM音源ですなぁ。X68k生誕35周年記念ということで。
# Cho Ren Sha 68K Original Soundtracks Complete
$ kodi-send -a "PlayMedia(plugin://plugin.video.youtube/play/?playlist_id=PL6PHQCxAqpJTA3R5hgkqVJChfIuecx2gh&play=1&order=default)"

こちらはplaylist_id=
でプレイリストID を指定する形。play=1
でプレイリストの先頭からの再生を指定しているけど、2 以降を指定すると再生できない。謎。order=default
を省略すると、再生順番を確認するダイアログが表示されてしまうので指定するが吉。
以上は YouTube Add-on経由ということになる。詳細は以下参照。
Add-on_YouTube - Official Kodi Wiki
因みに変なタイミングで再生すると、動画の手前にメニューが表示されてしまう場合がある。その時は前述kodi-send -a "Action(Back)"
実行でメニューをどかすこと。
シェルスクリプト1
コマンド入力は一通り分かったけど、やはり面倒。そもそも本来はリモコン操作でできるものだし。
そこでせめてシェルスクリプト化。まずは以下。
#!/bin/bash
# 引数未指定の場合
if [ $# -ne 1 ]; then
echo "使用法: $0 [動画ID | プレイリストID]" 1>&2
echo " YouTube 動画ID、またはプレイリストID を指定してください。" 1>&2
exit 1
fi
if [ ${#1} = 11 ]; then
kodi-send -a "PlayMedia(plugin://plugin.video.youtube/play/?video_id=$1,resume)" > /dev/null
else
kodi-send -a "PlayMedia(plugin://plugin.video.youtube/play/?playlist_id=$1&play=1&order=default)" > /dev/null
fi
github
にアップしたので、そこから取得する場合は以下。
$ wget https://github.com/god1964/RaspberryPi/raw/main/kodi-send/ksid.sh
$ chmod 755 ./ksid.sh
実行例は以下。YouTube動画ID、またはプレイリストID を引数で与え再生。
$ ./ksid.sh PL6PHQCxAqpJTA3R5hgkqVJChfIuecx2gh
シェルスクリプトを見てもらえば分かる通り、動画IDかプレイリストID かの判定は単純に文字列の長さ。(if [ ${#1} = 11 ]; then
の箇所)
エラー判定等は行っていない。存在しない ID を与えてもエラー終了するだけ。
PlayMedia
の引数にresume
を指定しているのは、前回再生を中断している動画の場合、中断箇所からの再生か先頭から再生するかの確認ダイアログが表示されてしまうので、その対策。
シェルスクリプト2
どうせならお気に入りの動画一覧を表示し、選択指定し再生したい。ついでの制御コマンド類もショートカットで指定したい。ということで以下。
クリックで開閉
#/bin/bash
function menu {
# メニューカーソルの位置
choice=0
# メニュー配列
menu=(
"ydYDqZQpim8 Namibia: Live stream in the Namib Desert"
"DAJYk1jOhzk Let It Go - Frozen - Alex Boyé (Africanized Tribal Cover) Ft. One Voice Children's Choir"
"StLHSkvz3Rk 【鬼滅の刃 Demon Slayer: Kimetsu no Yaiba】和楽 紅蓮華【LiSA/紅蓮華 Gurenge】"
"UvouZBYuijM JOKER | Don't Stop Me Now"
"elJc256ekw4 【BGMギターカバー】沙羅曼蛇(1986KONAMI/AC))全曲メドレー"
"PL6PHQCxAqpJTA3R5hgkqVJChfIuecx2gh Cho Ren Sha 68K Original Soundtracks Complete"
)
tail=$((${#menu[@]} - 1)) # メニューの末尾番号
printf "\e[32mq:メニュー終了, Q:kodi終了, c:ダイアログ閉じる, e:選択, b:戻る, u:カーソル上移動, d:カーソル下移動, l:カーソル左移動, r:カーソル右移動, p:一時停止/再開, s:停止, n:次の動画, f:前の動画, o:お気に入りを開く, -:音量下げる, +:音量挙げる, t:スクショ, m:ミュート/解除, k:kodi起動\e[m\n" >&2
for _ in $(seq 0 $tail);do echo "";done
# 無限ループ
while true
do
printf "\e[${#menu[@]}A\e[m" >&2
for i in $(seq 0 $tail);do
if [ $choice = $i ]; then
printf "\e[1;31m>\e[m \e[1;4m" >&2
else # メニューが選択中でなければ
printf " " >&2
fi
title=`echo ${menu[$i]} | sed -e "s/^[^ ]*[ ]//"`
printf "$title\e[m\n" >&2
done
read -sn1 input
# ショートカット処理
case $input in
"q") return ;;
"Q") kodi-send -a Quit > /dev/null ;;
"c") kodi-send -a "Action(Close)" > /dev/null ;;
"e") kodi-send -a "Action(Select)" > /dev/null ;;
"b") kodi-send -a "Action(Back)" > /dev/null ;;
"u") kodi-send -a "Action(Up)" > /dev/null ;;
"d") kodi-send -a "Action(Down)" > /dev/null ;;
"l") kodi-send -a "Action(Left)" > /dev/null ;;
"r") kodi-send -a "Action(Right)" > /dev/null ;;
"p") kodi-send -a "Action(PlayPause)" > /dev/null ;;
"s") kodi-send -a "Action(Stop)" > /dev/null ;;
"n") kodi-send -a "Action(SkipNext)" > /dev/null ;;
"f") kodi-send -a "Action(SkipPrevious)" > /dev/null ;;
"o") kodi-send -a "ActivateWindow(favourites)" > /dev/null ;;
"-") kodi-send -a "Action(VolumeDown)" > /dev/null ;;
"+") kodi-send -a "Action(VolumeUp)" > /dev/null ;;
"t") kodi-send -a "TakeScreenshot" > /dev/null ;;
"m") kodi-send -a "Mute" > /dev/null ;;
"k")
ps=`ps aux | grep "/bin/sh /usr/bin/kodi" | grep -v grep | wc -l`
if [ $ps -eq 0 ]; then
/bin/sh /usr/bin/kodi & > /dev/null
fi
;;
esac
# メニュー制御
if [ "$input" = "^[" ]; then # (^[はctrl+V ctrl+[とかで入力してね)
read -sn2 input
fi
case $input in
"j"|"[B") choice=$((choice + 1)); if [ $choice -gt $tail ]; then choice=0; fi ;;
"k"|"[A") choice=$((choice - 1)); if [ $choice -lt 0 ]; then choice=$tail; fi ;;
"")
# 改行で決定
./ksid.sh `echo ${menu[$choice]} | awk '{print $1}'`
;;
esac
done
}
menu
こちらもgithub
にアップしたのでそこから取得する場合は以下。
$ wget https://github.com/god1964/RaspberryPi/raw/main/kodi-send/ksyt.sh
$ chmod 755 ./ksyt.sh
実行例は以下。
$ ./ksyt.sh

以下を参考にさせていただいた。感謝。
menu.sh
矢印上下キーで対象動画を選択、Enterキー、またはSpaceキー押下で再生。
緑色文字の説明にあるように、基本的なコマンドもショートカットキーに割り当ててある。
画面に表示しているメニュー定義はスクリプト冒頭で定義している以下の配列。
menu=(
"ydYDqZQpim8 Namibia: Live stream in the Namib Desert"
以下のように、<動画ID又はプレイリストリストID>
と<動画タイトル>
を半角スペース区切りで記述する。
"<動画ID又はプレイリストリストID> <動画タイトル>"`
スクリプトの作りとして、最初の半角までをID
、それ以降を動画タイトル
として解釈するので、動画タイトル
に半角スペースが含まれていても問題ない。
お気に入りの物に差し替えてもらえば相応に動作する筈。
但し問題がある。単純な文字列出力でメニューを構成しているので、まともに動くのは10個程度。多すぎると画面表示が乱れる。勿論一画面に収まらない量を定義したらまともに表示されない。程々に。
ベースとさせて頂いたものは、大量のメニューを想定していないものであり、本来の使用方法を逸脱しているので止む無し。
シェルスクリプト3
もう少し何とかならないものか。かといってncurses
とかでフルスクラッチで作るのは本末転倒だし。お手軽な範囲で何とかならないかとぐぐって辿り着いたのでdialog
コマンド。
これも標準パッケージなので以下でインストール。
$ sudo apt install dialog -y
dialog
コマンドを応用して作成したシェルスクリプトが以下。
クリックで開閉
#!/bin/bash
menu_file=./ksdlg_menu.txt
DATA=`cat $menu_file`
while true; do
str="dialog --menu \"一覧:\" 0 0 0 "
i=1
while read line
do
str+="$i "
title=`echo $line | sed -e "s/^[^ ]*[ ]//"`
str+="\"${title}\" "
i=$((i + 1))
done << FILE
$DATA
FILE
str+="2>temp"
eval $str
# OK が押されたら
if [ "$?" = "0" ]; then
_return=$(cat temp)
i=1
while read line
do
if [ $_return -eq $i ]; then
break
fi
i=$((i + 1))
done << FILE
$DATA
FILE
./ksid.sh `echo $line | awk '{print $1}'`
else
break
fi
rm -f temp
done
ydYDqZQpim8 Namibia: Live stream in the Namib Desert
DAJYk1jOhzk Let It Go - Frozen - Alex Boye (Africanized Tribal Cover) Ft. One Voice Children's Choir
StLHSkvz3Rk 【鬼滅の刃 Demon Slayer: Kimetsu no Yaiba】和楽 紅蓮華【LiSA/紅蓮華 Gurenge】
UvouZBYuijM JOKER | Don't Stop Me Now
PLvlum7YWrP-WtAH0PS6_WfoWs0XALtNJ_ グラディウスII-GRADIUS II [Guitar Cover]
PL6PHQCxAqpJTA3R5hgkqVJChfIuecx2gh Cho Ren Sha 68K Original Soundtracks Complete
こちらもgithub
にアップしたのでそこから取得する場合は以下。
$ wget https://github.com/god1964/RaspberryPi/raw/main/kodi-send/ksdlg.sh
$ wget https://github.com/god1964/RaspberryPi/raw/main/kodi-send/ksdlg_menu.txt
$ chmod 755 ./ksdlg.sh
実行例は以下。
$ ./ksdlg.sh

こちらはメニューを分離した。ksdlg_menu.txt
を編集しお気に入りの動画に差し替える想定。
操作方法は前出のスクリプト同様。大分まともになったけどやはり問題が。
まずメニュー選択位置が保持されない。
dialog
コマンドは<了解>
選択で終了し、メニュー選択位置(インデックス)を返す仕様であり、それを無限ループで回していて、再度dialog
コマンドが実行されるので、毎回先頭メニューが選択される動きになってしまう。
こちらも本来の使用方法を逸脱しているので止む無し。それとscreen
コマンドとの相性が最悪で表示が崩れる。
それでなくても選択肢が多過ぎるとやはり表示が一部乱れる。ここら辺は出来合いの物で間に合わせている以上対応策はないっぽい。それとこちらのスクリプトにはショートカットキーは組み込むことができない。うーむ。
既知の問題
ksyt.sh
ksdlg.sh
スクリプトはLibreELEC
環境では動かない。当初原因が分からず困惑したけど、シェルがbusybox
であることが原因。
LibreELEC:~ # ./ksyt.sh
./ksyt.sh: line 6: syntax error: unexpected "(" (expecting "}")
LibreELEC:~ # ./ksdlg.sh
./ksdlg.sh: line 3: syntax error: unexpected "("
LibreELEC:~ #
LibreELEC:~ # ls -l /bin/sh
lrwxrwxrwx 1 root root 7 Aug 10 2021 /bin/sh -> busybox
LibreELEC:~ # ls -l /bin/bash
lrwxrwxrwx 1 root root 7 Aug 10 2021 /bin/bash -> busybox
LibreELEC:~ #
busybox
は配列に対応していないので、結果上記のシェルスクリプトは動かないという。うーむ。何だかなぁ。
それとkodi-send
コマンドを連射すると、簡単にkodi
が落ちたりするので注意。
その他
ブラウザ上で一覧を表示して、という方向性をも考えたけどまとまらなかった。今日日はセキュリティ対策が厳しくブラウザ(JavaScript)上でコマンドを発行すのは地味に面倒。
標準で用意されている Webアプリはkodi-webinterface.js
を使用しているようで、それを利用して何とかできないかなとも思ったけど……。Web系は苦手なんだよねぇ。
あるとしたら、勉強がてらncurses
で作る、という方向性かなぁ。
参考URL
kodi-send(1) — kodi-eventclients-kodi-send — Debian bullseye — Debian Manpages
Debian -- bullseye の kodi-eventclients-kodi-send パッケージに関する詳細
List of built-in functions - Official Kodi Wiki
Action IDs - Official Kodi Wiki
Window IDs - Official Kodi Wiki
Add-on_YouTube - Official Kodi Wiki
Dialog_ How to create menus in your scripts - Applications and Systems
A menu box - Linux Shell Scripting Wiki
dialog(1) manページ
Shell _シェルスクリプトを組もう! Dialog 編 _ 221B Baker Street
2022/03/29 追記
ksdlg.sh
修正。
メニュー分離。
github上のフォルダ移動。