Kodi Community Forum

Full Version: HLS (.m3u8) and redirecting in XBMC
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Hello,
I was not sure where to post this, but here it goes. I am having issues with playing redirected .m3u8 streams in XBMC.
It's kinda hard to explain, so I'll try my best. I am not sure if this is a bug or if I do not understand how thing work in XBMC. Smile

I have a local web-server that provides http:// urls to all my XBMC units in the house (internet streams). When the url is called it fetches the channel Id and based on type of channel, generates propper url and redirects to it. So the redirected url can be anything, http, rtmp, rtsp, whatever. Some of the streams need to go via this server, in order to generate tokens and authenticate.

So the "start" url looks like this (local IP). This would commonly be in favourites.xml, a video-addon or in a .m3u file used in a pvr-addon that I use. Most streams work just fine this way:
http://192.168.1.10/RedirectToStream?chNr=374

In this particular case, the url returns\redirects to the external stream url of type .m3u8 (hls), that will look something like this:
http://ip-adress:port/live/TV1.stream/playlist.m3u8?token=4398756384975

This again returns a new .m3u8 file that contains "chunks", that will later on point to media.ts chunks:
Code:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1000476,RESOLUTION=640x360
chunk_2.m3u8


Now, the thing is that theese "chunk" parts are not full urls, they are just the filenames, and when XBMC tries to redirect to them, it thinks they are stored localy somewhere and the stream fails.
The url should be, in this case, http://ip-adress:port/live/TV1.stream/chunk_2.m3u8. It should redirect based on the url that originaly retrieved the playlist.m3u8 file.

What bothers me the most, is that this url-redirection works perfectly in VLC. it finds the propper url (the parent url) to redirect to, and it just works. But in XBMC it fails. See a snippet of debug log below.
Most interesting line is ffmpeg[96C]: ... it adds the chunk to 'pvr://channels/tv/All TV channels/'.
Code:
DEBUG: opening live stream on url 'http://192.168.1.10/RedirectToStream?chNr=374'
DEBUG: PVRFile - XFILE::CPVRFile::Open - playback has started on filename pvr://channels/tv/All TV channels/92.pvr
DEBUG: CFileCache::Open - opening </RedirectToStream> using cache
DEBUG: CurlFile::Open(0E1AA948) http://192.168.1.10/RedirectToStream?chNr=374
DEBUG: ------ Window Init (DialogBusy.xml) ------
DEBUG: CDVDInputStreamPVRManager::Open - stream opened: http://192.168.1.10/RedirectToStream?chNr=374
NOTICE: Creating Demuxer
NOTICE: Thread FileCache start, auto delete: false
  INFO: CFileCache::Process - Hit eof.
DEBUG: CDVDDemuxFFmpeg::Open - probing detected format [hls,applehttp]
ERROR: ffmpeg[96C]: [hls,applehttp] Error when loading first segment 'pvr://channels/tv/All TV channels/chunk_2.m3u8?token=4398756384975'
ERROR: CDVDDemuxFFmpeg::Open - Error, could not open file pvr://channels/tv/All TV channels/92.pvr
ERROR: CDVDDemuxFFmpeg::Open - error probing input format, pvr://channels/tv/All TV channels/92.pvr
ERROR: Previous line repeats 8 times.
ERROR: CDVDPlayer::OpenDemuxStream - Error creating demuxer
NOTICE: CDVDPlayer::OnExit()
NOTICE: CDVDPlayer::OnExit() deleting input stream

There is a similar post to the same issue here: http://forum.xbmc.org/showthread.php?tid...pid1540008

I'am just looking for guidance here. How should I resolve this? Is this a bug or limitation? If I was to compile my own version of xbmc where should I look in the code to modfiy this?
Thanks
Anyone?
Did I post this in the wrong forum perhaps?
Reading of segment playlist (not media/master playlist) is afaik done by ffmpeg, so it depends if ffmpeg can handle relative urls. I'm not sure that's the issue here though. The "pvr://" paths are virtual and is translated by the pvr manager, I don't think this should every be passed to the demuxer or ffmpeg. If you want to debug, check in DVDFactoryDemuxer and DVDDemuxFFmpeg::Open if the paths are correct
@takoi du er helt konge, takk skal du ha.

Thank you very much for pointing me in the right direction takoi! I've spent more than two days digging trough the code, trying to understand where things lead. Very confusing.

After debugging for hours I noticed that it used "CDVDInputStreamFile" to play the streams from my server. So the segmented playlists did not get handled correctly.
DVDFactoryDemuxer does indeed contain the capability to play streams via ffmpeg, but the stream needs to be the right type, and the type is set beforehand in the DVDFactoryInputStream.

I had to do two things:

