2018-08-17, 19:18
Sometimes I find myself with my laptop on a wifi that's not fast enough to stream my collection of glorious FullHD video, which Kodi accesses on NFS over VPN. This happened often enough so that I did a workaround:
Basically I added a script as an external player. This script does something like this:
And now I can play all my media even over slow connections. However, this approach has a few downsides. The first one is that it doesn't use the native player, so kodi cannot determine how much of the video is actually watched. The other issue is that I don't know how to do something similar on android (this is actually the sole reason I want to do this to be honest).
So I'm thinking there may be a more generic way to fix this by creating a native add-on that does this. Basically I want to add a context item on videos that, when used, connects to another machine, starts the transcoding, and starts playing the resulting stream using the internal player. Sounds simple enough I think.
Now, I've only pondered and investigated this for a few hours, but if anyone has any input on the following questions I would be grateful:
xml:
<playercorefactory>
<players>
<player name="Transcode" type="ExternalPlayer" audio="false" video="true">
<filename>/home/user/mpv.sh</filename>
<args>"{1}"</args>
<hidexbmc>false</hidexbmc>
<playcountminimumtime>600</playcountminimumtime>
</player>
</players>
</playercorefactory>
Basically I added a script as an external player. This script does something like this:
bash:
ssh <server> ffprobe "$1" 2> /tmp/mpv.txt
VENC='-c:v libx264 -preset medium -crf 20'
VIDEO=$(egrep '^[ \t]*Stream.*Video' /tmp/mpv.txt | head -1 | sed "s,^[ \\t]*Stream #0:\\([0-9]*\\).*,-map 0:\\1 $VENC,")
AUDIO=$(egrep '^[ \t]*Stream.*Audio' /tmp/mpv.txt | head -1 | sed 's,^[ \t]*Stream #0:\([0-9]*\).*,-map 0:\1 -c:a aac -b 192,')
SUBS=$(egrep '^[ \t]*Stream.*Subtitle' /tmp/mpv.txt | sed 's,^[ \t]*Stream #0:\([0-9]*\).*,-map 0:\1 -c copy,')
ssh <server> ffmpeg -i "$1" -vf scale=1280:-2 $VIDEO $AUDIO $SUBS -f matroska - | mpv -
And now I can play all my media even over slow connections. However, this approach has a few downsides. The first one is that it doesn't use the native player, so kodi cannot determine how much of the video is actually watched. The other issue is that I don't know how to do something similar on android (this is actually the sole reason I want to do this to be honest).
So I'm thinking there may be a more generic way to fix this by creating a native add-on that does this. Basically I want to add a context item on videos that, when used, connects to another machine, starts the transcoding, and starts playing the resulting stream using the internal player. Sounds simple enough I think.
Now, I've only pondered and investigated this for a few hours, but if anyone has any input on the following questions I would be grateful:
- How do I make a context item visible only for video items? The wikis list of boolean conditions doesn't seem to have any "IsVideo" or similar.
- How do I determine the full path to the video file from a context plugin? I'm able to get the path via the VideoInfoTag, but I can't get the filename (getFile() returns nothing).
- Kodi has support for SFTP, which mean there is some SSH implementation present, but I can't find that there is any way to access it from an add-on. Is there a way, or do I have to make a paramiko module or something?
- Is there a way to make the internal player play video from something that is not a regular file? For example, it would be nice to stream via a file-like python object, but otherwise I guess a FIFO or something could work. Any ideas?
- Is this a reasonable approach, or should I spend my time elsewhere?