Add multimedia player controllers
This commit is contained in:
		
							parent
							
								
									d08a4e2bcf
								
							
						
					
					
						commit
						5c542922e1
					
				|  | @ -0,0 +1,234 @@ | ||||||
|  | #!/bin/sh | ||||||
|  | # | ||||||
|  | # Purpose {{{ | ||||||
|  | # This script will try to control Kodi with kodi-send command | ||||||
|  | #   1. Start Kodi if not already running. | ||||||
|  | #   2. Send user command to Kodi running instance. | ||||||
|  | # | ||||||
|  | # 2022-05-22 | ||||||
|  | # }}} | ||||||
|  | # Vars {{{ | ||||||
|  | PROGNAME=$(basename "${0}"); readonly PROGNAME | ||||||
|  | PROGDIR=$(readlink -m $(dirname "${0}")); readonly PROGDIR | ||||||
|  | ARGS="${*}"; readonly ARGS | ||||||
|  | readonly NBARGS="${#}" | ||||||
|  | [ -z "${DEBUG}" ] && DEBUG=1 | ||||||
|  | ## Export DEBUG for sub-script | ||||||
|  | export DEBUG | ||||||
|  | 
 | ||||||
|  | ## Default values for some vars | ||||||
|  | readonly USER_MULTIMEDIA_COMMAND_DEFAULT="toggle" | ||||||
|  | readonly KODI_PROC_REGEXP="kodi.bin" | ||||||
|  | 
 | ||||||
|  | ## Colors | ||||||
|  | readonly PURPLE='\033[1;35m' | ||||||
|  | readonly RED='\033[0;31m' | ||||||
|  | readonly RESET='\033[0m' | ||||||
|  | readonly COLOR_DEBUG="${PURPLE}" | ||||||
|  | # }}} | ||||||
|  | usage() {                                                       # {{{ | ||||||
|  | 
 | ||||||
|  | 	cat <<- HELP | ||||||
|  | usage: $PROGNAME [-c|-d|-h] | ||||||
|  | 
 | ||||||
|  | Manage Kodi player with some commands. | ||||||
|  | 
 | ||||||
|  | EXAMPLES : | ||||||
|  |     - Starts playing current playlist | ||||||
|  |         ${PROGNAME} --command start | ||||||
|  | 
 | ||||||
|  |     - Start Kodi if not already running | ||||||
|  |         ${PROGNAME} | ||||||
|  | 
 | ||||||
|  |       - Send default action (${USER_MULTIMEDIA_COMMAND_DEFAULT}) to Kodi instance | ||||||
|  |         ${PROGNAME} | ||||||
|  | 
 | ||||||
|  | OPTIONS : | ||||||
|  |     -c,--command | ||||||
|  |         Send a command to running Kodi. Available commands : | ||||||
|  |           * toggle, play, pause | ||||||
|  |           * next | ||||||
|  |           * previous | ||||||
|  |           * random, party, partymode | ||||||
|  | 
 | ||||||
|  |     -d,--debug | ||||||
|  |         Enable debug messages. | ||||||
|  | 
 | ||||||
|  |     -h,--help | ||||||
|  |         Print this help message. | ||||||
|  | HELP | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | debug_message() {                                               # {{{ | ||||||
|  | 
 | ||||||
|  | 	local_debug_message="${1}" | ||||||
|  | 
 | ||||||
|  | 	## Print message if DEBUG is enable (=0) | ||||||
|  | 	[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6b\e[m\n' "DEBUG − ${PROGNAME} : ${local_debug_message}" | ||||||
|  | 
 | ||||||
|  | 	unset local_debug_message | ||||||
|  | 
 | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | error_message() {                                               # {{{ | ||||||
|  | 
 | ||||||
|  | 	local_error_message="${1}" | ||||||
|  | 	local_error_code="${2}" | ||||||
|  | 
 | ||||||
|  | 	## Print message | ||||||
|  | 	printf '%b\n' "ERROR − ${PROGNAME} : ${RED}${local_error_message}${RESET}" | ||||||
|  | 
 | ||||||
|  | 	exit "${local_error_code:=66}" | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | define_vars() {                                                 # {{{ | ||||||
|  | 
 | ||||||
|  | 	## If USER_MULTIMEDIA_COMMAND wasn't defined (argument) {{{ | ||||||
|  | 	if [ -z "${USER_MULTIMEDIA_COMMAND}" ]; then | ||||||
|  | 		## Use default value | ||||||
|  | 		readonly USER_MULTIMEDIA_COMMAND="${USER_MULTIMEDIA_COMMAND_DEFAULT}" | ||||||
|  | 	fi | ||||||
|  | 	## }}} | ||||||
|  | 	## Translate user command to Kodi action {{{ | ||||||
|  | 	case "${USER_MULTIMEDIA_COMMAND}" in | ||||||
|  | 		toggle|play|pause )                   ## Toggle current play | ||||||
|  | 			KODI_ACTION="PlayerControl(play)" | ||||||
|  | 			;; | ||||||
|  | 		next )                                ## Next element in the playlist | ||||||
|  | 			KODI_ACTION="PlayerControl(next)" | ||||||
|  | 			;; | ||||||
|  | 		previous )                            ## Next element in the playlist | ||||||
|  | 			KODI_ACTION="PlayerControl(previous)" | ||||||
|  | 			;; | ||||||
|  | 		random|party|partymode )              ## Start random music | ||||||
|  | 			KODI_ACTION="PlayerControl(partymode)" | ||||||
|  | 			;; | ||||||
|  | 		* )                                   ## unknow option | ||||||
|  | 			printf '%b\n' "${RED}Invalid Kodi command: ${USER_MULTIMEDIA_COMMAND}${RESET}" | ||||||
|  | 			printf '%b\n' "---" | ||||||
|  | 			usage | ||||||
|  | 			exit 1 | ||||||
|  | 			;; | ||||||
|  | 	esac | ||||||
|  | 	## }}} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | is_proc_absent() {                                             # {{{ | ||||||
|  | 
 | ||||||
|  | 	local_proc_pattern="${1}" | ||||||
|  | 
 | ||||||
|  | 	## Proc is absent by default | ||||||
|  | 	return_proc_absent="0" | ||||||
|  | 
 | ||||||
|  | 	local_count_proc_pattern="$(pgrep -f -- "${local_proc_pattern}" | wc -l)" | ||||||
|  | 
 | ||||||
|  | 	case "${local_count_proc_pattern}" in | ||||||
|  | 		0 ) ## No procs related to this pattern are running | ||||||
|  | 			return_proc_absent="0" | ||||||
|  | 			;; | ||||||
|  | 		* ) ## At least one proc seems running | ||||||
|  | 			return_proc_absent="1" | ||||||
|  | 			;; | ||||||
|  | esac | ||||||
|  | 
 | ||||||
