Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ff24c65

Browse files
authored
Merge pull request streamlink#675 from beardypig/hls-name-fmt
stream.hls: format string name input for parse_variant_playlist
2 parents e0a20f5 + e1b6677 commit ff24c65

3 files changed

Lines changed: 50 additions & 14 deletions

File tree

src/streamlink/plugin/plugin.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
from ..exceptions import PluginError, NoStreamsError
88
from ..options import Options
99

10+
# FIXME: This is a crude attempt at making a bitrate's
11+
# weight end up similar to the weight of a resolution.
12+
# Someone who knows math, please fix.
13+
BIT_RATE_WEIGHT_RATIO = 2.8
1014

1115
QUALITY_WEIGTHS_EXTRA = {
1216
"other": {
@@ -37,28 +41,28 @@ def stream_weight(stream):
3741
if stream in weights:
3842
return weights[stream], group
3943

40-
match = re.match("^(\d+)([k]|[p])?(\d*)([\+])?$", stream)
44+
match = re.match(r"^(\d+)(k|p)?(\d+)?(\+)?(?:_(\d+)k)?$", stream)
4145

4246
if match:
43-
if match.group(2) == "k":
47+
name_type = match.group(2)
48+
if name_type == "k": # bit rate
4449
bitrate = int(match.group(1))
45-
46-
# FIXME: This is a crude attempt at making a bitrate's
47-
# weight end up similar to the weight of a resolution.
48-
# Someone who knows math, please fix.
49-
weight = bitrate / 2.8
50+
weight = bitrate / BIT_RATE_WEIGHT_RATIO
5051

5152
return weight, "bitrate"
5253

53-
elif match.group(2) == "p":
54+
elif name_type == "p": # resolution
5455
weight = int(match.group(1))
5556

56-
if match.group(3):
57+
if match.group(3): # fps eg. 60p or 50p
5758
weight += int(match.group(3))
5859

5960
if match.group(4) == "+":
6061
weight += 1
6162

63+
if match.group(5): # bit rate classifier for resolution
64+
weight += int(match.group(5)) / BIT_RATE_WEIGHT_RATIO
65+
6266
return weight, "pixels"
6367

6468
return 0, "none"
@@ -85,7 +89,7 @@ def stream_type_priority(stream_types, stream):
8589

8690

8791
def stream_sorting_filter(expr, stream_weight):
88-
match = re.match(r"(?P<op><=|>=|<|>)?(?P<value>[\w\+]+)", expr)
92+
match = re.match(r"(?P<op><=|>=|<|>)?(?P<value>[\w+]+)", expr)
8993

9094
if not match:
9195
raise PluginError("Invalid filter expression: {0}".format(expr))

src/streamlink/stream/hls.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,16 +271,18 @@ def open(self):
271271
@classmethod
272272
def parse_variant_playlist(cls, session_, url, name_key="name",
273273
name_prefix="", check_streams=False,
274-
force_restart=False,
274+
force_restart=False, name_fmt=None,
275275
**request_params):
276276
"""Attempts to parse a variant playlist and return its streams.
277277
278278
:param url: The URL of the variant playlist.
279279
:param name_key: Prefer to use this key as stream name, valid keys are:
280280
name, pixels, bitrate.
281281
:param name_prefix: Add this prefix to the stream names.
282+
:param check_streams: Only allow streams that are accessible.
282283
:param force_restart: Start at the first segment even for a live stream
283-
:param check_streams: Only allow streams that are accesible.
284+
:param name_fmt: A format string for the name, allowed format keys are
285+
name, pixels, bitrate.
284286
"""
285287
logger = session_.logger.new_module("hls.parse_variant_playlist")
286288
locale = session_.localization
@@ -338,8 +340,11 @@ def parse_variant_playlist(cls, session_, url, name_key="name",
338340
else:
339341
names["bitrate"] = "{0}k".format(bw / 1000.0)
340342

341-
stream_name = (names.get(name_key) or names.get("name") or
342-
names.get("pixels") or names.get("bitrate"))
343+
if name_fmt:
344+
stream_name = name_fmt.format(**names)
345+
else:
346+
stream_name = (names.get(name_key) or names.get("name") or
347+
names.get("pixels") or names.get("bitrate"))
343348

344349
if not stream_name:
345350
continue

tests/test_plugin_stream.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from streamlink import Streamlink
44
from streamlink.plugins.stream import StreamURL
5+
from streamlink.plugin.plugin import stream_weight
56
from streamlink.stream import *
67

78

@@ -107,5 +108,31 @@ def test_parse_params(self):
107108
StreamURL._parse_params(""""conn=['B:1', 'S:authMe', 'O:1', 'NN:code:1.23', 'NS:flag:ok', 'O:0']""")
108109
)
109110

111+
def test_stream_weight(self):
112+
self.assertEqual(
113+
(720, "pixels"),
114+
stream_weight("720p"))
115+
self.assertEqual(
116+
(721, "pixels"),
117+
stream_weight("720p+"))
118+
self.assertEqual(
119+
(780, "pixels"),
120+
stream_weight("720p60"))
121+
122+
self.assertTrue(
123+
stream_weight("720p+") > stream_weight("720p"))
124+
self.assertTrue(
125+
stream_weight("720p") == stream_weight("720p"))
126+
self.assertTrue(
127+
stream_weight("720p_3000k") > stream_weight("720p_2500k"))
128+
self.assertTrue(
129+
stream_weight("720p60_3000k") > stream_weight("720p_3000k"))
130+
self.assertTrue(
131+
stream_weight("720p_3000k") < stream_weight("720p+_3000k"))
132+
133+
self.assertTrue(
134+
stream_weight("3000k") > stream_weight("2500k"))
135+
136+
110137
if __name__ == "__main__":
111138
unittest.main()

0 commit comments

Comments
 (0)