You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							262 lines
						
					
					
						
							5.2 KiB
						
					
					
				
			
		
		
	
	
							262 lines
						
					
					
						
							5.2 KiB
						
					
					
				#!/bin/sh | 
						|
 | 
						|
# Depends: GNU getopt, mpv, socat, streamlink | 
						|
 | 
						|
SOCK="/tmp/umpv-fifo" | 
						|
 | 
						|
help() { | 
						|
	B=$(tput bold) | 
						|
	U=$(tput smul) | 
						|
	N=$(tput sgr0) | 
						|
 | 
						|
	cat << EOF | 
						|
${B}NAME${N} | 
						|
	play - mpv playback functions | 
						|
 | 
						|
${B}SYNOPSIS${N} | 
						|
	${B}play${N} [${U}OPTION${N}] [${U}ARGS${N}...] | 
						|
 | 
						|
${B}DESCRIPTION${N} | 
						|
	play is a script to manage different mpv viewing bahavior. | 
						|
	If no ${U}URLS${N} argument is provided, it is read from the clipboard instead. | 
						|
	The queue option starts a mpv window with a playlist, which all videos of | 
						|
	subsequent queue calls get added to. | 
						|
 | 
						|
${B}OPTIONS${N} | 
						|
	${B}-h${N}, ${B}--help${N} | 
						|
		Display usage message and exit. | 
						|
 | 
						|
	${B}-q${N}, ${B}--quality${N} ${U}QUALITY${N} | 
						|
		Set the video quality, example: ${U}720p60${N}. | 
						|
 | 
						|
	${B}-f${N}, ${B}--shuffle${N} [${U}URLS${N}...] | 
						|
		Shuffle audio playlist (disables video playback). | 
						|
 | 
						|
	${B}-u${N}, ${B}--queue${N} [${U}URLS${N}...] | 
						|
		Add multiple videos to the unique mpv's queue. | 
						|
 | 
						|
	${B}-s${N}, ${B}--stream${N} [${U}URLS${N}...] | 
						|
		Play video(s) using streamlink. | 
						|
 | 
						|
	${B}-l${N}, ${B}--low-latency${N} | 
						|
		Enable twitch low-latency mode in streamlink. | 
						|
EOF | 
						|
} | 
						|
 | 
						|
# -------------------------------------- | 
						|
 | 
						|
qualityFormat() { | 
						|
	url="$1" | 
						|
 | 
						|
	# Twitch urls dont support fancy matching | 
						|
	if echo "$url" | grep -q "twitch\.tv"; then | 
						|
		if [ -z "$quality" ]; then | 
						|
			echo "Source" | 
						|
		else | 
						|
			echo "$quality" | 
						|
		fi | 
						|
		return | 
						|
	fi | 
						|
 | 
						|
	# , separator = download several formats | 
						|
	# + separator = merge several formats into a single file | 
						|
	# / separator = or | 
						|
	if [ -z "$quality" ]; then | 
						|
		echo "bestvideo[height<=?1080]+bestaudio/best" | 
						|
	else | 
						|
		height="$(echo "$quality" | awk -F 'p' '{ print $1 }')" | 
						|
		fps="$(echo "$quality" | awk -F 'p' '{ print $2 }')" | 
						|
 | 
						|
		format="bestvideo[height<=?$height]" | 
						|
		if [ -n "$fps" ]; then | 
						|
			format="${format}[fps<=?$fps]" | 
						|
		fi | 
						|
		format="$format+bestaudio/best" | 
						|
 | 
						|
		echo "$format" | 
						|
	fi | 
						|
} | 
						|
 | 
						|
play() { | 
						|
	url="$1" | 
						|
 | 
						|
	notify-send -t 2500 "Loading video: $url" | 
						|
	setsid -f mpv --no-terminal \ | 
						|
		   --ytdl-format="$(qualityFormat "$url")" \ | 
						|
		   --ytdl-raw-options=add-metadata=,external-downloader=aria2c \ | 
						|
		   "$url" | 
						|
} | 
						|
 | 
						|
shuffle() { | 
						|
	urls="$*" | 
						|
 | 
						|
	mpv --no-video --shuffle \ | 
						|
		--ytdl-format='bestaudio[ext=m4a]' \ | 
						|
		--ytdl-raw-options=add-metadata=,external-downloader=aria2c \ | 
						|
		"$urls" | 
						|
} | 
						|
 | 
						|
queue() { | 
						|
	urls="$*" | 
						|
 | 
						|
	options="--no-terminal --force-window --input-ipc-server=$SOCK" | 
						|
 | 
						|
	# Create mpv cache directory | 
						|
	dir="$(dirname "$SOCK")" | 
						|
	[ ! -d "$dir" ] && mkdir -p "$dir" | 
						|
 | 
						|
	# Delete socket if no umpv is running | 
						|
	if ! pgrep -f "mpv $options" > /dev/null; then | 
						|
		rm -f "$SOCK" | 
						|
	fi | 
						|
 | 
						|
	if [ -S "$SOCK" ]; then | 
						|
		notify-send -t 2500 "Added video to queue.." | 
						|
		# Add video to named pipe | 
						|
		echo "$urls" | awk -v RS=' ' '{ print "raw loadfile "$1" append" }' \ | 
						|
			| socat UNIX-CONNECT:"$SOCK" - | 
						|
	else | 
						|
		# Play video | 
						|
		notify-send -t 2500 "Loading video: $urls" | 
						|
		# shellcheck disable=2086 | 
						|
		setsid -f mpv $options \ | 
						|
			   --ytdl-format="$(qualityFormat $urls)" \ | 
						|
			   --ytdl-raw-options=add-metadata=,external-downloader=aria2c \ | 
						|
			   $urls | 
						|
	fi | 
						|
} | 
						|
 | 
						|