|  | 	## Simple debug message to valid current variables | ||||||
|  | 	debug_message "is_proc_absent − \ | ||||||
|  | procs running (with the pattern: ${RED}${local_proc_pattern}${COLOR_DEBUG}) on the current host: ${RED}${local_count_proc_pattern}${COLOR_DEBUG}." | ||||||
|  | 
 | ||||||
|  | 	return "${return_proc_absent}" | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | 
 | ||||||
|  | main() {                                                        # {{{ | ||||||
|  | 
 | ||||||
|  | 	## Define all vars | ||||||
|  | 	define_vars | ||||||
|  | 
 | ||||||
|  | 	## If kodi is not running {{{ | ||||||
|  | 	### AND Start it | ||||||
|  | 	### AND exit 0 | ||||||
|  | 	is_proc_absent "${KODI_PROC_REGEXP}" \ | ||||||
|  | 		&& debug_message "Start a new Kodi instance." \ | ||||||
|  | 		&& kodi \ | ||||||
|  | 		&& exit 0 | ||||||
|  | 	## }}} | ||||||
|  | 
 | ||||||
|  | 	## Send Kodi action to running instance {{{ | ||||||
|  | 	### And exit | ||||||
|  | 	debug_message "Send ${RED}${USER_MULTIMEDIA_COMMAND}${COLOR_DEBUG} (${RED}${KODI_ACTION}${COLOR_DEBUG}) action to running Kodi instance." \ | ||||||
|  | 		&& kodi-send --action="${KODI_ACTION}" > /dev/null \ | ||||||
|  | 		&& exit 0 | ||||||
|  | 	## }}} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | 
 | ||||||
|  | # Manage arguments                                                # {{{ | ||||||
|  | # This code can't be in a function due to argument management | ||||||
|  | 
 | ||||||
|  | if [ ! "${NBARGS}" -eq "0" ]; then | ||||||
|  | 
 | ||||||
|  | 	manage_arg="0" | ||||||
|  | 
 | ||||||
|  | 	## If the first argument is not an option | ||||||
|  | 	if ! printf -- '%s' "${1}" | grep -q -E -- "^-+"; | ||||||
|  | 	then | ||||||
|  | 		## Print help message and exit | ||||||
|  | 		printf '%b\n' "${RED}Invalid option: ${1}${RESET}" | ||||||
|  | 		printf '%b\n' "---" | ||||||
|  | 		usage | ||||||
|  | 
 | ||||||
|  | 		exit 1 | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	# Parse all options (start with a "-") one by one | ||||||
|  | 	while printf -- '%s' "${1}" | grep -q -E -- "^-+"; do | ||||||
|  | 
 | ||||||
|  | 	case "${1}" in | ||||||
|  | 		-c|--command )                        ## User command | ||||||
|  | 			### Move to the next argument | ||||||
|  | 			shift | ||||||
|  | 			### Define var | ||||||
|  | 			USER_MULTIMEDIA_COMMAND="${1}" | ||||||
|  | 			;; | ||||||
|  | 		-d|--debug )                          ## debug | ||||||
|  | 			DEBUG=0 | ||||||
|  | 			;; | ||||||
|  | 		-h|--help )                           ## help | ||||||
|  | 			usage | ||||||
|  | 			## Exit after help informations | ||||||
|  | 			exit 0 | ||||||
|  | 			;; | ||||||
|  | 		* )                                   ## unknow option | ||||||
|  | 			printf '%b\n' "${RED}Invalid option: ${1}${RESET}" | ||||||
|  | 			printf '%b\n' "---" | ||||||
|  | 			usage | ||||||
|  | 			exit 1 | ||||||
|  | 			;; | ||||||
|  | 	esac | ||||||
|  | 
 | ||||||
