globocom / m3u8

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

Can't dump playlist with custom tags #347

Closed turfintl closed 4 months ago

turfintl commented 10 months ago

The playlist can be parsed with custom tags correctly. But when dumping the playlist, the parsed custom tags info will be lost.

bbayles commented 10 months ago

From the README:

This library ignores all the non-standard tags by default. If you want them to be collected while loading the file content, you need to pass a function to the load/loads functions...

To preserve a tag in the output, you may also need to subclass the Playlist or Segment classes and add in your logic.

ulville commented 9 months ago

I've basically written my custom dumps function to include custom tags in the output:

https://github.com/ulville/freeiptv/blob/master/testlinks.py#L24C1-L24C1

I could have created subclasses but it's just a quick and dirty solution if you need one.

PS: custom tag names are hardcoded

mauricioabreu commented 4 months ago

@ulville did it work fine? Could I add your code as an example? This way more people would learn from your code, parsing IPTV tags correctly.

ulville commented 4 months ago

@mauricioabreu it works fine for my use case. And would be helpful for others who need something similar too. You can add it as an example 👍🏼 Of course It would be better to write a more general function with args as custom tags etc. for general purpose usage and more so if implemented in the module itself

mauricioabreu commented 4 months ago

@ulville thank you!

Can you please explain in more details about your idea?

write a more general function with args as custom tags etc

ulville commented 4 months ago

@mauricioabreu Nevermind, I haven't looked at the code for a while so I forgot how thing worked.

Segment.custom_parser_values[key] already gives us the parsed list of custom tags. So no need to pass any aditional args. Only difference in my function would be having a for loop which loops through that list and appends them as "key=value" strings to output string (instead of doing it one by one, manually like I did). Only time we would want additional args is when we want to cherry-pick certain tags and only include them in the final dump.

I also looked at the ways we could implement it inside the M3U8.dumps and Segment.dumps and, well, I still think it's doable but not as easy as I initially thought. M3U8.dumps, Segment.dumps and SegmentList.dumps needs to be modified. Maybe adding them an additional boolean argument include_custom_values and another for specifying which custom_parser_values keys we want to include, something like custom_value_keys. Then inside Segment.dumps here https://github.com/globocom/m3u8/blob/1ac31c131940672829ec083ac20ef740617907e2/m3u8/model.py#L660 we can do something like:

        if self.uri:
            if self.duration is not None:
                output.append("#EXTINF:%s" % number_to_string(self.duration))
                if self.include_custom_values:
                    for key in custom_value_keys:
                        custom_tags = self.custom_parser_values[key]
                        for tag in custom_tags:
                            output.append(" %s=\"%s\"" % (tag, seg_props[tag]))
                if self.title:
                    output.append(","self.title)
                output.append("\n")
            ...
            ...

But I don't think it's any "general purpose" of a solution. It's very opinionated and very case spesific. Especially the location I append the custom tags.

Maybe writing your own custom dumps functions is just better in this case...

And as I said I haven't looked at the code for a while so excuse me if I made any mistakes here and there.

mauricioabreu commented 4 months ago

@ulville Thank you! There are all good ideas

I'm going to add your code in the docs to better document how to use custom tags

mauricioabreu commented 4 months ago

I've just noticed it is already in the docs 😆

ulville commented 4 months ago

@mauricioabreu where exactly? I couldn't find it. There is an example for parsing custom tags (that I took advantage of when writing my code) but I couldn't find anything mentioning dumping with them. Am I looking at the wrong place?

mauricioabreu commented 4 months ago

@ulville Here https://github.com/globocom/m3u8?tab=readme-ov-file#custom-tags

My mistake. I was reading your code thinking it was m3u8 docs 😕