stream() { | 
						|
	channel="$1" | 
						|
	quality="$2" | 
						|
	lowLatency="$3" | 
						|
 | 
						|
	if [ -z "$quality" ]; then | 
						|
		if ! streamlink --quiet --config /dev/null "$channel"; then | 
						|
			return 1 | 
						|
		fi | 
						|
 | 
						|
		printf "Select stream quality: " | 
						|
		read -r quality | 
						|
	fi | 
						|
 | 
						|
	if [ -z "$lowLatency" ]; then | 
						|
		arguments="\ | 
						|
			--player-args '--force-window'" | 
						|
	else | 
						|
		arguments="\ | 
						|
			--twitch-low-latency \ | 
						|
			--player-args '--force-window --cache=yes --demuxer-max-bytes=750k'" | 
						|
	fi | 
						|
 | 
						|
	echo "Starting stream $channel @ $quality" | 
						|
	command="setsid -f streamlink \ | 
						|
		--twitch-disable-hosting \ | 
						|
		--twitch-disable-reruns \ | 
						|
		--player mpv \ | 
						|
		--stream-sorting-excludes '<480p,>=1080p' \ | 
						|
		$arguments \ | 
						|
		$channel $quality > /dev/null 2>&1" | 
						|
	eval "$command" | 
						|
} | 
						|
 | 
						|
# Option parsing | 
						|
# -------------------------------------- | 
						|
 | 
						|
script="$(basename "$0")" | 
						|
parsed="$(getopt --options "hslquf" \ | 
						|
				 --longoptions "help,stream,quality,queue,shuffle" \ | 
						|
				 -n "$script" -- "$@" 2>&1)" | 
						|
result="$?" | 
						|
 | 
						|
# Exit if invalid option is provided | 
						|
if [ "$result" -ne 0 ]; then | 
						|
	echo "$parsed" | head -n 1 >&2 | 
						|
	echo "Try './$script --help' for more information." >&2 | 
						|
	exit 1 | 
						|
fi | 
						|
 | 
						|
eval set -- "$parsed" | 
						|
 | 
						|
streamOption=0 | 
						|
qualityOption=0 | 
						|
lowLatencyOption=0 | 
						|
queueOption=0 | 
						|
shuffleOption=0 | 
						|
while true; do | 
						|
	case "$1" in | 
						|
		-h | --help) | 
						|
			help | 
						|
			exit | 
						|
			;; | 
						|
		-s | --stream) | 
						|
			streamOption=1 | 
						|
			shift | 
						|
			;; | 
						|
		-l | --low-latency) | 
						|
			lowLatencyOption=1 | 
						|
			shift | 
						|
			;; | 
						|
		-q | --quality) | 
						|
			qualityOption=1 | 
						|
			shift | 
						|
			;; | 
						|
		-u | --queue) | 
						|
			queueOption=1 | 
						|
			shift | 
						|
			;; | 
						|
		-f | --shuffle) | 
						|
			shuffleOption=1 | 
						|
			shift | 
						|
			;; | 
						|
		--) | 
						|
			shift | 
						|
			break | 
						|
			;; | 
						|
		*) | 
						|
			break | 
						|
			;; | 
						|
	esac | 
						|
done | 
						|
 | 
						|
# Target parsing | 
						|
# -------------------------------------- | 
						|
 | 
						|
# Incompatible flags | 
						|
result=$((streamOption + queueOption + shuffleOption)) | 
						|
if [ $result -gt 1 ]; then | 
						|
	echo "Incompatible flags." >&2 | 
						|
	echo "Try './$script --help' for more information." >&2 | 
						|
	exit 1; | 
						|
fi | 
						|
 | 
						|
# Get quality | 
						|
if [ $qualityOption -eq 1 ]; then | 
						|
	quality="$1" | 
						|
	shift | 
						|
fi | 
						|
 | 
						|
# Set url to clipboard if none provided | 
						|
clip="$(xclip -selection clipboard -out)" | 
						|
if [ "$#" -eq 0 ]; then | 
						|
	eval set -- "$clip" | 
						|
fi | 
						|
 | 
						|
[ $lowLatencyOption -eq 1 ] && lowLatency="1" | 
						|
 | 
						|
# Execute | 
						|
# -------------------------------------- | 
						|
 | 
						|
if [ $streamOption -eq 1 ]; then | 
						|
	for url in "$@"; do | 
						|
		stream "$url" "$quality" "$lowLatency" | 
						|
	done | 
						|
elif [ $shuffleOption -eq 1 ]; then | 
						|
	shuffle "$*" | 
						|
elif [ $queueOption -eq 1 ]; then | 
						|
	queue "$*" | 
						|
else | 
						|
	for url in "$@"; do | 
						|
		play "$url" | 
						|
	done | 
						|
fi
 | 
						|
 |