-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkodi-remote
executable file
·203 lines (181 loc) · 6.04 KB
/
kodi-remote
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#!/bin/sh
help() { cat <</help
Usage: kodi-command [OPTIONS] COMMAND|JSON
or: kodi-command [OPTIONS] METHOD [PARAM]
Options:
-c FILE Configuration file (default: \`$api_creds\`)
For further info, run \`${0##*/} --config-help\`
-q Make output quieter, -qq also suppresses response JSON
-u URL The kodi control URL (default: \`url\` value from config file)
Command aliases:
clean, clean-audio Clean library: VideoLibrary.Clean or AudioLibrary.Clean
info Get info on the video or audio being played
mute Toggle mute: Application.SetMute
open FILE Open and play FILE
play, pause Toggle between play and pause (video)
quit Exit kodi
update, update-audio Update library: VideoLibrary.Scan or AudioLibrary.Scan
This requires you to have enabled the web server
Settings -> Services -> Control -> Allow remote control via HTTP
Docs for JSON, methods, and parameters: $api_link
A part of media-scripts, https://github.com/adamhotep/media-scripts
kodi-remote 0.2.20240701.0 copyright 2021+ by Adam Katz, GPLv2+
/help
exit
}
# Output a warning text to standard error and optionally exit
# Usage: warn [-x] [MESSAGE]
warn() {
if [ "$1" = -x ]; then die=2; shift; fi
echo "$*" >&2
if [ "${die:-0}" -ge 0 ]; then exit $die; fi
}
api_file_help() { cat <</api_help
\`$api_creds\` is a curl config file,
called with \`curl --config FILE\` (see \`man curl\`).
It should look like this (with no indentation, ideally with a better password):
url = "http://localhost:8080/jsonrpc"
user = "kodi_user:kodi_webapi_PA55w0rd"
That's a plain-text password in an unencrypted file, which is not at all ideal!
Please at least use file mode 600 (-rw-------) or 400 (-r--------)
/api_help
exit $1
}
# constants
api_link="https://kodi.wiki/view/JSON-RPC_API/v13"
qq='"'
# defaults
api_creds="$HOME/.kodi/.api_creds"
url=
quiet=0
# load options
needs_arg() {
if [ -z "$OPTARG" ]; then
warn -x "No arg for --$OPT option"
fi
}
while getopts c:hqu:v-: OPT; do
if [ "$OPT" = - ]; then # long opt https://stackoverflow.com/a/28466267/519360
OPT="${OPTARG%%=*}" OPTARG="${OPTARG#$OPT}" OPTARG="${OPTARG#=}"
fi
case $OPT in
( c* ) if [ -z "$OPTARG" ]; then api_file_help; fi; api_creds="$OPTARG" ;;
( h* ) help ;;
( q* ) quiet=$(( quiet + 1 )) ;;
( u* ) needs_arg; url="$OPTARG" ;;
( v* ) quiet=$(( quiet - 1 )) ;;
( ??* ) warn "Illegal option --$OPT"; warn -x "Try \`${0##*/} --help\`" ;;
( ? ) warn -x "Try \`${0##*/} --help\`" ;;
esac
done
shift $((OPTIND-1))
if ! [ -s "$api_creds" ] || ! [ -r "$api_creds" ]; then
warn "You don't have a nonzero-sized readable '$api_creds' file."
api_file_help 2
fi
# Run a Kodi JSON command
# Usage: kodi_json_cmd JSON
kodi_json_cmd() {
case $quiet in
( 0 | -* ) silent='' ;;
( 1 ) silent='--silent' ;;
( * ) silent='--silent --output /dev/null' ;;
esac
curl --config "$api_creds" $silent --request POST \
--header "content-type:application/json" --data "$*" ${url:+"$url"}
}
# Run a basic command (an alias or a method with optional parameter(s)
# Usage: kodi_cmd COMMAND [PARAM...]
kodi_cmd() {
method="$1" params=
shift
case "$*" in
( \{*\} ) params='"params":'"$*" ;;
( * )
params='"params":{'
key=1
comma=
for p in "$@"; do
if [ $key = 1 ]; then
params="$params$comma$qq$p$qq:"
comma=','
key=0
elif [ "$p" = "${p#*[^0-9]}" ] || [ "$p" != "${p#\[}" ]; then
# pure numeric value or a JSON nested structure, take as-is (no quotes)
params="$params$p"
key=1
else
params="$params$qq$p$qq"
key=1
fi
done
params="$params}"
;;
esac
# Run constructed JSON with identifier set to identify this script and its PID
kodi_json_cmd "$(printf \
'{ "jsonrpc": "2.0", "id": "kodi-command[%d]", "method": "%s", %s }' \
"$$" "$method" "$params"
)"
}
kodi_info() {
# Why does this need to be more quiet than other curl commands?
case "$(quiet=$((quiet+1)) kodi_cmd Player.GetActivePlayers)" in
( *'"type":"video"'* ) kodi_json_cmd '{
"jsonrpc": "2.0",
"method": "Player.GetItem",
"params": {
"properties": [
"title", "album", "artist", "season", "episode", "duration",
"showtitle", "tvshowid", "file"
],
"playerid": 1
},
"id": "VideoGetItem"
}' ;;
( *'"type":"audio"'* ) kodi_json_cmd '{
"jsonrpc": "2.0",
"method": "Player.GetItem",
"params": {
"properties": [ "title", "album", "artist", "duration", "file" ],
"playerid": 0
},
"id": "AudioGetItem"
}' ;;
esac
}
# Convert relative paths to absolute paths
# Usage: realpath PATH
if ! command -v realpath >/dev/null; then
realpath() { readlink -f "$@"; }
fi
# Play a file or toggle play/pause on a given playerid (default=1, video)
kodi_play() {
if [ "$*" -ge 0 ] 2>/dev/null; then # non-negative number: toggle playerid
kodi_cmd Player.PlayPause playerid "$1"
elif [ -z "$1" ]; then # no argument: toggle video
kodi_cmd Player.PlayPause playerid 1
else
kodi_cmd Player.Open '{"item":{"file":"'"$(realpath "$1")"'"}}'
fi
}
case "$1" in
( help ) help ;;
# Aliases for common commands
( aplay | aplaypause | apause ) kodi_play 0 ;;
( clean | clean*vid* | clean*mov* ) kodi_cmd VideoLibrary.Clean ;;
( clean-audio* | clean*music* ) kodi_cmd AudioLibrary.Clean ;;
( info ) kodi_info ;;
( mute | unmute ) kodi_cmd Application.SetMute ;;
( open | play ) shift; kodi_play "$@" ;;
( play* | pause | vplay* | vpause ) kodi_play ;;
( stop ) kodi_cmd Player.Stop playerid ${2:-1} ;;
( quit | exit ) kodi_cmd Application.Quit ;;
( update | upd*vid* | upd*mov* ) kodi_cmd VideoLibrary.Scan ;;
( update-audio* | update*music* ) kodi_cmd AudioLibrary.Scan ;;
( \{* ) kodi_json_cmd "$*" ;;
( *.* ) kodi_cmd "$@" ;;
( * ) warn "Unknown command: '$*'"
warn -x "Try \`${0##*/} --help\`"
;;
esac