|  | 	debug_message "Arguments management − \ | ||||||
|  | ${RED}${1}${COLOR_DEBUG} option|command managed." | ||||||
|  | 
 | ||||||
|  | 	## Move to the next argument | ||||||
|  | 	shift | ||||||
|  | 	manage_arg=$((manage_arg+1)) | ||||||
|  | 
 | ||||||
|  | 	done | ||||||
|  | 
 | ||||||
|  | 	debug_message "Arguments management − \ | ||||||
|  | ${RED}${manage_arg}${COLOR_DEBUG} argument(s) successfully managed." | ||||||
|  | else | ||||||
|  | 	debug_message "Arguments management − \ | ||||||
|  | No arguments/options to manage." | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | # }}} | ||||||
|  | 
 | ||||||
|  | main | ||||||
|  | 
 | ||||||
|  | exit 255 | ||||||
|  | @ -0,0 +1,262 @@ | ||||||
|  | #!/bin/sh | ||||||
|  | # | ||||||
|  | # Purpose {{{ | ||||||
|  | # This script will try to control MPD with mpc client command | ||||||
|  | #   1. Start MPD if not already running and disable random mode. | ||||||
|  | #   2. Send user command to MPD running instance. | ||||||
|  | # | ||||||
|  | # 2022-05-22 | ||||||
|  | # }}} | ||||||
|  | # Vars {{{ | ||||||
|  | PROGNAME=$(basename "${0}") | ||||||
|  | readonly PROGNAME | ||||||
|  | PROGDIR=$(readlink -m $(dirname "${0}")) | ||||||
|  | readonly PROGDIR | ||||||
|  | ARGS="${*}" | ||||||
|  | readonly ARGS | ||||||
|  | readonly NBARGS="${#}" | ||||||
|  | [ -z "${DEBUG}" ] && DEBUG=1 | ||||||
|  | ## Export DEBUG for sub-script | ||||||
|  | export DEBUG | ||||||
|  | 
 | ||||||
|  | ## Default values for some vars | ||||||
|  | readonly MPD_PROC_REGEXP="mpd.*systemd" | ||||||
|  | readonly USER_MULTIMEDIA_COMMAND_DEFAULT="toggle" | ||||||
|  | 
 | ||||||
