Repository: globocom/m3u8

Issue:
EXT-X-BITRATE parsing returns value as string rather than int
[EXT-X-BITRATE](https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#section-4.4.4.8) is defined as a decimal integer describing the rate in kilobits per second.

Currently the parser will return this value [as a string](https://github.com/globocom/m3u8/blob/master/tests/test_parser.py#L859) which is awkward when working with this value.

I have a simple patch to parse and dump this as an int but it would technically be a small breaking change.

What do people think?

Discussion:
@mauricioabreu: @davemevans submit your PR, please. If it follows the spec, I'll gladly accept it. We can upgrade the major.@mauricioabreu: Closed via #379 

Solution patch:
diff --git a/m3u8/model.py b/m3u8/model.py
index 716852c..7f293d1 100644
--- a/m3u8/model.py
+++ b/m3u8/model.py
@@ -671,7 +671,7 @@ class Segment(BasePathMixin):
                 output.append("#EXT-X-BYTERANGE:%s\n" % self.byterange)
 
             if self.bitrate:
-                output.append("#EXT-X-BITRATE:%s\n" % self.bitrate)
+                output.append("#EXT-X-BITRATE:%d\n" % self.bitrate)
 
             if self.gap_tag:
                 output.append("#EXT-X-GAP\n")
diff --git a/m3u8/parser.py b/m3u8/parser.py
index c3a9e31..21c4d2c 100644
--- a/m3u8/parser.py
+++ b/m3u8/parser.py
@@ -439,10 +439,10 @@ def _parse_variant_playlist(line, data, state, **kwargs):
     state["expect_playlist"] = False
 
 
-def _parse_bitrate(line, state, **kwargs):
+def _parse_bitrate(state, **kwargs):
     if "segment" not in state:
         state["segment"] = {}
-    state["segment"]["bitrate"] = line.replace(protocol.ext_x_bitrate + ":", "")
+    state["segment"]["bitrate"] = _parse_simple_parameter(cast_to=int, **kwargs)
 
 
 def _parse_byterange(line, state, **kwargs):


Test patch:
diff --git a/tests/test_model.py b/tests/test_model.py
index 835db88..abeb61d 100755
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -1704,6 +1704,13 @@ def test_low_latency_output():
     assert actual == expected
 
 
+def test_bitrate_settable_as_int():
+    obj = m3u8.loads(playlists.BITRATE_PLAYLIST)
+    obj.segments[0].bitrate = 9876
+
+    assert "#EXT-X-BITRATE:9876" in obj.dumps().strip()
+
+
 # custom asserts
 
 
diff --git a/tests/test_parser.py b/tests/test_parser.py
index a501571..dae6f64 100644
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -856,8 +856,8 @@ def test_delta_playlist_daterange_skipping():
 
 def test_bitrate():
     data = m3u8.parse(playlists.BITRATE_PLAYLIST)
-    assert data["segments"][0]["bitrate"] == "1674"
-    assert data["segments"][1]["bitrate"] == "1625"
+    assert data["segments"][0]["bitrate"] == 1674
+    assert data["segments"][1]["bitrate"] == 1625
 
 
 def test_content_steering():