1) Edit DVDFactoryInputStream, line 92 - to check for .strm extension
Code:
|| (item.IsInternetStream() && (item.IsType(".m3u8") || item.IsType(".strm"))))

2) Change my asp.mvc app to accept urls with .strm extension, and then redirect to propper stream url that is generated dynamicly (the power of MVC routing) Smile

Works like a charm!
No problem! but uhm, I'm not sure I understand. Your streams have .strm extension now? There's no mention of that in OP. HLS is alway m3u8 and ".strm" is not any standard format ffmpeg will recognize..
Yeah I don't blame you for not understanding. I forgot to mention something I discovered last night.

Yesturday i did manage to run my streams via favourites.xml (just to test them), and they did work as log as the url had a .strm extenstion. But they did not work via LiveTV. It seemed like pvr\livetv did not support urls with .strm extension or something.

So my urls went from this:
http://192.168.1.10/RedirectToStream?chNr=374
To This: http://192.168.1.10/play.strm?chNr=374

They both would redirect to the real stream url that is a .m3u8. But I had to "package" it into a fake .strm file so that XBMC would proccess it. At least it did so when playing the url via favourites window.


But after editing the line 92 in DVDFactoryInputStream to check for .strm extension. It also played correctly via pvr\livetv.
I needed something in the url in order to force XBMC to create the correct InputStream (DVDInputStreamFFmpeg) when proccessing the redirected url. Otherwise it would use CDVDInputStreamFile, and start mergeing the chunks of .m3u8 with the local url which is wrong in my case.

So, the .strm extension in my url is just present so that I can force xbmc to use DVDInputStreamFFmpeg when playing the redirected url (which is a m3u8).

Very nasty I know, but I was clueless on how to get it to work.
Sorry I still don't follow you, at all. Going back to my original answer I would say that the correct behavior is that at the last call to DVDFactoryInputStream::create the url should already be resolved http://**/playlist.m3u8, then DVDInputStreamFFmpeg created with this url. In DVDInputStreamFFmpeg::open "chunk_2.m3u8" will be append to the base url. Creating CDVDInputStreamFile from *.strm is correct because it is a playlist file type in xbmc.
That's the problem, when it reaches DVDFactoryInputStream::create for the second time the url is resloved to http://192.168.1.10/RedirectToStream?chNr=374.
And that is the last call to it. There should have been a last one pointing to the redirected http://**/playlist.m3u8 and create the DVDInputStreamFFmpeg, but it doesn't. It just returns a CDVDInputStreamFile.

It i supposed to reslove like this, but it does not.
pvr://channels/tv/All TV channels/92.pvr > http://192.168.1.10/RedirectToStream?chNr=374 > http://**/playlist.m3u8 > http://**/chunk_2.m3u8 > ...

So confusing Smile
and if you put http://192.168.1.10/RedirectToStream?chNr=374 inside a local .strm file it still isn't redirected?
This is about as much I know about it (because I once fixed an issue with the pvr to m3u8 resolving). Either the url isn't updated somewhere before DVDFactoryInputStream, maybe in DVDPlayer, or it's simply never opened and resolved and this kind of redirecting isn't supported.
Nope, did not work with a local .strm file either. The "hack" I wrote earlier works only with a combination of item.IsInternetStream() && item.IsType(".strm"). This is just so that I can force xbmc to create DVDInputStreamFFmpeg with the url http://192.168.1.10/play.strm?chNr=374. After that it fetches the redirected url and plays the chunks properly.

In the url above, "play.strm" is really not a file, it does not exsist. But with the help of Asp.net MVC and Routing. It's like a url "mask". it can look like whatever you want and redirect to whatever you want Smile

There is probably a much better way to solve this, but I am no C++ coder (only .net\C#).
then why not just put .m3u8 in your url? I guess it would be correct to allow if mime type for the url is set and not require m3u8 file extension, but your server would have to give proper content type then.
Does PR4729 fix it perhaps? I haven't tested if it handles redirecting
Hmmm very interesting PR you have there. this might do the trick Smile My url does in fact return propper mime type, "application/vnd.apple.mpegurl". Think I am going to test this.
I guess I need to apply the changes manualy to my code, since this change is not merged yet?

Nice find, thanks.
Ok, did a bit testing today. First, all these changes (both mine and from the PR) do not work on Gotham 13, only on the latest master.

I tested the PR, and it accually works great by cheking the content\mimetype, altho it does require an extra call to my server when it checks for mimetype the first time. Smile
Also noticed that by using DVDInputStreamFFmpeg also on other internet-streams it works much better.

Think I am stil going to try and build my own version of xbmc, so that all internet streams use DVDInputStreamFFmpeg.

Thanks again takoi
I guess it has something to do with the fact that gotham uses ffmpeg 1.2 and mainline uses ffmpeg 2.2 Wink
Pages: 1 2