|  | ## Colors | ||||||
|  | readonly PURPLE='\033[1;35m' | ||||||
|  | readonly RED='\033[0;31m' | ||||||
|  | readonly RESET='\033[0m' | ||||||
|  | readonly COLOR_DEBUG="${PURPLE}" | ||||||
|  | # }}} | ||||||
|  | usage() {                                                       # {{{ | ||||||
|  | 
 | ||||||
|  | 	cat <<- HELP | ||||||
|  | usage: $PROGNAME [-c|-d|-h] | ||||||
|  | 
 | ||||||
|  | Manage MPD with commands. | ||||||
|  | 
 | ||||||
|  | EXAMPLES : | ||||||
|  |     - Starts playing next song on the queue | ||||||
|  |         ${PROGNAME} --command next | ||||||
|  | 
 | ||||||
|  |     - Send default command (${USER_MULTIMEDIA_COMMAND_DEFAULT}) to MPD | ||||||
|  |         ${PROGNAME} | ||||||
|  | 
 | ||||||
|  |     - Start MPD if not already running and starts playing | ||||||
|  |         ${PROGNAME} | ||||||
|  | 
 | ||||||
|  | OPTIONS : | ||||||
|  |     -c,--command | ||||||
|  |         Send a command to running MPD. Available commands : | ||||||
|  |           * toggle, play, pause | ||||||
|  |           * next | ||||||
|  |           * previous | ||||||
|  |           * random | ||||||
|  |           * party, partymode, randomparty | ||||||
|  | 
 | ||||||
|  |     -d,--debug | ||||||
|  |         Enable debug messages. | ||||||
|  | 
 | ||||||
|  |     -h,--help | ||||||
|  |         Print this help message. | ||||||
|  | HELP | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | debug_message() {                                               # {{{ | ||||||
|  | 
 | ||||||
|  | 	local_debug_message="${1}" | ||||||
|  | 
 | ||||||
|  | 	## Print message if DEBUG is enable (=0) | ||||||
|  | 	[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6b\e[m\n' "DEBUG − ${PROGNAME} : ${local_debug_message}" | ||||||
|  | 
 | ||||||
|  | 	unset local_debug_message | ||||||
|  | 
 | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | error_message() {                                               # {{{ | ||||||
|  | 
 | ||||||
|  | 	local_error_message="${1}" | ||||||
|  | 	local_error_code="${2}" | ||||||
|  | 
 | ||||||
|  | 	## Print message | ||||||
|  | 	printf '%b\n' "ERROR − ${PROGNAME} : ${RED}${local_error_message}${RESET}" | ||||||
|  | 
 | ||||||
|  | 	exit "${local_error_code:=66}" | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | define_vars() {                                                 # {{{ | ||||||
|  | 
 | ||||||
|  | 	## If USER_MULTIMEDIA_COMMAND wasn't defined (argument) {{{ | ||||||
|  | 	if [ -z "${USER_MULTIMEDIA_COMMAND}" ]; then | ||||||
|  | 		## Use default value | ||||||
|  | 		readonly USER_MULTIMEDIA_COMMAND="${USER_MULTIMEDIA_COMMAND_DEFAULT}" | ||||||
|  | 	fi | ||||||
|  | 	## }}} | ||||||
|  | 	## Translate user command to MPD command {{{ | ||||||
|  | 	case "${USER_MULTIMEDIA_COMMAND}" in | ||||||
|  | 		toggle )                              ## Toggle current play | ||||||
|  | 			debug_message "defined − \ | ||||||
|  | Use ${RED}MPC${COLOR_DEBUG} client for ${USER_MULTIMEDIA_COMMAND} command." | ||||||
|  | 			MPD_COMMAND=$(mpc --quiet toggle) | ||||||
|  | 			;; | ||||||
|  | 		play )                                ## Starts playing song (default number 1) | ||||||
|  | 			debug_message "defined − \ | ||||||
|  | Use ${RED}MPC${COLOR_DEBUG} client for ${USER_MULTIMEDIA_COMMAND} command." | ||||||
|  | 			MPD_COMMAND=$(mpc --quiet play) | ||||||
|  | 			;; | ||||||
|  | 		pause )                               ## Pauses playing | ||||||
|  | 			debug_message "defined − \ | ||||||
|  | Use ${RED}MPC${COLOR_DEBUG} client for ${USER_MULTIMEDIA_COMMAND} command." | ||||||
|  | 			MPD_COMMAND=$(mpc --quiet pause) | ||||||
|  | 			;; | ||||||
|  | 		next )                                ## Starts playing next song on queue | ||||||
|  | 			debug_message "defined − \ | ||||||
|  | Use ${RED}MPC${COLOR_DEBUG} client for ${USER_MULTIMEDIA_COMMAND} command." | ||||||
|  | 			MPD_COMMAND=$(mpc --quiet next) | ||||||
|  | 			;; | ||||||
|  | 		prev|previous )                       ## Starts playing previous song | ||||||
|  | 			debug_message "defined − \ | ||||||
|  | Use ${RED}MPC${COLOR_DEBUG} client for ${USER_MULTIMEDIA_COMMAND} command." | ||||||
|  | 			MPD_COMMAND=$(mpc --quiet prev) | ||||||
|  | 			;; | ||||||
|  | 		random )                              ## Toggle random mode | ||||||
|  | 			debug_message "defined − \ | ||||||
|  | Use ${RED}MPC${COLOR_DEBUG} client for ${USER_MULTIMEDIA_COMMAND} command." | ||||||
|  | 			MPD_COMMAND=$(mpc --quiet random) | ||||||
|  | 			;; | ||||||
|  | 		party|partymode|randomparty )         ## Start random playing | ||||||
|  | 			debug_message "defined − \ | ||||||
|  | Use multiple ${RED}MPC${COLOR_DEBUG} commands for ${USER_MULTIMEDIA_COMMAND} action." | ||||||
|  | 			MPD_COMMAND=$(mpc --quiet clear; mpc --quiet random on; mpc --quiet add /; mpc --quiet play) | ||||||
|  | 			;; | ||||||
|  | 		* )                                   ## unknow option | ||||||
|  | 			printf '%b\n' "${RED}Invalid MPD|MPC command: ${USER_MULTIMEDIA_COMMAND}${RESET}" | ||||||
|  | 			printf '%b\n' "---" | ||||||
|  | 			usage | ||||||
|  | 			exit 1 | ||||||
|  | 			;; | ||||||
|  | 	esac | ||||||
|  | 	## }}} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | is_proc_absent() {                                             # {{{ | ||||||
|  | 
 | ||||||
|  | 	local_proc_pattern="${1}" | ||||||
|  | 
 | ||||||
|  | 	## Proc is absent by default | ||||||
|  | 	return_proc_absent="0" | ||||||
|  | 
 | ||||||
