Kodi Community Forum

Full Version: Help with getting remote m3u8 playlist working
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi everybody,


I'm working on an addon for the F1TV official streaming service.
I think I got the business logic/parsing of the API right.
Now I started to create a simple addon that lets you browse the entire archive of the streaming service.

However:
The stream itself is provided using an m3u8 file that seems to be unique per user/session.
When I try to open the link to this file using xbmc.Playlist().load(url) it just fails with the error:
bash:
17:59:26.370 T:123145319133184   ERROR: EXCEPTION Thrown (PythonToCppException) : -->Python callback/script returned the following error<--
                                             - NOTE: IGNORING THIS CAN LEAD TO MEMORY LEAKS!
                                            Error Type: <type 'exceptions.RuntimeError'>
                                            Error Contents: Not a valid playlist
                                            Traceback (most recent call last):
                                              File "/Users/bbsan/Library/Application Support/Kodi/addons/plugin.f1tv/main.py", line 249, in <module>
                                                router(sys.argv[2][1:])
                                              File "/Users/bbsan/Library/Application Support/Kodi/addons/plugin.f1tv/main.py", line 234, in router
                                                playContent(params['content_url'], params['content_type'])
                                              File "/Users/bbsan/Library/Application Support/Kodi/addons/plugin.f1tv/main.py", line 193, in playContent
                                                play_video(stream_url)
                                              File "/Users/bbsan/Library/Application Support/Kodi/addons/plugin.f1tv/main.py", line 207, in play_video
                                                playlist.load(path)
                                            RuntimeError: Not a valid playlist
                                            -->End of Python script error report<--

The M3U8 looks like the following:

m3u:

#EXTM3U
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS,GROUP-ID="cc",NAME="Closed Captions",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="eng",INSTREAM-ID="CC1"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="Encoding_0",NAME="FX",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="eng",URI="<<NAME_REMOVED>>.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="Encoding_0",NAME="English",AUTOSELECT=YES,LANGUAGE="eng",URI="<<NAME_REMOVED>>.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="Encoding_0",NAME="German",AUTOSELECT=YES,LANGUAGE="ger",URI="<<NAME_REMOVED>>.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="Encoding_0",NAME="French",AUTOSELECT=YES,LANGUAGE="fre",URI="<<NAME_REMOVED>>.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="Encoding_0",NAME="Spanish",AUTOSELECT=YES,LANGUAGE="spa",URI="<<NAME_REMOVED>>.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=7015190,AVERAGE-BANDWIDTH=5742536,CODECS="avc1.640028,mp4a.40.2",AUDIO="Encoding_0",RESOLUTION=1920x1080,FRAME-RATE=30,CLOSED-CAPTIONS="cc"
<<NAME_REMOVED>>.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5190321,AVERAGE-BANDWIDTH=4209836,CODECS="avc1.4D4020,mp4a.40.2",AUDIO="Encoding_0",RESOLUTION=1280x720,FRAME-RATE=30,CLOSED-CAPTIONS="cc"
<<NAME_REMOVED>>.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2963291,AVERAGE-BANDWIDTH=2370596,CODECS="avc1.4D401F,mp4a.40.2",AUDIO="Encoding_0",RESOLUTION=1024x576,FRAME-RATE=30,CLOSED-CAPTIONS="cc"
<<NAME_REMOVED>>.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1952811,AVERAGE-BANDWIDTH=1553156,CODECS="avc1.4D401E,mp4a.40.2",AUDIO="Encoding_0",RESOLUTION=768x432,FRAME-RATE=30,CLOSED-CAPTIONS="cc"
<<NAME_REMOVED>>.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1310282,AVERAGE-BANDWIDTH=1042256,CODECS="avc1.4D401E,mp4a.40.2",AUDIO="Encoding_0",RESOLUTION=640x360,FRAME-RATE=30,CLOSED-CAPTIONS="cc"
<<NAME_REMOVED>>.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=918388,AVERAGE-BANDWIDTH=735716,CODECS="avc1.4D4015,mp4a.40.2",AUDIO="Encoding_0",RESOLUTION=512x288,FRAME-RATE=30,CLOSED-CAPTIONS="cc"
<<NAME_REMOVED>>.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=518511,AVERAGE-BANDWIDTH=429176,CODECS="avc1.4D400D,mp4a.40.2",AUDIO="Encoding_0",RESOLUTION=384x216,FRAME-RATE=30,CLOSED-CAPTIONS="cc"
<<NAME_REMOVED>>.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=191972,AVERAGE-BANDWIDTH=188031,CODECS="mp4a.40.2",AUDIO="Encoding_0"
<<NAME_REMOVED>>.m3u8

Code to open:
python:

playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
playlist.load(path)
xbmc.Player().play(playlist)

Am I missing something?

Thanks for your help
How could we tell anything without seeing the code?

And I guess even with the code we couldn't help much. There must be a reason you edited the files before providing them.

That's only a personal guess, but if you want us to support any kind of piracy, then this is the wrong forum for you.
Try:
 
python:
xbmc.Player().play(path)
No, this is definitely not about piracy.
I even implemented a layer using their official authorization API.

The reason I edited the file is because in each returned playlist there are user specific tokens, and as I donˋt want to share my credentials/tokens here I needed to edit them...
(2018-08-06, 19:23)JinJin Wrote: [ -> ]Try:
 
python:
xbmc.Player().play(path)
 You are my hero sir!

