190 lines
17 KiB
Python
Executable File
190 lines
17 KiB
Python
Executable File
#!/usr/bin/python3
|
|
"""
|
|
A little script for viewing German Live TV (and scraping the URLs off
|
|
of mediathekview's metadata.
|
|
|
|
Distributed under CC-0 (public domain), except for the contents of
|
|
LIST_CACHE, which is formally GPL-3 (but it's hard to figure out
|
|
who holds the copyright, and I don't think anyone wants to claim it).
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import re
|
|
import sys
|
|
import time
|
|
from urllib import request
|
|
|
|
|
|
LIST_URL = ("https://raw.githubusercontent.com/mediathekview"
|
|
"/MServer/master/dist/live-streams.json")
|
|
|
|
|
|
LIST_CACHE = """{
|
|
\"Filmliste\" : [ \"22.10.2018, 19:29\", \"22.10.2018, 19:29\", \"3\", \"MSearch [Rel: 550] - Compiled: 29.05.2016 / 16:16:25\", \"92bdd1d2c16779f916e64d0bcf493c81\" ],
|
|
\"Filmliste\" : [ \"Sender\", \"Thema\", \"Titel\", \"Datum\", \"Zeit\", \"Dauer\", \"Größe [MB]\", \"Beschreibung\", \"Url\", \"Website\", \"Untertitel\", \"UrlRTMP\", \"Url_Klein\", \"UrlRTMP_Klein\", \"Url_HD\", \"UrlRTMP_HD\", \"DatumL\", \"Url_History\", \"Geo\", \"neu\" ],
|
|
\"X\" : [ \"3Sat\", \"Livestream\", \"3Sat Livestream\", \"\", \"\", \"\", \"\", \"\", \"http://zdf-hls-18.akamaized.net/hls/live/2016501/dach/high/master.m3u8\", \"http://www.zdf.de/ZDFmediathek/hauptnavigation/live\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"ARD\", \"Livestream\", \"ARD Livestream\", \"\", \"\", \"\", \"\", \"\", \"http://mcdn.daserste.de/daserste/de/master.m3u8\", \"https://www.ardmediathek.de/live/Y3JpZDovL2Rhc2Vyc3RlLmRlL0xpdmVzdHJlYW0tRGFzRXJzdGU/\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"ARD\", \"Livestream\", \"ARD Alpha Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://mcdn.br.de/br/fs/ard_alpha/hls/de/master.m3u8\", \"https://www.ardmediathek.de/live/Y3JpZDovL2JyLmRlL0xpdmVzdHJlYW0tQVJELUFscGhh/\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"ARD\", \"Livestream\", \"ARD ONE Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://mcdn.one.ard.de/ardone/hls/master.m3u8\", \"https://www.ardmediathek.de/live/Y3JpZDovL3dkci5kZS9CZWl0cmFnLTFlNjA0YWFlLTViODctNGMzNC04ZDhmLTg4OWI1ZjE2ZDU3Mw/\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"ARD\", \"Livestream\", \"ARD Tagesschau Livestream\", \"\", \"\", \"\", \"\", \"\", \"http://tagesschau-lh.akamaihd.net/i/tagesschau_1@119231/master.m3u8\", \"https://www.ardmediathek.de/live/Y3JpZDovL2Rhc2Vyc3RlLmRlL3RhZ2Vzc2NoYXUvbGl2ZXN0cmVhbQ/\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"ARTE.DE\", \"Livestream\", \"ARTE.DE Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://artesimulcast.akamaized.net/hls/live/2030993/artelive_de/index.m3u8\", \"https://www.arte.tv/de/live/\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"ARTE.FR\", \"Livestream\", \"ARTE.FR Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://artesimulcast.akamaized.net/hls/live/2031003/artelive_fr/index.m3u8\", \"https://www.arte.tv/fr/direct/\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"BR\", \"Livestream\", \"BR Nord Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://mcdn.br.de/br/fs/bfs_nord/hls/de/master.m3u8\", \"https://www.br.de/mediathek/live\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"BR\", \"Livestream\", \"BR Süd Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://mcdn.br.de/br/fs/bfs_sued/hls/de/master.m3u8\", \"https://www.br.de/mediathek/live\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"DW\", \"Livestream\", \"DW Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://dwamdstream111.akamaized.net/hls/live/2017972/dwstream111/index.m3u8\", \"https://www.dw.com\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"HR\", \"Livestream\", \"HR Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://hrhls.akamaized.net/hls/live/2024525/hrhls/master.m3u8\", \"https://www.ardmediathek.de/live/Y3JpZDovL2hyLmRlL0xpdmVzdHJlYW0tSFI/\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"KiKA\", \"Livestream\", \"KiKA Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://kikageohls.akamaized.net/hls/live/2022693/livetvkika_de/master.m3u8\", \"https://www.ardmediathek.de/live/Y3JpZDovL2tpa2EuZGUvTGl2ZXN0cmVhbS1LaUth/\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"MDR\", \"Livestream\", \"MDR Sachsen Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://mdrtvsnhls.akamaized.net/hls/live/2016928/mdrtvsn/master.m3u8\", \"https://www.mdr.de/video/livestreams/fernsehen/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"MDR\", \"Livestream\", \"MDR Sachsen-Anhalt Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://mdrtvsahls.akamaized.net/hls/live/2016879/mdrtvsa/master.m3u8\", \"https://www.mdr.de/video/livestreams/sachsen-anhalt/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"MDR\", \"Livestream\", \"MDR Thüringen Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://mdrtvthhls.akamaized.net/hls/live/2016880/mdrtvth/master.m3u8\", \"https://www.mdr.de/video/livestreams/thueringen/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"NDR\", \"Livestream\", \"NDR Hamburg\", \"\", \"\", \"\", \"\", \"\", \"https://ndrfs-lh.akamaihd.net/i/ndrfs_hh@430231/master.m3u8\", \"https://www.ndr.de/fernsehen/livestream/livestream223.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"NDR\", \"Livestream\", \"NDR Mecklenburg-Vorpommern\", \"\", \"\", \"\", \"\", \"\", \"https://mcdn.ndr.de/ndr/hls/ndr_fs/ndr_mv/master.m3u8\", \"https://www.ndr.de/fernsehen/livestream/livestream221.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"NDR\", \"Livestream\", \"NDR Niedersachsen\", \"\", \"\", \"\", \"\", \"\", \"https://mcdn.ndr.de/ndr/hls/ndr_fs/ndr_nds/master.m3u8\", \"https://www.ndr.de/fernsehen/livestream/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"NDR\", \"Livestream\", \"NDR Schleswig-Holstein\", \"\", \"\", \"\", \"\", \"\", \"https://mcdn.ndr.de/ndr/hls/ndr_fs/ndr_sh/master.m3u8\", \"https://www.ndr.de/fernsehen/livestream/livestream219.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"ORF\", \"Livestream\", \"ORF-1 Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://orf1.mdn.ors.at/out/u/orf1/qxb/manifest.m3u8\", \"http://tvthek.orf.at/live\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"ORF\", \"Livestream\", \"ORF-2 Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://orf2.mdn.ors.at/out/u/orf2/qxb/manifest.m3u8\", \"http://tvthek.orf.at/live\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"ORF\", \"Livestream\", \"ORF-3 Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://orf3.mdn.ors.at/out/u/orf3/qxb/manifest.m3u8\", \"http://tvthek.orf.at/live\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"ORF\", \"Livestream\", \"ORF-Sport Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://orfs.mdn.ors.at/out/u/orfs/qxb/manifest.m3u8\", \"http://tvthek.orf.at/live\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"RBB\", \"Livestream\", \"RBB Brandenburg Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://rbb-hls-brandenburg.akamaized.net/hls/live/2017825/rbb_brandenburg/master.m3u8\", \"https://www.ardmediathek.de/live/Y3JpZDovL3JiYi1vbmxpbmUuZGUvcmJiZmVybnNlaGVuL2xpdmVfYnJhbmRlbmJ1cmcvc2VuZGVwbGF0ei0tLWxpdmVzdHJlYW0tLS1icmFuZGVuYnVyZy0tLWhsczE/\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"RBB\", \"Livestream\", \"RBB Berlin Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://rbb-hls-berlin.akamaized.net/hls/live/2017824/rbb_berlin/master.m3u8\", \"https://www.ardmediathek.de/live/Y3JpZDovL3JiYi1vbmxpbmUuZGUvcmJiZmVybnNlaGVuL2xpdmVfYnJhbmRlbmJ1cmcvc2VuZGVwbGF0ei0tLWxpdmVzdHJlYW0tLS1icmFuZGVuYnVyZy0tLWhsczE/\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"SR\", \"Livestream\", \"SR Livestream\", \"\", \"\", \"\", \"\", \"\", \"http://srlive24-lh.akamaihd.net/i/sr_universal02@107595/master.m3u8\", \"https://www.ardmediathek.de/live/Y3JpZDovL3NyLW9ubGluZS5kZS8yODQ4NjAvbGl2ZXN0cmVhbQ/\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"SWR\", \"Livestream\", \"SWR BW Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://swrbwd-hls.akamaized.net/hls/live/2018672/swrbwd/master.m3u8\", \"https://www.ardmediathek.de/live/Y3JpZDovL3N3ci5kZS8xMzQ4MTA0Mg/\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"SWR\", \"Livestream\", \"SWR RP Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://swrrpd-hls.akamaized.net/hls/live/2018676/swrrpd/master.m3u8\", \"https://www.ardmediathek.de/live/Y3JpZDovL3N3ci5kZS8xMzQ4MTA0Mg/\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"WDR\", \"Livestream\", \"WDR Livestream (Deutschland)\", \"\", \"\", \"\", \"\", \"\", \"https://wdrfs247.akamaized.net/hls/live/681509/wdr_msl4_fs247/index.m3u8\", \"https://www1.wdr.de/fernsehen/livestream/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"WDR\", \"Livestream\", \"WDR Livestream (weltweit)\", \"\", \"\", \"\", \"\", \"\", \"https://mcdn.wdr.de/wdr/wdrfs/de/master.m3u8\", \"https://www.ardmediathek.de/live/Y3JpZDovL3dkci5kZS9CZWl0cmFnLTNkYTY2NGRlLTE4YzItNDY1MC1hNGZmLTRmNjQxNDcyMDcyYg/\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"WDR\", \"Livestream\", \"WDR Lokalzeit Aachen Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://wdrlokalzeit.akamaized.net/hls/live/2018019/wdrlz_aachen/index.m3u8\", \"https://www1.wdr.de/fernsehen/livestream/lokalzeit-livestream/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"WDR\", \"Livestream\", \"WDR Lokalzeit Bergisches Land Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://wdrlokalzeit.akamaized.net/hls/live/2018028/wdrlz_wuppertal/index.m3u8\", \"https://www1.wdr.de/fernsehen/livestream/lokalzeit-livestream/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"WDR\", \"Livestream\", \"WDR Lokalzeit Bonn Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://wdrlokalzeit.akamaized.net/hls/live/2018021/wdrlz_bonn/index.m3u8\", \"https://www1.wdr.de/fernsehen/livestream/lokalzeit-livestream/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"WDR\", \"Livestream\", \"WDR Lokalzeit Dortmund Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://wdrlokalzeit.akamaized.net/hls/live/2018022/wdrlz_dortmund/index.m3u8\", \"https://www1.wdr.de/fernsehen/livestream/lokalzeit-livestream/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"WDR\", \"Livestream\", \"WDR Lokalzeit Düsseldorf Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://wdrlokalzeit.akamaized.net/hls/live/2018023/wdrlz_duesseldorf/index.m3u8\", \"https://www1.wdr.de/fernsehen/livestream/lokalzeit-livestream/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"WDR\", \"Livestream\", \"WDR Lokalzeit Duisburg Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://wdrlokalzeit.akamaized.net/hls/live/2018024/wdrlz_duisburg/index.m3u8\", \"https://www1.wdr.de/fernsehen/livestream/lokalzeit-livestream/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"WDR\", \"Livestream\", \"WDR Lokalzeit Köln Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://wdrlokalzeit.akamaized.net/hls/live/2023550/wdrlz_koeln/index.m3u8\", \"https://www1.wdr.de/fernsehen/livestream/lokalzeit-livestream/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"WDR\", \"Livestream\", \"WDR Lokalzeit Münsterland Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://wdrlokalzeit.akamaized.net/hls/live/2018025/wdrlz_muensterland/index.m3u8\", \"https://www1.wdr.de/fernsehen/livestream/lokalzeit-livestream/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"WDR\", \"Livestream\", \"WDR Lokalzeit Ostwestfalen Lippe Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://wdrlokalzeit.akamaized.net/hls/live/2018026/wdrlz_bielefeld/index.m3u8\", \"https://www1.wdr.de/fernsehen/livestream/lokalzeit-livestream/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"WDR\", \"Livestream\", \"WDR Lokalzeit Ruhr Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://wdrlokalzeit.akamaized.net/hls/live/2018027/wdrlz_essen/index.m3u8\", \"https://www1.wdr.de/fernsehen/livestream/lokalzeit-livestream/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"WDR\", \"Livestream\", \"WDR Lokalzeit Südwestfalen Livestream\", \"\", \"\", \"\", \"\", \"\", \"https://wdrlokalzeit.akamaized.net/hls/live/2018020/wdrlz_siegen/index.m3u8\", \"https://www1.wdr.de/fernsehen/livestream/lokalzeit-livestream/index.html\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"ZDF\", \"Livestream\", \"ZDF Livestream\", \"\", \"\", \"\", \"\", \"\", \"http://zdf-hls-15.akamaized.net/hls/live/2016498/de/high/master.m3u8\", \"http://www.zdf.de/ZDFmediathek/hauptnavigation/live\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"ZDF\", \"Livestream\", \"ZDF.info Livestream\", \"\", \"\", \"\", \"\", \"\", \"http://zdf-hls-17.akamaized.net/hls/live/2016500/de/high/master.m3u8\", \"http://www.zdf.de/ZDFmediathek/hauptnavigation/live\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"ZDF\", \"Livestream\", \"ZDF.neo Livestream\", \"\", \"\", \"\", \"\", \"\", \"http://zdf-hls-16.akamaized.net/hls/live/2016499/de/high/master.m3u8\", \"http://www.zdf.de/ZDFmediathek/hauptnavigation/live\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ],
|
|
\"X\" : [ \"PHOENIX\", \"Livestream\", \"PHOENIX Livestream\", \"\", \"\", \"\", \"\", \"\", \"http://zdf-hls-19.akamaized.net/hls/live/2016502/de/high/master.m3u8\", \"http://www.zdf.de/ZDFmediathek/hauptnavigation/live\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" ]
|
|
}
|
|
"""
|
|
|
|
|
|
def update_stations():
|
|
"""modifies sys.argv[0]'s source to update the live URL list
|
|
from mediathekview's list.
|
|
|
|
Of course, this only works if the user has write permission to
|
|
this script.
|
|
"""
|
|
in_bytes = request.urlopen(LIST_URL).read()
|
|
self_path = sys.argv[0]
|
|
with open(self_path, "rb") as f:
|
|
src = f.read()
|
|
|
|
src = re.sub(b'(?s)LIST_CACHE\x20= """.*?"""',
|
|
b'LIST_CACHE\x20= """%s"""'%(in_bytes.replace(b'"', b'\\"')),
|
|
src)
|
|
|
|
with open(self_path, "wb") as f:
|
|
f.write(src)
|
|
|
|
|
|
def load_stations():
|
|
"""returns a mapping of station_id -> stream URL from the built-in json
|
|
station list.
|
|
"""
|
|
channels = {}
|
|
def collect(args):
|
|
for name, val in args:
|
|
if name=="X":
|
|
channels[val[2]] = val[8]
|
|
|
|
dec = json.JSONDecoder(object_pairs_hook=collect)
|
|
dec.decode(LIST_CACHE)
|
|
|
|
return channels
|
|
|
|
|
|
def write_dump(hls_url, args):
|
|
"""writes a dump of the stream to recorded.mp4.
|
|
|
|
This uses streamlink and changes the interpretation of max-bitrate.
|
|
Ah well.
|
|
"""
|
|
# regrettaly, mpv has dumped the copy codecs, it seems. I'll
|
|
# switch to streamlink for now. But that doesn't have
|
|
# mpv's nice bitrate selection. Aw, dang. I'll think
|
|
# about it if I actually care one day.
|
|
import streamlink
|
|
streams = streamlink.streams(hls_url)
|
|
try:
|
|
src = streams[args.hls_bitrate].open()
|
|
except KeyError:
|
|
sys.exit("Setze --max-bitrate auf eines von "+(" ".join(streams)))
|
|
|
|
start_time = time.time()
|
|
|
|
with open("recorded.mp4", "wb") as dest:
|
|
while True:
|
|
dest.write(src.read(2**20))
|
|
if time.time()-start_time>args.record:
|
|
break
|
|
|
|
|
|
def parse_command_line():
|
|
import argparse
|
|
parser = argparse.ArgumentParser(description="Livestream glotzen")
|
|
|
|
parser.add_argument("sender", help="Sendername -- leer lassen für"
|
|
" Liste, 'update', um interne Senderliste zu aktualisieren.",
|
|
nargs="*")
|
|
parser.add_argument("--max-bitrate", help="Max. Bitrate für die"
|
|
" Streamauswahl (kann auch min/max sein).",
|
|
dest="hls_bitrate", default="2000000")
|
|
parser.add_argument("--record", help="Nimm ZEIT Sekunden zu 'recorded.mp4'"
|
|
"auf.", dest="record", default=None, metavar="ZEIT", type=int)
|
|
return parser.parse_args()
|
|
|
|
|
|
def main():
|
|
args = parse_command_line()
|
|
station = " ".join(args.sender).lower()
|
|
|
|
if station=="":
|
|
print("\n".join(load_stations()))
|
|
|
|
elif station=="update":
|
|
update_stations()
|
|
|
|
else:
|
|
stations = load_stations()
|
|
matches = []
|
|
for key in stations:
|
|
matcher = key.lower()
|
|
if station==matcher:
|
|
matches = [key]
|
|
break
|
|
else:
|
|
if station in matcher:
|
|
matches.append(key)
|
|
|
|
if len(matches)==0:
|
|
sys.exit("Nichts passendes")
|
|
|
|
elif len(matches)>1:
|
|
sys.exit("? ".join(matches)+"?")
|
|
|
|
else:
|
|
if args.record:
|
|
write_dump(stations[matches[0]], args)
|
|
else:
|
|
os.execlp("mpv", "mpv",
|
|
f"--hls-bitrate={args.hls_bitrate}", stations[matches[0]])
|
|
|
|
|
|
if __name__=="__main__":
|
|
main()
|