|  | 	local_count_proc_pattern="$(pgrep -f -- "${local_proc_pattern}" | wc -l)" | ||||||
|  | 
 | ||||||
|  | 	case "${local_count_proc_pattern}" in | ||||||
|  | 		0 ) ## No procs related to this pattern are running | ||||||
|  | 			return_proc_absent="0" | ||||||
|  | 			;; | ||||||
|  | 		* ) ## At least one proc seems running | ||||||
|  | 			return_proc_absent="1" | ||||||
|  | 			;; | ||||||
|  | esac | ||||||
|  | 
 | ||||||
|  | 	## Simple debug message to valid current variables | ||||||
|  | 	debug_message "is_proc_absent − \ | ||||||
|  | procs running (with the pattern: ${RED}${local_proc_pattern}${COLOR_DEBUG}) on the current host: ${RED}${local_count_proc_pattern}${COLOR_DEBUG}." | ||||||
|  | 
 | ||||||
|  | 	return "${return_proc_absent}" | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | 
 | ||||||
|  | main() {                                                        # {{{ | ||||||
|  | 
 | ||||||
|  | 	## Define all vars | ||||||
|  | 	define_vars | ||||||
|  | 
 | ||||||
|  | 	## If MPD is not running {{{ | ||||||
|  | 	### AND Start it | ||||||
|  | 	### AND exit 0 | ||||||
|  | 	is_proc_absent "${MPD_PROC_REGEXP}" \ | ||||||
|  | 		&& debug_message "Start ${RED}mpd with systemd${COLOR_DEBUG}." \ | ||||||
|  | 		&& systemctl --user start mpd.service \ | ||||||
|  | 		&& mpc --quiet random off \ | ||||||
|  | 		&& exit 0 | ||||||
|  | 	## }}} | ||||||
|  | 
 | ||||||
|  | 	## Send MPD action to running instance {{{ | ||||||
|  | 	### And exit | ||||||
|  | 	debug_message "Send ${RED}${USER_MULTIMEDIA_COMMAND}${COLOR_DEBUG} action to running MPD instance." \ | ||||||
|  | 		"${MPD_COMMAND}" \ | ||||||
|  | 		&& exit 0 | ||||||
|  | 	## }}} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | 
 | ||||||
|  | # Manage arguments                                                # {{{ | ||||||
|  | # This code can't be in a function due to argument management | ||||||
|  | 
 | ||||||
|  | if [ ! "${NBARGS}" -eq "0" ]; then | ||||||
|  | 
 | ||||||
|  | 	manage_arg="0" | ||||||
|  | 
 | ||||||
|  | 	## If the first argument is not an option | ||||||
|  | 	if ! printf -- '%s' "${1}" | grep -q -E -- "^-+"; | ||||||
|  | 	then | ||||||
|  | 		## Print help message and exit | ||||||
|  | 		printf '%b\n' "${RED}Invalid option: ${1}${RESET}" | ||||||
|  | 		printf '%b\n' "---" | ||||||
|  | 		usage | ||||||
|  | 
 | ||||||
|  | 		exit 1 | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	# Parse all options (start with a "-") one by one | ||||||
|  | 	while printf -- '%s' "${1}" | grep -q -E -- "^-+"; do | ||||||
|  | 
 | ||||||
|  | 	case "${1}" in | ||||||
|  | 		-c|--command )                        ## User command | ||||||
|  | 			### Move to the next argument | ||||||
|  | 			shift | ||||||
|  | 			### Define var | ||||||
|  | 			USER_MULTIMEDIA_COMMAND="${1}" | ||||||
|  | 			;; | ||||||
|  | 		-d|--debug )                          ## debug | ||||||
|  | 			DEBUG=0 | ||||||
|  | 			;; | ||||||
|  | 		-h|--help )                           ## help | ||||||
|  | 			usage | ||||||
|  | 			## Exit after help informations | ||||||
|  | 			exit 0 | ||||||
|  | 			;; | ||||||
|  | 		* )                                   ## unknow option | ||||||
|  | 			printf '%b\n' "${RED}Invalid option: ${1}${RESET}" | ||||||
|  | 			printf '%b\n' "---" | ||||||
|  | 			usage | ||||||
|  | 			exit 1 | ||||||
|  | 			;; | ||||||
|  | 	esac | ||||||
|  | 
 | ||||||
|  | 	debug_message "Arguments management − \ | ||||||
|  | ${RED}${1}${COLOR_DEBUG} option|command managed." | ||||||
|  | 
 | ||||||
|  | 	## Move to the next argument | ||||||
|  | 	shift | ||||||
|  | 	manage_arg=$((manage_arg+1)) | ||||||
|  | 
 | ||||||
|  | 	done | ||||||
|  | 
 | ||||||
