#!/bin/sh # invidious # Written in 2019 by Leslie # Modified in 2019-2020 by Lucas # CC0 1.0 Universal/Public domain - No rights reserved # # To the extent possible under law, the author(s) have dedicated all # copyright and related and neighboring rights to this software to the # public domain worldwide. This software is distributed without any # warranty. You should have received a copy of the CC0 Public Domain # Dedication along with this software. If not, see # . usage() { printf "Usage: [-T] %s url\n" "${0##*/}" >&2 exit 1 } err() { printf "%s: %s\n" "${0##*/}" "$*" >&2 exit 1 } fetch_file() { # Assumes utility supports `-o output_file` case $(uname) in OpenBSD) $torsocks ftp -MV "$@" ;; *) $torsocks curl -fLSs "$@" ;; esac } api() { printf "https://%s%s\n" "$INVIDIOUS" "$*" } known_site() { printf "%s\n" "$1" | grep -Eq \ -e "^https?://(www\.)?youtube\.com/" \ -e "^https?://youtu\.be/" \ -e "^https?://(www\.)?invidio\.us/" \ -e "^https?://invidious\.snopyta\.org/" \ -e "^https?://yewtu\.be/" } get_id_path() { printf "%s\n" "${1##*/}" } get_id_query() { oldIFS=$IFS IFS="&" set -- ${1##*"?"} IFS=$oldIFS id= for param; do case $param in v=*) id=${param#v=} break ;; esac done printf "%s\n" "$id" } get_id() { case $1 in *"?v="*) get_id_query "$1" ;; *) get_id_path "$1" ;; esac } : ${INVIDIOUS:=invidious.snopyta.org} torsocks=torsocks while getopts T flag; do case $flag in T) torsocks= ;; *) usage ;; esac done shift $((OPTIND - 1)) [ $# -eq 1 ] || usage url=$1 known_site "$url" || err "unknown site $url" id=$(get_id "$url") [ ${#id} -eq 11 ] || err "invalid video ID $id" # XXX choose in some clever way itag=$(fetch_file -o - "$(api "/api/v1/videos/$id")" | jq -r ".formatStreams[].itag" | head -n 1) api "/latest_version?id=$id&itag=$itag"