-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdvb-vlc.py
executable file
·155 lines (120 loc) · 4.21 KB
/
dvb-vlc.py
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
#!/usr/bin/python3
import argparse
import re
import requests
import xml.etree.ElementTree as ET
categories = {
"TV HD": {
"m3u_path": "dvb/m3u/tvhd.m3u",
"logo_url": "https://tv.avm.de/tvapp/logos/hd",
},
"TV SD": {
"m3u_path": "dvb/m3u/tvsd.m3u",
"logo_url": "https://tv.avm.de/tvapp/logos",
},
"Radio": {
"m3u_path": "dvb/m3u/radio.m3u",
"logo_url": "https://tv.avm.de/tvapp/logos/radio",
},
}
logo_replace = [
("ä", "ae"),
("ö", "oe"),
("ü", "ue"),
("ß", "ss"),
("[.,-]", ""),
("[ /]+", "_"),
]
def get_arguments():
parser = argparse.ArgumentParser()
parser.add_argument(
"--host",
type=str,
default="dvb",
metavar="HOSTNAME",
help="hostname of FRITZ!WLAN Repeater DVB-C",
)
parser.add_argument(
"--output",
type=str,
default="dvb.xspf",
metavar="FILENAME",
help="output filename",
)
return parser.parse_args()
def get_m3u_channels(m3u_url):
channels = {}
# download m3u playlist
result = requests.get(m3u_url)
# split m3u playlist
lines = result.text.split("\n")
for l in range(1, len(lines) - 1, 3):
# title from 1st line
title = re.sub("^#EXTINF:0,", "", lines[l]).strip()
# option from 2nd line
option = re.sub("^#EXTVLCOPT:", "", lines[l + 1])
# url from 3rd line
url = lines[l + 2]
channels[title] = {"option": option, "url": url}
return channels
def get_channel_image(title, logo_url):
image = title.lower()
# replace patterns in image name
for pattern, repl in logo_replace:
image = re.sub(pattern, repl, image)
logo_url = "{}/{}.png".format(logo_url, image)
return logo_url
def add_playlist_logos(channels, url):
for title, channel in channels.items():
channel["image"] = get_channel_image(title, url)
def export_xspf_playlist(channel_lists, filename):
# create playlist root element
playlist = ET.Element("playlist")
playlist.set("xmlns", "http://xspf.org/ns/0/")
playlist.set("xmlns:vlc", "http://www.videolan.org/vlc/playlist/ns/0/")
playlist.set("version", "1")
# create playlist title, tracklist and playlist tree
ET.SubElement(playlist, "title").text = "DVB"
tracklist = ET.SubElement(playlist, "trackList")
playlist_tree = ET.SubElement(
playlist, "extension", application="http://www.videolan.org/vlc/playlist/0"
)
# use unique track ID so the playlist can reference the elements in the tracklist
track_id = 0
for category, channels in channel_lists.items():
# create node in playlist tree
playlist_node = ET.SubElement(playlist_tree, "vlc:node", title=category)
for title, channel in sorted(channels.items(), key=lambda x: x[0].lower()):
# add track to tracklist
track = ET.SubElement(tracklist, "track")
ET.SubElement(track, "title").text = title
ET.SubElement(track, "location").text = channel["url"]
ET.SubElement(track, "image").text = channel["image"]
# add track extension
track_ext = ET.SubElement(
track, "extension", application="http://www.videolan.org/vlc/playlist/0"
)
ET.SubElement(track_ext, "vlc:id").text = str(track_id)
ET.SubElement(track_ext, "vlc:option").text = channel["option"]
# add track to playlist tree
ET.SubElement(playlist_node, "vlc:item", tid=str(track_id))
track_id += 1
# write indented xspf playlist to file
ET.indent(playlist)
tree = ET.ElementTree(playlist)
tree.write(filename, encoding="UTF-8", xml_declaration=True)
def main():
# get arguments
args = get_arguments()
# download and convert m3u playlists
channel_lists = {}
for category, options in categories.items():
channels = get_m3u_channels(
"http://{}/{}".format(args.host, options["m3u_path"])
)
add_playlist_logos(channels, options["logo_url"])
channel_lists[category] = channels
# export xspf playlist
export_xspf_playlist(channel_lists, args.output)
if __name__ == "__main__":
main()