|  | 	debug_message "Arguments management − \ | ||||||
|  | ${RED}${manage_arg}${COLOR_DEBUG} argument(s) successfully managed." | ||||||
|  | else | ||||||
|  | 	debug_message "Arguments management − \ | ||||||
|  | No arguments/options to manage." | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | # }}} | ||||||
|  | 
 | ||||||
|  | main | ||||||
|  | 
 | ||||||
|  | exit 255 | ||||||
|  | @ -0,0 +1,275 @@ | ||||||
|  | #!/bin/sh | ||||||
|  | # | ||||||
|  | # Purpose {{{ | ||||||
|  | # This script will try to control MPV with IPC socket | ||||||
|  | #   1. Check for MPV proc with IPC socket option. | ||||||
|  | #   2. Verify if a process runs with one of the expected socket. | ||||||
|  | #      Unable to correctly extract socket path from command line… | ||||||
|  | #   3. Send user command to the last MPV process with a existing socket. | ||||||
|  | # | ||||||
|  | # 2022-05-22 | ||||||
|  | # }}} | ||||||
|  | # TODO {{{ | ||||||
|  | # * Add an option to set the socket path. | ||||||
|  | # * Set a list of sockets path and use the first existing one. | ||||||
|  | # * Add new user command ? | ||||||
|  | # }}} | ||||||
|  | # Vars {{{ | ||||||
|  | PROGNAME=$(basename "${0}"); readonly PROGNAME | ||||||
|  | PROGDIR=$(readlink -m $(dirname "${0}")); readonly PROGDIR | ||||||
|  | ARGS="${*}"; readonly ARGS | ||||||
|  | [ -z "${DEBUG}" ] && DEBUG=1 | ||||||
|  | ## Export DEBUG for sub-script | ||||||
|  | export DEBUG | ||||||
|  | 
 | ||||||
|  | ## Default values for some vars | ||||||
|  | readonly MPV_PROC_REGEXP="mpv.*--input-ipc-server" | ||||||
|  | readonly USER_MULTIMEDIA_COMMAND_DEFAULT="toggle" | ||||||
|  | readonly MPV_POSSIBLE_SOCKET_PATH="${HOME}/.cache/qutebrowser/mpv.ipc.socket" | ||||||
|  | 
 | ||||||