Thanks a lot - it works even better than expected.


Now some more code cleanup needs to be done and eventually I can start publishing it at the weekend!
Thanks for working on it, much appreciated.
If you have further questions feel free to ask here. If you need testers (mainly from germany) let me know.
Alright, I will definitely need further support for testing esp. because I would like somebody with TV Access to test (I only have Pro).

I‘ll post an update here once I did some further cleanup!
Okay...
I guess I pretty much made some progress with my addon.
Unfortunately, there are still issues with the playlist:
In some of the m3u files there are variants for each stream:
m3u:

#EXTM3U
#EXT-X-VERSION:4
## Created with Unified Streaming Platform(version=1.7.32)
# AUDIO groups
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-aacl-128",LANGUAGE="zxx",NAME="No linguistic content",DEFAULT=YES,AUTOSELECT=YES,CHANNELS="2",URI="layer_7_<<SPECIAL_TOKEN>>/<<FILENAME>>_<<SPECIAL_TOKEN>>_7.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-aacl-130",LANGUAGE="de",NAME="German",DEFAULT=YES,AUTOSELECT=YES,CHANNELS="2",URI="layer_8_<<SPECIAL_TOKEN>>/<<FILENAME>>_<<SPECIAL_TOKEN>>_8.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-aacl-130",LANGUAGE="fr",NAME="French",AUTOSELECT=YES,CHANNELS="2",URI="layer_9_<<SPECIAL_TOKEN>>/<<FILENAME>>_<<SPECIAL_TOKEN>>_9.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-aacl-129",LANGUAGE="en",NAME="English",DEFAULT=YES,AUTOSELECT=YES,CHANNELS="2",URI="layer_10_<<SPECIAL_TOKEN>>/<<FILENAME>>_<<SPECIAL_TOKEN>>_10.m3u8"
# variants
#EXT-X-STREAM-INF:BANDWIDTH=8499000,AVERAGE-BANDWIDTH=7179000,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=25,AUDIO="audio-aacl-128",CLOSED-CAPTIONS=NONE
layer_0_<<SPECIAL_TOKEN>>/<<FILENAME>>_<<SPECIAL_TOKEN>>_0.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=4769000,AVERAGE-BANDWIDTH=4114000,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=1280x720,FRAME-RATE=25,AUDIO="audio-aacl-128",CLOSED-CAPTIONS=NONE
layer_1_<<SPECIAL_TOKEN>>/<<FILENAME>>_<<SPECIAL_TOKEN>>_1.m3u8
<<....MORE VARIANTS OF THIS IN DIFFERENT RESOLUTIONS....>>
#EXT-X-STREAM-INF:BANDWIDTH=8509000,AVERAGE-BANDWIDTH=7181000,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=25,AUDIO="audio-aacl-130",CLOSED-CAPTIONS=NONE
layer_0_<<SPECIAL_TOKEN>>/<<FILENAME>>_<<SPECIAL_TOKEN>>_0.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=4779000,AVERAGE-BANDWIDTH=4116000,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=1280x720,FRAME-RATE=25,AUDIO="audio-aacl-130",CLOSED-CAPTIONS=NONE
layer_1_<<SPECIAL_TOKEN>>/<<FILENAME>>_<<SPECIAL_TOKEN>>_1.m3u8
<<....MORE VARIANTS OF THIS IN DIFFERENT RESOLUTIONS....>>
#EXT-X-STREAM-INF:BANDWIDTH=8506000,AVERAGE-BANDWIDTH=7180000,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=25,AUDIO="audio-aacl-129",CLOSED-CAPTIONS=NONE
layer_0_<<SPECIAL_TOKEN>>/<<FILENAME>>_<<SPECIAL_TOKEN>>_0.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=4776000,AVERAGE-BANDWIDTH=4115000,CODECS="avc1.4D401F,mp4a.40.2",RESOLUTION=1280x720,FRAME-RATE=25,AUDIO="audio-aacl-129",CLOSED-CAPTIONS=NONE
layer_1_<<SPECIAL_TOKEN>>/<<FILENAME>>_<<SPECIAL_TOKEN>>_1.m3u8
<<....MORE VARIANTS OF THIS IN DIFFERENT RESOLUTIONS....>>

In the above example you can see:
<<SPECIAL_TOKEN>> == Token that seems to be user/session specific
<<FILENAME>> == The filename of the m3u file, not relevant here. Is always the same

The problem is: When I try to view this with xbmc.Player().play(path), I only get ONE video (line 15) and TWO audio streams (line 6 + 7, group "audio-aacl-130").
Is it possible that the player does not evaluate the complete playlist file?
(2018-08-06, 19:23)JinJin Wrote: [ -> ]Try:
 
python:
xbmc.Player().play(path)

Xbmc.player is limited to scripts and NOT recommended for plugin use. Use setresolvedurl
https://codedocs.xyz/xbmc/xbmc/group__py...3977acde0f
xbmc.Player() is used to prevent "watched" marks and resume points from being saved for live content links.
(2018-08-12, 17:08)V8MEM Wrote: [ -> ]xbmc.Player() is used to prevent "watched" marks and resume points from being saved for live content links.
It doesn't work this way... you are using a hack and improperly using the xbmc.player() class which was designed for scripts and not the plugin VFS.
https://forum.kodi.tv/showthread.php?tid=325059 << easier workaround that uses setresolver.