Solved How does Kodi player request a video via http?
#1
Currently I'm working on my own implementation of a torrent-streaming plugin. Basically, its an analog of Pulsar but written in pure Python (except for python-libtorrent module, which is binary) and with some additional features, like seeding after playback and a web-UI for managing torrents.
Architecture-wise the plugin consists of a server and a client parts. The client is responsible for passing .torrent files and magnet links to the server and starting playback (via setResolvedUrl) once a video file is buffered enough for continuous playback. The server part is a simple torrent-client (based on libtorrent) and a web-server for serving media-files to Kodi.
One thing I'm struggling with is playback seek/jump support. The idea is that when a user wants to seek a video, the server receives an appropriate 'Content-Range' header from Kodi and prioritizes download of the parts that has been requested for playback. But it's not that simple because Kodi does not always issue a http request when a user performs a seek (especially for mkv files).

Basically, what I need to know is how to correctly serve a video file to Kodi via http protocol: what requests it normally issues and what replies it expects. And how to make it always issue a 'Content-Range' range request when a user wants to jump/skip a part of the video being played.

What I found out experimentally that starting a playback a remote file via http Kodi issues 3 requests: HEAD, GET from start ('Content-Range': '0-') and GET near the end of the file. And the piece requested at the end of a video file differs depending on the type of a video file. For mp4 and mkv Kodi requests the last 64KB and the last ~200KB for avi. I tried to provide the necessary http headers but obviously I'm missing something because, as I said, a http request with a 'Content-Range' header is not always issued after a video seek command - Kodi simply tries to grab the necessary pieces from the server without any http requests.

Just to be clear: the server part is based on Bottle web-framework and WSGIref server from Python standard library.
Reply
#2
It probably using the file cache, so as long as the needed data is in the cache, not http request is sent. You can try to turn off caching and do large skips to see if that makes a difference.
Reply
#3
(2015-08-18, 20:30)wsnipex Wrote: It probably using the file cache, so as long as the needed data is in the cache, not http request is sent. You can try to turn off caching and do large skips to see if that makes a difference.

No, I'm absolutely sure that video is not read from cache because the built-in web-server that serves video controls and and writes to Kodi log which chunks it serves.

PS. What I've found out that Kodi player behavior depends on the type of content it plays. mp4 videos are the easiest - for them jumps work like charm. mkv and avi are the hard case - I cannot figure out how to serve them correctly - the same algorithm as for mp4 does not work for them.

PPS. It looks like when I want to jump/seek ahead in a mkv video Kodi tries to pull the video quickly from the server instead of issuing a new 'Content-Range' request.
Reply
#4
I seem to have made some progress. Turned out I was wrong about the 3rd GET request from the end of the file that is being played. It is not issued when playback starts but when a user gives a jump/seek command. Kodi player checks the end of the file and if this check is successful, it issues another GET http request from the requested position, and a server must satisfy this request via Partial-content reply. If this "end" request is uncessesful for some reason, Kodi tries to download the file byte by byte as fast as possible to reach the requested position.

So I was looking for the solution in the wrong place - as soon as I got the this "end" GET request working the problem was solved.
Reply
#5
Roman - I noticed that XFILE::CFileCache::Seek is called for some mp4 stream on the start of the playback (I think it originates from CCurlFile::FillBuffer). How have you handled the "end" get request? Are you returning real data or have you found some HTTP response that makes the player think the check is successful?

I'm asking because I try to allow playback from streaming sites that forbid multiple requests (return HTTP error 503). As the playback starts both the regular and the "end" GET requests are sent, since the second request gets HTTP error, the playback stops immediately.
Reply
#6
(2015-08-21, 13:04)roee88 Wrote: Roman - I noticed that XFILE::CFileCache::Seek is called for some mp4 stream on the start of the playback (I think it originates from CCurlFile::FillBuffer). How have you handled the "end" get request? Are you returning real data or have you found some HTTP response that makes the player think the check is successful?

I'm asking because I try to allow playback from streaming sites that forbid multiple requests (return HTTP error 503). As the playback starts both the regular and the "end" GET requests are sent, since the second request gets HTTP error, the playback stops immediately.

Yes, for end-check my server (Bottle+WSGIref) returns real data - my plugin downloads some pieces at the start and at the end of a video before starting playback. I guess my situation is simpler than yours since I control both ends of the connection.
Reply
#7
I am interested in this.

How did you solve it?
Reply

Logout Mark Read Team Forum Stats Members Help
How does Kodi player request a video via http?0