|  | ## Colors | ||||||
|  | readonly PURPLE='\033[1;35m' | ||||||
|  | readonly RED='\033[0;31m' | ||||||
|  | readonly RESET='\033[0m' | ||||||
|  | readonly COLOR_DEBUG="${PURPLE}" | ||||||
|  | # }}} | ||||||
|  | usage() {                                                       # {{{ | ||||||
|  | 
 | ||||||
|  | 	cat <<- HELP | ||||||
|  | usage: $PROGNAME [-c|-d|-h] | ||||||
|  | 
 | ||||||
|  | Manage MPV with IPC socket. | ||||||
|  | Can only manage the last mpv process started with --input-ipc-server option. | ||||||
|  | 
 | ||||||
|  | EXAMPLES : | ||||||
|  |     - Pauses playing | ||||||
|  |         ${PROGNAME} --command pause | ||||||
|  | 
 | ||||||
|  |     - Send default command (${USER_MULTIMEDIA_COMMAND_DEFAULT}) to MPV | ||||||
|  |         ${PROGNAME} | ||||||
|  | 
 | ||||||
|  | OPTIONS : | ||||||
|  |     -c,--command | ||||||
|  |         Send a command to running MPV. Available commands : | ||||||
|  |           * toggle play, pause | ||||||
|  |           * play | ||||||
|  |           * pause | ||||||
|  | 
 | ||||||
|  |     -d,--debug | ||||||
|  |         Enable debug messages. | ||||||
|  | 
 | ||||||
|  |     -h,--help | ||||||
|  |         Print this help message. | ||||||
|  | HELP | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | debug_message() {                                               # {{{ | ||||||
|  | 
 | ||||||
|  | 	local_debug_message="${1}" | ||||||
|  | 
 | ||||||
|  | 	## Print message if DEBUG is enable (=0) | ||||||
|  | 	[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6b\e[m\n' "DEBUG − ${PROGNAME} : ${local_debug_message}" | ||||||
|  | 
 | ||||||
|  | 	unset local_debug_message | ||||||
|  | 
 | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | error_message() {                                               # {{{ | ||||||
|  | 
 | ||||||
|  | 	local_error_message="${1}" | ||||||
|  | 	local_error_code="${2}" | ||||||
|  | 
 | ||||||
|  | 	## Print message | ||||||
|  | 	printf '%b\n' "ERROR − ${PROGNAME} : ${RED}${local_error_message}${RESET}" | ||||||
|  | 
 | ||||||
|  | 	exit "${local_error_code:=66}" | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | define_vars() {                                                 # {{{ | ||||||
|  | 
 | ||||||
|  | 	## Get the socket path of the last MPV process {{{ | ||||||
|  | 	## Can't extract a valid socket path from the command line ! | ||||||
|  | 	## So… no other choice than test a static list of possible socket | ||||||
|  | 	MPV_SOCKET_PATH="${MPV_POSSIBLE_SOCKET_PATH}" | ||||||
|  | 	debug_message "define_vars − \ | ||||||
|  | IPC socket path for the last MPV process : ${RED}${MPV_SOCKET_PATH}${COLOR_DEBUG} ." | ||||||
|  | 	## }}} | ||||||
|  | 	## If USER_MULTIMEDIA_COMMAND wasn't defined (argument) {{{ | ||||||
|  | 	if [ -z "${USER_MULTIMEDIA_COMMAND}" ]; then | ||||||
|  | 		## Use default value | ||||||
|  | 		readonly USER_MULTIMEDIA_COMMAND="${USER_MULTIMEDIA_COMMAND_DEFAULT}" | ||||||
|  | 	fi | ||||||
|  | 	## }}} | ||||||
|  | 	## Translate user command to MPV command {{{ | ||||||
|  | 	case "${USER_MULTIMEDIA_COMMAND}" in | ||||||
|  | 		toggle )                              ## Toggle current play | ||||||
|  | 			debug_message "define_vars − \ | ||||||
|  | Use ${RED}MPV socket${COLOR_DEBUG} to send ${USER_MULTIMEDIA_COMMAND} command." | ||||||
|  | 			MPV_COMMAND=$(echo '{ "command": ["cycle", "pause"] }' | socat - "${MPV_SOCKET_PATH}") | ||||||
|  | 			;; | ||||||
|  | 		play )                                ## Starts playing song (default number 1) | ||||||
|  | 			debug_message "define_vars − \ | ||||||
|  | Use ${RED}MPV socket${COLOR_DEBUG} to send ${USER_MULTIMEDIA_COMMAND} command." | ||||||
|  | 			MPV_COMMAND=$(echo '{ "command": ["set_property", "pause", false] }' | socat - "${MPV_SOCKET_PATH}") | ||||||
|  | 			;; | ||||||
|  | 		pause )                               ## Pauses playing | ||||||
|  | 			debug_message "define_vars − \ | ||||||
|  | Use ${RED}MPV socket${COLOR_DEBUG} to send ${USER_MULTIMEDIA_COMMAND} command." | ||||||
|  | 			MPV_COMMAND=$(echo '{ "command": ["set_property", "pause", true] }' | socat - "${MPV_SOCKET_PATH}") | ||||||
|  | 			;; | ||||||
|  | 		* )                                   ## unknow option | ||||||
|  | 			printf '%b\n' "${RED}Invalid MPV command: ${USER_MULTIMEDIA_COMMAND}${RESET}" | ||||||
|  | 			printf '%b\n' "---" | ||||||
|  | 			usage | ||||||
|  | 			exit 1 | ||||||
|  | 			;; | ||||||
|  | 	esac | ||||||
|  | 	## }}} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | is_proc_absent() {                                              # {{{ | ||||||
|  | 
 | ||||||
|  | 	local_proc_pattern="${1}" | ||||||
|  | 
 | ||||||
|  | 	## Proc is absent by default | ||||||
|  | 	return_proc_absent="0" | ||||||
|  | 
 | ||||||
|  | 	local_count_proc_pattern="$(pgrep -f -- "${local_proc_pattern}" | wc -l)" | ||||||
|  | 
 | ||||||
|  | 	case "${local_count_proc_pattern}" in | ||||||
|  | 		0 ) ## No procs related to this pattern are running | ||||||
|  | 			return_proc_absent="0" | ||||||
|  | 			;; | ||||||
|  | 		* ) ## At least one proc seems running | ||||||
|  | 			return_proc_absent="1" | ||||||
|  | 			;; | ||||||
|  | esac | ||||||
|  | 
 | ||||||
|  | 	## Simple debug message to valid current variables | ||||||
|  | 	debug_message "is_proc_absent − \ | ||||||
|  | procs running (with the pattern: ${RED}${local_proc_pattern}${COLOR_DEBUG}) on the current host: ${RED}${local_count_proc_pattern}${COLOR_DEBUG}." | ||||||
|  | 
 | ||||||
