allejok96 / send-to-kodi Goto Github PK
View Code? Open in Web Editor NEWPlay online videos on Kodi, or stream local media
Play online videos on Kodi, or stream local media
Hello,
First I'd like to say it's very nice and powerfull script, yet simple and short.
Have you considered sending separate video and audio stream? Is it even possible with json-rpc kodi API?
Currently if I use the script it sends only 320p combined stream which is really poor. However with default action youtube-dl selects 720p but then these are separate video&audio streams.
Current youtube-dl usage by script:
youtube-dl -gf best 'https://www.facebook.com/watch/live/?v=190790559367200&ref=watch_permalink'
https://scontent.fwaw5-1.fna.fbcdn.net/v/t66.36281-6/10000000_907241116478824_1982327047256291720_n.mp4?_nc_cat=111&ccb=2&_nc_sid=985c63&efg=eyJ2ZW5jb2RlX3RhZyI6Im9lcF9zZCJ9&_nc_ohc=PTfIAsDM1AQAX-ltN9e&_nc_ht=scontent.fwaw5-1.fna&oh=50047fc087406a04a5171c254a61acb7&oe=5FF26A0A
Best quality 720p but 2 separate streams
youtube-dl -g 'https://www.facebook.com/watch/live/?v=190790559367200&ref=watch_permalink'
https://video.fwaw5-1.fna.fbcdn.net/v/t58.24163-29/10000000_374104710550142_4622832835349334323_n.mp4?_nc_cat=108&ccb=2&_nc_sid=5aebc0&efg=eyJ2ZW5jb2RlX3RhZyI6ImRhc2hfbGl2ZV9oZDFfdW1hX2ZyYWdfMl92aWRlbyJ9&_nc_ohc=WP8B6o5LAe8AX_82cWM&_nc_ht=video.fwaw5-1.fna&oh=b2fdcfe3830940c0095d39992e5ddd4e&oe=5FCF5E6E
https://video.fwaw5-1.fna.fbcdn.net/v/t58.24163-29/10000000_803469820218481_3195184083453920485_n.mp4?_nc_cat=104&ccb=2&_nc_sid=5aebc0&efg=eyJ2ZW5jb2RlX3RhZyI6ImRhc2hfbGl2ZV9tZF91bWFfZnJhZ18yX2F1ZGlvIn0=&_nc_ohc=fISeck7tShoAX_xZei2&_nc_ht=video.fwaw5-1.fna&oh=af7fe1ac18f037f50eb531792ca1022b&oe=5FCFB9CF
Without needing to enable the Kodi http server, you can use:
adb shell am start -a android.intent.action.VIEW -d "$URL" org.xbmc.kodi/.Splash
I'll leave a little script I've made.
#!/bin/bash
function is_tv_connected() { #adb doesn't give good exit codes :(
TV_IP="$(avahi-browse -r -kt _googlecast._tcp |sed -nE 's/.*\[([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\].*/\1/p' | head -n1)"
#TV_IP=$(resolvectl query Android.local -4 --legend=false | sed -n 's/.* \([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\).*/\1/p' | head -n1)
echo "[INFO] Chromecast ip address: $TV_IP"
adb connect "$TV_IP" 1>/dev/null
if adb get-state | grep "device" 1>/dev/null ; then
echo '[INFO] Device is connected'
return 0
else
echo '[ERROR] no device connected! or unauthorized (check TV)'
return 1
fi
}
function kill_app(){ #[PKGNAME]
GETPKGNAME=$(adb shell pm list packages | grep -i "$1" | awk -F':' '{print $2}' | tr -d '[:space:]')
adb shell am force-stop "${GETPKGNAME}"
}
function androidrun() { #PKGNAME #URL
#Get app pkgname
GETPKGNAME=$(adb shell pm list packages | grep -i "$1" | awk -F':' '{print $2}' | tr -d '[:space:]')
PKGNAME="${GETPKGNAME:-com.google.android.youtube.tv}"
echo "[INFO] Playing video on $PKGNAME"
adb shell am force-stop "${PKGNAME}"
#adb shell am start -a android.intent.action.VIEW --activity-clear-task -d "$2" "${PKGNAME}"
if [[ "${PKGNAME}" == org.xbmc.kodi ]]; then
adb shell am start -a android.intent.action.VIEW -d "$2" "${PKGNAME}"/.Splash
else
adb shell am start -a android.intent.action.VIEW -d "$2" "${PKGNAME}"
fi
}
function webserver(){ #[Filepath to serve on /video.mkv]
python - "$1" <<END
import os, re, sys
from flask import Flask, Response, request
app = Flask(__name__)
@app.route('/video.mkv')
def get_video():
filename = sys.argv[1] if len(sys.argv) > 1 else 'video.mkv'
filesize = os.path.getsize(filename)
range_header = request.headers.get('Range', None)
if range_header:
byte1, byte2 = 0, None
match = re.search(r'(\d+)-(\d*)', range_header)
groups = match.groups()
if groups[0]:
byte1 = int(groups[0])
if groups[1]:
byte2 = int(groups[1])
if byte2 is not None:
if byte2 > filesize - 1:
byte2 = filesize - 1
length = byte2 - byte1 if byte2 is not None else filesize - byte1
with open(filename, 'rb') as f:
f.seek(byte1)
data = f.read(length)
resp = Response(
data, status=206, mimetype='video/x-matroska',
content_type='video/x-matroska', direct_passthrough=True
)
resp.headers.add('Content-Range',
'bytes {0}-{1}/{2}'
.format(byte1, byte1 + length - 1, filesize))
resp.headers.add('Accept-Ranges', 'bytes')
return resp
return Response(
open(filename, 'rb').read(), status=200, mimetype='video/x-matroska'
)
if __name__ == '__main__':
app.run(host='0.0.0.0',port=5000,debug=False)
END
}
### Main
#Check dependencies
command -v ffmpeg >/dev/null 2>&1 || { echo >&2 "I require ffmpeg but it's not installed. Aborting."; exit 1; }
command -v adb >/dev/null 2>&1 || { echo >&2 "I require adb but it's not installed. Aborting."; exit 1; }
command -v ip >/dev/null 2>&1 || { echo >&2 "I require ip but it's not installed. Aborting."; exit 1; }
command -v yt-dlp >/dev/null 2>&1 || { echo >&2 "I require yt-dlp but it's not installed. Aborting."; exit 1; }
#Help and usage
if [[ "$*" =~ "--help" ]] || [[ "$*" =~ "-h" ]] || [[ $# -eq 0 ]]; then
#printf "Usage:\n\t[URL]\n\tkill [APP NAME]\n"
printf """Usage:
[FILE OR URL] : Plays the local file or URL on the Chromecast.
kill [appname] : kills the appname. fuzzy search of the nane.
"""
exit 0
elif [[ "$1" =~ "kill" ]]; then
kill_app "$2"
exit 0
fi
if echo "$1" | grep -P "^(https?):\/\/[^\s/$.?#].[^\s]*$" > /dev/null; then #Check valid URL
if is_tv_connected; then
adb shell input keyevent KEYCODE_WAKEUP #Wake up TV
if [[ "$1" =~ (youtube.com|youtu.be) ]]; then
androidrun smarttubetv "$1" #Play youtube video
exit
elif [[ "${1}" =~ (twitch.tv|m3u8) ]]; then
URL=$(yt-dlp --get-url "$1")
androidrun mxtech "$URL"
exit
else
URL=$(yt-dlp --get-url "$1")
androidrun mxtech "$URL"
exit
fi
fi
else
if [ -f "$1" ]; then #check if argv is a valid path to a file
if is_tv_connected; then
adb shell input keyevent KEYCODE_WAKEUP #Wake up TV
video_file="$1"
# Use ffprobe to get the video resolution
resolution=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 "$video_file")
# Extract width and height from the resolution output
width=$(echo "$resolution" | cut -d 'x' -f1)
height=$(echo "$resolution" | cut -d 'x' -f2)
# Check if the video resolution is larger than 1920x1080
if [ "$width" -gt 1920 ] && [ "$height" -gt 1080 ]; then
echo "[INFO] The video is larger than 1920x1080. Transcoding"
TEMP_VIDEO=$(mktemp --suffix=.mkv)
## Burn subtitles: -vf "scale=1920:-2,subtitles=${video_file}:stream_index=0:force_style='FontName=Droid Sans,Fontsize=12'"
ffmpeg -nostdin -hide_banner -loglevel quiet -y \
-hwaccel cuda \
-i "${video_file}" -c:v hevc_nvenc -b:v 5M -c:a libopus -b:a 128k -ac 2 -pix_fmt yuv420p \
-vf "scale=1920:-2" \
-f matroska -movflags faststart -strict -2 \
"${TEMP_VIDEO}" &
sleep 1
webserver "${TEMP_VIDEO}" &
IP=$(ip -4 addr show | grep -oP "(?<=inet ).*(?=/)" | tail -n1)
androidrun kodi "http://$IP:5000/video.mkv"
else
echo "[INFO] The video is not larger than 1920x1080."
webserver "${video_file}" &
IP=$(ip -4 addr show | grep -oP "(?<=inet ).*(?=/)" | tail -n1)
androidrun kodi "http://$IP:5000/video.mkv"
fi
fi
else
echo "[ERROR] The path $1 is either not a file or doesn't exist."
fi
fi
function exit_handler(){
jobs -p | xargs -r kill
if [ -n "$TEMP_VIDEO" ]; then
rm -f "$TEMP_VIDEO"
fi
kill_app kodi
kill 0
echo "Finished cleaning up."
}
trap "exit" INT TERM
trap exit_handler EXIT
#Wait until control+C
echo "Control+C to quit"
read -r _
exit_handler
exit
I love the idea of this script! However, when I run it I see Kodi respond with a notification saying "unknown".
In terminal I get this response: {"id":1,"jsonrpc":"2.0","result":"OK"}
Used a normal youtube link, running mac Catalina.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.