globocom / m3u8

Python m3u8 Parser for HTTP Live Streaming (HLS) Transmissions
Other
1.98k stars 464 forks source link

Editing value in playlist.segment_map["uri"] is ignored by parser #234

Open viktorfreiman opened 3 years ago

viktorfreiman commented 3 years ago

Editing value in playlist.segment_map["uri"] is ignored by parser

m3u8-lib version: 0.7.1

$ cat normal_sub_v8.m3u8
#EXTM3U
#EXT-X-VERSION:8
#EXT-X-TARGETDURATION:6
#EXT-X-MAP:URI="volume_3246_0000/segment_0000_init.mp4"
#EXTINF:6.006,
volume_3246_0000/segment_0000.m4s
#EXTINF:6.006,
volume_3246_0000/segment_0001.m4s
#EXTINF:6.006,
volume_3246_0000/segment_0002.m4s
#EXT-X-ENDLIST
>>> import m3u8
>>> playlist = m3u8.load("normal_sub_v8.m3u8")
>>> playlist.segment_map["uri"] = "new_init_file.mp4"
>>> playlist.dump("output.m3u8")
$ cat output.m3u8
#EXTM3U
#EXT-X-VERSION:8
#EXT-X-TARGETDURATION:6
#EXT-X-MAP:URI="volume_3246_0000/segment_0000_init.mp4"
#EXTINF:6.006,
volume_3246_0000/segment_0000.m4s
#EXTINF:6.006,
volume_3246_0000/segment_0001.m4s
#EXTINF:6.006,
volume_3246_0000/segment_0002.m4s
#EXT-X-ENDLIST

There is no diff between normal_sub_v8.m3u8 and output.m3u8

To edit the init #EXT-X-MAP I have found that I need to use the
playlist.segments[0].init_section.uri = "NEW-INIT-MAP.mp4"
to make it work

But the problem is that you need to edit for every segment
and if you don't do it you will get the old #EXT-X-MAP on the next segment

>>> import m3u8
>>> playlist = m3u8.load("normal_sub_v8.m3u8")
>>> playlist.segments[0].init_section.uri = "NEW-INIT-MAP.mp4"
>>> playlist.dump("output2.m3u8")
$ cat output2.m3u8
#EXTM3U
#EXT-X-VERSION:8
#EXT-X-TARGETDURATION:6
#EXT-X-MAP:URI="NEW-INIT-MAP.mp4"
#EXTINF:6.006,
volume_3246_0000/segment_0000.m4s
#EXT-X-MAP:URI="volume_3246_0000/segment_0000_init.mp4"
#EXTINF:6.006,
volume_3246_0000/segment_0001.m4s
#EXTINF:6.006,
volume_3246_0000/segment_0002.m4s
#EXT-X-ENDLIST

Also;

Is there a way on removing a #EXT-X-MAP from the segment m3u8?
I tried to use del playlist.segments[1].init_section but I get a AttributeError
When I try to run playlist.dump("OUT_normal_sub_v8.m3u8")

Traceback (most recent call last):
  File "ks-playlist.py", line 34, in <module>
    playlist.dump("OUT_normal_sub_v8.m3u8")
  File "/home/vscode/.local/lib/python3.8/site-packages/m3u8/model.py", line 351, in dump
    fileobj.write(self.dumps())
  File "/home/vscode/.local/lib/python3.8/site-packages/m3u8/model.py", line 327, in dumps
    output.append(str(self.segments))
  File "/home/vscode/.local/lib/python3.8/site-packages/m3u8/model.py", line 552, in __str__
    output.append(segment.dumps(last_segment))
  File "/home/vscode/.local/lib/python3.8/site-packages/m3u8/model.py", line 471, in dumps
    if last_segment and self.init_section != last_segment.init_section:
AttributeError: 'Segment' object has no attribute 'init_section'
mauricioabreu commented 2 years ago

@viktorfreiman sorry for taking so long. We're investigating.

mauricioabreu commented 2 years ago

EXT-X-MAP is a tag designed to be placed before every segment, so, yes, I think we can have many of them and we must know which ones we want to update before hand. Do you think a helper method to update all of them at once would help?

But the problem is that you need to edit for every segment and if you don't do it you will get the old #EXT-X-MAP on the next segment

It happens because EXT-X-MAP is a tag designed for segments so, if you don't change it for every segment, the next one you forgot to updated will have the old value

Is there a way on removing a #EXT-X-MAP from the segment m3u8?

Sorry, but could you give me an example of how this could be useful?

viktorfreiman commented 6 months ago

Hi @mauricioabreu,

Great to see that you are still working and adding new stuff to the lib.

I bypassed the the issue with a hacky string replace. It worked but I would be nice to get the lib to do it. The reason I wanting the change it is that we serve the m3u8 from a central origin place with relative path m3u8 and we then change it to point to a specific edge node with absolut path for the clients. The init.mp4 is still the same to not break the player. We just have a diffrent url for it.

Like my exemple before I don't want it just move the init to the next segment I just want to change the the 0-index url init.mp4