|  | 	return "${return_proc_absent}" | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | is_socket_absent() {                                            # {{{ | ||||||
|  | 
 | ||||||
|  | 	local_socket_absent="${1}" | ||||||
|  | 
 | ||||||
|  | 	## Socket exists by default | ||||||
|  | 	return_is_socket_absent="1" | ||||||
|  | 
 | ||||||
|  | 	### Check if the socket exists | ||||||
|  | 	# shellcheck disable=SC2086 | ||||||
|  | 	if find ${local_socket_absent} -type s > /dev/null 2>&1; then | ||||||
|  | 		return_is_socket_absent="1" | ||||||
|  | 		debug_message "is_socket_absent − \ | ||||||
|  | The socket ${RED}${local_socket_absent}${COLOR_DEBUG} exists." | ||||||
|  | 	else | ||||||
|  | 		return_is_socket_absent="0" | ||||||
|  | 		debug_message "is_socket_absent − \ | ||||||
|  | The socket ${RED}${local_socket_absent}${COLOR_DEBUG} doesn't exist." | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	return "${return_is_socket_absent}" | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | 
 | ||||||
|  | main() {                                                        # {{{ | ||||||
|  | 
 | ||||||
|  | 	## If MPV is not running {{{ | ||||||
|  | 	### AND exit 1 | ||||||
|  | 	is_proc_absent "${MPV_PROC_REGEXP}" \ | ||||||
|  | 		&& debug_message "No MPV running process with IPS socket." \ | ||||||
|  | 		&& exit 1 | ||||||
|  | 	## }}} | ||||||
|  | 
 | ||||||
|  | 	## Define all vars | ||||||
|  | 	define_vars | ||||||
|  | 
 | ||||||
|  | 	## If MPV's IPC socket is not present {{{ | ||||||
|  | 	### AND exit 1 | ||||||
|  | 	is_socket_absent "${MPV_SOCKET_PATH}" \ | ||||||
|  | 		&& debug_message "Can't access to MPV IPC socket : ${RED}${MPV_SOCKET_PATH}${COLOR_DEBUG}." \ | ||||||
|  | 		&& exit 1 | ||||||
|  | 	## }}} | ||||||
|  | 	## Send MPV action to running instance {{{ | ||||||
|  | 	### And exit | ||||||
|  | 	debug_message "Send ${RED}${USER_MULTIMEDIA_COMMAND}${COLOR_DEBUG} action to last MPV running instance with an IPC socket." \ | ||||||
|  | 		"${MPV_COMMAND}" \ | ||||||
|  | 		&& exit 0 | ||||||
|  | 	## }}} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | # }}} | ||||||
|  | 
 | ||||||
|  | # Manage arguments                                                # {{{ | ||||||
|  | # This code can't be in a function due to argument management | ||||||
|  | 
 | ||||||
|  | if [ ! "${NBARGS}" -eq "0" ]; then | ||||||
|  | 
 | ||||||
|  | 	manage_arg="0" | ||||||
|  | 
 | ||||||
|  | 	## If the first argument is not an option | ||||||
|  | 	if ! printf -- '%s' "${1}" | grep -q -E -- "^-+"; | ||||||
|  | 	then | ||||||
|  | 		## Print help message and exit | ||||||
|  | 		printf '%b\n' "${RED}Invalid option: ${1}${RESET}" | ||||||
|  | 		printf '%b\n' "---" | ||||||
|  | 		usage | ||||||
|  | 
 | ||||||
|  | 		exit 1 | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	# Parse all options (start with a "-") one by one | ||||||
|  | 	while printf -- '%s' "${1}" | grep -q -E -- "^-+"; do | ||||||
|  | 
 | ||||||
|  | 	case "${1}" in | ||||||
|  | 		-c|--command )                        ## User command | ||||||
|  | 			### Move to the next argument | ||||||
|  | 			shift | ||||||
|  | 			### Define var | ||||||
|  | 			USER_MULTIMEDIA_COMMAND="${1}" | ||||||
|  | 			;; | ||||||
|  | 		-d|--debug )                          ## debug | ||||||
|  | 			DEBUG=0 | ||||||
|  | 			;; | ||||||
|  | 		-h|--help )                           ## help | ||||||
|  | 			usage | ||||||
|  | 			## Exit after help informations | ||||||
|  | 			exit 0 | ||||||
|  | 			;; | ||||||
|  | 		* )                                   ## unknow option | ||||||
|  | 			printf '%b\n' "${RED}Invalid option: ${1}${RESET}" | ||||||
|  | 			printf '%b\n' "---" | ||||||
|  | 			usage | ||||||
|  | 			exit 1 | ||||||
|  | 			;; | ||||||
|  | 	esac | ||||||
|  | 
 | ||||||
|  | 	debug_message "Arguments management − \ | ||||||
|  | ${RED}${1}${COLOR_DEBUG} option|command managed." | ||||||
|  | 
 | ||||||
|  | 	## Move to the next argument | ||||||
|  | 	shift | ||||||
|  | 	manage_arg=$((manage_arg+1)) | ||||||
|  | 
 | ||||||
|  | 	done | ||||||
|  | 
 | ||||||
|  | 	debug_message "Arguments management − \ | ||||||
|  | ${RED}${manage_arg}${COLOR_DEBUG} argument(s) successfully managed." | ||||||
|  | else | ||||||
|  | 	debug_message "Arguments management − \ | ||||||
|  | No arguments/options to manage." | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | # }}} | ||||||
|  | 
 | ||||||
|  | main | ||||||
|  | 
 | ||||||
|  | exit 255 | ||||||
		Loading…
	
		Reference in New Issue