-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtvmenu.1d.sh
317 lines (289 loc) · 12.8 KB
/
tvmenu.1d.sh
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
#!/usr/bin/env bash
# https://github.com/einstweilen/tvmenu
# 2023-01-28
# <xbar.title>TV Menü</xbar.title>
# <xbar.version>v2</xbar.version>
# <xbar.author>Einstweilen</xbar.author>
# <xbar.author.github>Einstweilen</xbar.author.github>
# <xbar.desc>TV Streams der ÖR Sender / German public-service television broadcasters</xbar.desc>
# <xbar.image>https://i.imgur.com/5vjg4ln.png</xbar.image>
# <xbar.dependencies>bash</xbar.dependencies>
# <xbar.abouturl>https://github.com/einstweilen/tvmenu_xbar</xbar.abouturl>
check_database(){
sqlite3 .tvmenu.db "CREATE TABLE IF NOT EXISTS senderlisten (liste TEXT, sendername TEXT, url TEXT UNIQUE);"
# Senderlistenkürzel, Sendername, StreamURL
sqlite3 .tvmenu.db "CREATE TABLE IF NOT EXISTS menuitems (menuart TEXT, liste TEXT, item TEXT, command TEXT);"
# Menuart, Kürzel der Senderliste, im Menü angezeigter Text, Befehle bei Auswahl
# menuart: Sender G=gruppiert, N=nicht gruppiert
# menuart: L=Senderlisten, S=Servicemenü
sqlite3 .tvmenu.db "CREATE TABLE IF NOT EXISTS settings (key TEXT UNIQUE, value TEXT);"
# key: senderliste v: Kürzel der aktuell angezeigten Liste
# key: player QuickTime|VLC, gruppierung an|aus
if [ $(sqlite3 .tvmenu.db "SELECT COUNT(*) FROM settings;") -lt 3 ] ; then
settings 'senderliste' 'oerr'
settings 'player' 'QuickTime'
settings 'gruppierung' 'an'
fi
if [ $(sqlite3 .tvmenu.db "SELECT COUNT(*) FROM senderlisten;") -eq 0 ] ; then
get_channels
update_sendermenu
update_settings_submenu
fi
}
settings(){
if [ -n "$1" ]; then
if [ -n "$2" ]; then
sqlite3 .tvmenu.db "REPLACE INTO settings VALUES (\"$1\", \"$2\");"
else
sqlite3 .tvmenu.db "SELECT value FROM settings WHERE key=\"$1\";"
fi
fi
}
check_VLC(){
mdfind kind:application -name 'VLC' 2>/dev/null | grep -q 'VLC.app' && return 0 || return 1
}
close_player_windows(){
if [[ "$1" == 'QuickTime' ]]; then
osascript -e 'tell application "QuickTime Player" to close every window' >> /dev/null 2>&1
else
osascript -e 'tell application "VLC" to close every window' >> /dev/null 2>&1
fi
}
stream_abspielen(){
url=$(sqlite3 .tvmenu.db "SELECT url FROM senderlisten WHERE liste=\"$(settings senderliste)\" AND sendername=\"$1\";")
if [ ! -z $url ]; then
player="$(settings player)"
close_player_windows "$player"
if [[ "$player" == 'QuickTime' ]]; then
open -a 'QuickTime Player.app' -u "$url"
else
open -a 'VLC.app' -u "$url"
fi
exit 0
fi
exit 1 # kein passender Senderstream in der DB gefunden
}
get_channels(){
if [ $(sqlite3 .tvmenu.db "SELECT COUNT(*) FROM senderlisten") -eq 0 ]; then
get_channels_zapp
get_channels_konerd
# Doppelte und nicht abspielbare Streams löschen
sqlite3 .tvmenu.db "DELETE FROM senderlisten WHERE rowid NOT IN (SELECT min(rowid) FROM senderlisten GROUP BY url);"
sqlite3 .tvmenu.db "DELETE FROM senderlisten WHERE url LIKE '%@%';"
fi
}
get_channels_zapp(){
ch_url='https://raw.githubusercontent.com/mediathekview/zapp/main/app/src/main/res/raw/channels.json'
raw=$(curl -s --max-time 9 "$ch_url")
if [ "$?" -eq 0 ]; then
IFS=$'\n' ch_raw=($(grep '"name"' <<< "$raw")) ; unset IFS
IFS=$'\n' url_raw=($(grep '"stream_url"' <<< "$raw")) ; unset IFS
# Sicherheitsabfrage falls beim Parsen Fehler aufgetreten sind
if [[ ${#ch_raw[*]} -eq ${#url_raw[*]} ]] && [ ${#ch_raw[*]} -gt 0 ]; then
t='": "' # Trennzeichen
for ((i=0;i<${#ch_raw[*]}; i++)); do
n=${ch_raw[i]}; n=${n#*"$t"} ; n=${n:0:$((${#n} - 2))}
u=${url_raw[i]}; u=${u#*"$t"} ; u=${u:0:$((${#u} - 2))}
n=${n//\\u00ad/} # Shy bedingter Trennstrich entfernen
sqlite3 .tvmenu.db "INSERT OR IGNORE INTO senderlisten VALUES (\"oerr\", \"${n}\", \"${u}\");"
done
fi
fi
# Ersatz für ZAPP Streams die nicht mit QT funktionieren
declare -a fixes=(
'tagesschau24|https://tagesschau.akamaized.net/hls/live/2020115/tagesschau/tagesschau_1/master.m3u8'
'NDR Hamburg|https://mcdn.ndr.de/ndr/hls/ndr_fs/ndr_hh/master.m3u8'
'NDR Niedersachsen|https://mcdn.ndr.de/ndr/hls/ndr_fs/ndr_nds/master.m3u8'
'NDR Mecklenburg-Vorpommern|https://mcdn.ndr.de/ndr/hls/ndr_fs/ndr_mv/master.m3u8'
'NDR Schleswig-Holstein|https://mcdn.ndr.de/ndr/hls/ndr_fs/ndr_sh/master.m3u8'
'SWR Baden-Württemberg|https://swrbwd-hls.akamaized.net/hls/live/2018672/swrbwd/master.m3u8'
'SWR Rheinland-Pfalz|https://swrrpd-hls.akamaized.net/hls/live/2018676/swrrpd/master.m3u8'
)
for fix in "${fixes[@]}"; do
sqlite3 .tvmenu.db "INSERT OR IGNORE INTO senderlisten VALUES (\"oerr\", \"${fix%%|*}\", \"${fix##*|}\");"
done
}
get_channels_konerd(){
declare -a kodinerds_channels=(
'sonst|https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/iptv/clean/clean_tv_main.m3u'
'lokal|https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/iptv/clean/clean_tv_local.m3u'
'ach|https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/iptv/clean/clean_tv_atch.m3u'
'usuk|https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/iptv/clean/clean_tv_usuk.m3u'
'inter|https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/iptv/clean/clean_tv_international.m3u'
)
for kodinerds in "${kodinerds_channels[@]}"; do
kn_liste="${kodinerds%|*}"
kn_url="${kodinerds##*|}"
ch_raw=$(curl -s "$kn_url")
IFS=$'\n'
ch_info=($(grep "^#EXTINF" <<<"$ch_raw"))
ch_url=($(grep "^http" <<<"$ch_raw"))
unset IFS
if [ ${#ch_info[*]} -eq ${#ch_url[*]} ]; then
for ((i = 0 ; i < ${#ch_url[*]} ; i++)); do
info_name=$(cut -d'"' -f 2 <<<"${ch_info[i]}")
sqlite3 .tvmenu.db "INSERT OR IGNORE INTO senderlisten VALUES (\"${kn_liste}\", \"${info_name}\", \"${ch_url[i]}\");"
done
fi
done
# Fix für Gruppierungserkennug
sqlite3 .tvmenu.db "UPDATE senderlisten SET sendername = REPLACE(sendername, 'Adult Swim', 'AdultSwim');"
}
force_update(){
sqlite3 .tvmenu.db "DELETE FROM senderliste;"
sqlite3 .tvmenu.db "DELETE FROM menuitems;"
get_channels
update_sendermenu
}
update_sendermenu(){
sqlite3 .tvmenu.db "DELETE FROM menuitems;"
unset listen
IFS=$'\n' read -rd '' -a listen < <(sqlite3 .tvmenu.db "SELECT DISTINCT liste FROM senderlisten;");
unset IFS
for akt_senderliste in "${listen[@]}"; do
unset channels
unset sender_menu
IFS=$'\n' read -rd '' -a channels < <(sqlite3 .tvmenu.db "SELECT sendername FROM senderlisten WHERE liste=\"$akt_senderliste\" ORDER BY sendername COLLATE NOCASE;")
unset IFS
for channel in "${channels[@]}"; do
sender="${channel%|*}"
url="${channel##*|}"
sendername="$sender"
sender_menu+=("$sendername")
done
unset sender_gruppen
IFS=$'\n'
sender_menu=($(sort -f <<<"${sender_menu[*]}"))
read -rd '' -a sender_gruppen < <(sqlite3 .tvmenu.db "SELECT SUBSTR(sendername, 1, INSTR(sendername, ' ')) FROM senderlisten GROUP BY SUBSTR(sendername, 1, INSTR(sendername, ' ')) HAVING COUNT(*) > 1;")
unset IFS
unset gruppen_submenu
temp="" ; temp_c=0
for ((i=0;i<${#sender_gruppen[*]}; i++)); do
if [[ ${sender_gruppen[i]} == "$temp" ]]; then
((temp_c++))
else
temp="${sender_gruppen[i]}"
temp_c=1
fi
if [[ temp_c -ge gruppen_min ]] && [[ ! " ${gruppen_submenu[*]} " =~ ${sender_gruppen[i]} ]]; then
gruppen_submenu+=("${sender_gruppen[i]}")
fi
done
gruppe_aktuell=""
for sendername in "${sender_menu[@]}"; do
gruppe="${sendername%% *}"
if [[ " ${gruppen_submenu[*]} " =~ ${gruppe} ]]; then
if [[ ${gruppe} != "${gruppe_aktuell}" ]]; then
sqlite3 .tvmenu.db "INSERT INTO menuitems VALUES ('G', \"${akt_senderliste}\", \"${gruppe}\", '');"
gruppe_aktuell="$gruppe"
fi
item="--${sendername}"
command="$item_selected'${sendername}'"
sqlite3 .tvmenu.db "INSERT INTO menuitems VALUES ('G', \"${akt_senderliste}\", \"${item}\", \"${command}\");"
else
item="${sendername}"
command="$item_selected'${sendername}'"
sqlite3 .tvmenu.db "INSERT INTO menuitems VALUES ('G', \"${akt_senderliste}\", \"${item}\", \"${command}\");"
fi
item="${sendername}"
command="$item_selected'${sendername}'"
sqlite3 .tvmenu.db "INSERT INTO menuitems VALUES ('N', \"${akt_senderliste}\", \"${item}\", \"${command}\");"
done
done
senderlisten_auswahl_anlegen
}
senderlisten_auswahl_anlegen(){
sqlite3 .tvmenu.db "INSERT INTO menuitems VALUES ('L', '', '---', '');"
sqlite3 .tvmenu.db "INSERT INTO menuitems VALUES ('L', '', 'Senderlisten', '');"
IFS=$'\n'
for liste in $(sqlite3 .tvmenu.db "SELECT DISTINCT liste FROM senderlisten;"); do
command="${item_selected}list_${liste}"
# Senderlistenkürzel in Menüdarstellung ändern
liste=${liste/oerr/D ÖRR}
liste=${liste/sonst/D Sonstige}
liste=${liste/lokal/D lokal}
liste=${liste/ach/A CH}
liste=${liste/usuk/US UK}
liste=${liste/inter/International}
item="--${liste}"
sqlite3 .tvmenu.db "INSERT INTO menuitems VALUES ('L', '', \"${item}\", \"${command}\");"
done
unset IFS
sqlite3 .tvmenu.db "INSERT INTO menuitems VALUES ('L', '', '---', '');"
}
update_settings_submenu(){
sqlite3 .tvmenu.db "DELETE FROM menuitems WHERE menuart='S';"
sqlite3 .tvmenu.db "INSERT INTO menuitems VALUES ('S', '', 'Einstellungen', '');"
if check_VLC ; then
player=$(settings player)
if [[ $player == 'QuickTime' ]]; then
sqlite3 .tvmenu.db "INSERT INTO menuitems VALUES ('S', '', '--VLC verwenden', \"$item_selected'VLC verwenden'\");"
else
sqlite3 .tvmenu.db "INSERT INTO menuitems VALUES ('S', '', '--QT Player verwenden', \"$item_selected'QT Player verwenden'\");"
fi
else
sqlite3 .tvmenu.db "INSERT INTO menuitems VALUES ('S', '', '--VLC verwenden', '');"
fi
submenu=$(settings gruppierung)
if [[ $submenu == 'an' ]]; then
sqlite3 .tvmenu.db "INSERT INTO menuitems VALUES ('S', '', '--Gruppierung ausschalten', \"$item_selected'Gruppierung ausschalten'\");"
else
sqlite3 .tvmenu.db "INSERT INTO menuitems VALUES ('S', '', '--Sender gruppieren', \"$item_selected'Sender gruppieren'\");"
fi
sqlite3 .tvmenu.db "INSERT INTO menuitems VALUES ('S', '', '--Senderlisten aktualisieren', \"$item_selected'Senderlisten aktualisieren'\");"
}
menu_ausgeben(){
submenu=$(settings gruppierung)
akt_senderliste=$(settings senderliste)
if [[ $submenu == 'an' ]]; then
menuart='G'
else
menuart='N'
fi
sqlite3 .tvmenu.db "SELECT item, command FROM menuitems WHERE menuart=\"$menuart\" AND liste=\"$akt_senderliste\";" # aktuelle Senderliste
sqlite3 .tvmenu.db "SELECT item, command FROM menuitems WHERE menuart='L';" # Submenü Senderlisten
sqlite3 .tvmenu.db "SELECT item, command FROM menuitems WHERE menuart='S';" # Submenü Servicemenu
}
# Main
echo "📺" # echo "TV" # Menubar Icon/Text
echo "---"
item_selected="bash='$0' terminal=false refresh=true param1="
check_database
# Übergabeparameter auswerten
if [ "$#" -gt 0 ]; then
parameter="$*"
case "$parameter" in
'Senderlisten aktualisieren')
force_update
;;
'VLC verwenden')
if check_VLC ; then
settings 'player' 'VLC'
fi
;;
'QT Player verwenden')
settings 'player' 'QuickTime'
;;
'Gruppierung ausschalten')
settings 'gruppierung' 'aus'
;;
'Sender gruppieren')
settings 'gruppierung' 'an'
;;
[l][i][s][t]*)
settings 'senderliste' "${parameter##*_}"
;;
*)
stream_abspielen "$parameter"
exit 0 # Menuausgabe nicht notwendig
;;
esac
if [[ "$parameter" == 'VLC verwenden' ]] || [[ "$parameter" == 'QT Player verwenden' ]]; then
update_settings_submenu
fi
if [[ "$parameter" == 'Sender gruppieren' ]] || [[ "$parameter" == 'Gruppierung ausschalten' ]]; then
update_settings_submenu
fi
fi
menu_ausgeben
exit 0