diff --git a/README.md b/README.md index 229b2016..6c0664a5 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,14 @@ ![GitHub top language](https://img.shields.io/github/languages/top/lwilletts/mpvc) ![GitHub lines of Code](https://sloc.xyz/github/lwilletts/mpvc/?category=code) -# mpvc ๐ŸŽง +# mpvc ๐ŸŽง [^install] A terminal music player in POSIX sh(1) that interfaces mpv providing mpc(1) commands + extras. Originally a fork of [lwillets/mpvc](https://github.com/lwilletts/mpvc) that evolved on its own, providing some extra goodies such as: improved CLI, TUI, FZF, WEB, EQ, & playing media from YouTube & streaming services. Check the [Wiki](../../wiki), [LogBook](../../wiki#logbook) & [Casts](../../wiki#screencasts) for a detailed view of the extra features of this fork. +Skip directly to [Installation](#Installation) to try mpvc! +
mpvc-tui -T: running the mpvc TUI (click to view screenshot) @@ -18,7 +20,7 @@ Check the [Wiki](../../wiki), [LogBook](../../wiki#logbook) & [Casts](../../wiki
mpvc-fzf -f: running with fzf to manage the playlist (click to view screenshot) - + ![mpvc-fzf screenshot](../../blob/master/docs/assets/mpvc-tui-arch.png)
@@ -26,9 +28,9 @@ Check the [Wiki](../../wiki), [LogBook](../../wiki#logbook) & [Casts](../../wiki mpvc-tui -n: running with mpvc-fzf and desktop notifications on the upper-right corner (click to view screenshot) ![mpvc tui+fzf+notifications screenshot](../../blob/master/docs/assets/mpvc-tui-fzf.png) -
+ -## Overview โ–ถ๏ธ +## Overview โ–ถ๏ธ [^install] [mpvc](../../) player functionality is provided by: @@ -36,6 +38,7 @@ Check the [Wiki](../../wiki), [LogBook](../../wiki#logbook) & [Casts](../../wiki - [extras/mpvc-tui](../../blob/master/extras/mpvc-tui): provides a console TUI, using mpvc underneath - [extras/mpvc-fzf](../../blob/master/extras/mpvc-fzf): provides FZF integration to mpvc. - [extras/mpvc-web](../../blob/master/extras/mpvc-web): a hack to remotely control mpvc from web (handy on mobile) +- [extras/mpvc-now](../../blob/master/extras/mpvc-now): generates a URL to share the current playlist - [extras/mpvc-mpris](../../blob/master/extras/mpvc-mpris): speaks MPRIS to control mpv player through key-bindings. - [extras/mpvc-equalizer](../../blob/master/extras/mpvc-equalizer): provides a basic mpv equalizer for the CLI. - [extras/mpvc-autostart](../../blob/master/extras/mpvc-autostart): automatic mpv start/stop based on presence. @@ -52,7 +55,7 @@ Required: - `socat`: is preferred due to the differing implementations of `netcat` across UNIXes. - `awk`: a sane version of `awk` for the same reason (`gawk` works) -Recommended extras: +Recommended extras: - `curl` - `fzf` @@ -72,6 +75,8 @@ Check for missing dependencies using `mpvc-installer check-reqs`. - [Gentoo](#gentoo-mpvc) - [Nix](#nix-mpvc) +Installing is just a matter of fetching the scripts either via Git/Curl/etc., scripts can be used directly from the repo, the `mpvc-installer` bit is just there for easiness, to fetch & link them into your `BINDIR=~/bin/` by default, + ### Manual The easiest install method is just to run the [mpvc-installer](../../blob/master/extras/mpvc-installer) to install under `$HOME/bin` @@ -83,11 +88,14 @@ curl -fsSL -o mpvc-installer https://github.com/lwilletts/mpvc/raw/master/extras ### Git +Below is a **Quick Start** guide showcasing mpvc commands usage. + ```sh # fetch a local copy of the github repo git clone https://github.com/lwilletts/mpvc/ # use extras/mpvc-installer: just copy/link to your $HOME/bin (cd mpvc; extras/mpvc-installer link-user) + (cd mpvc; extras/mpvc-installer check-reqs) # use mpvc-fzf to search and play youtube media mpvc-fzf -p 'kupla mirage' @@ -121,10 +129,10 @@ pacman -Sy mpv gawk curl socat fzf rlwrap jq libnotify ### BSD -BSD (and pkg(1) based derivatives such as FreeBSD): +BSD (and pkg(1) based derivatives as FreeBSD, see [FAQ](../../wiki/FAQ)): ```console -pkg install -y mpv gawk curl socat fzf rlwrap jq libnotify +pkg install -y mpv curl socat fzf rlwrap jq libnotify # gawk gsed ``` ### MacOS @@ -132,16 +140,16 @@ pkg install -y mpv gawk curl socat fzf rlwrap jq libnotify MacOS (and brew(1) based derivatives see [FAQ](../../wiki/FAQ)): ```console -brew install gawk socat fzf rlwrap jq gnu-sed yt-dlp # mpv curl libnotify +brew install mpv curl socat fzf rlwrap jq libnotify yt-dlp # gawk gnu-sed ``` ### Gentoo [mpvc](https://gitlab.com/xy2_/osman) ```console emerge mpvc -``` +``` -### Nix [mpvc](http://github.com/nixos/nixpkgs/tree/master/pkgs/applications/misc/mpvc) +### Nix [mpvc](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/mp/mpvc/) ```console nix-env -i mpvc @@ -199,7 +207,7 @@ usage: mpvc-fzf -[01ab:cCd:efFg:G:hk:K:n:s:p:P:o:Or:lL:xv] args # @version v1.5 ## Tricks -There's some basic tricks in [Git](#git) to get you started. +There's some basic tricks in [Git](#git) to get you started. For more check the [LogBook](../../wiki#logbook). This gives just a sneak peek on what's possible to manage mpv from the command-line, your best chances are to go play and have fun. @@ -215,3 +223,6 @@ Like any piece of software, mpvc is not perfect: all effort has been made to make mpvc as POSIX compliant as possible. Check out the [Issue Tracker](../../issues) for further improvements to be made. + +[^install]: Skip directly to [Installation](#Installation) to try mpvc + diff --git a/docs/logbook.html b/docs/logbook.html index 611e00aa..a43fe7de 100644 --- a/docs/logbook.html +++ b/docs/logbook.html @@ -91,6 +91,7 @@

Contents

  • #20240301 On support UNIXes besides GNU/Linux: BSD and MacOS
  • #20240405 Introducing mpvc-chapter: helper managing chapters, 5 Apr 2024
  • #20240505 Introducing mpvc-osd: interfacing mpvc with a 4x20 USB LCD, 5 May 2024
  • +
  • #20240704 Some notes on my current mpvc setup, 4 July 2024

  • @@ -389,6 +390,7 @@

    Introducing mpvc-web: a mpvc-tui like hack for the web alias mcI="mpvc chapter-list-full" alias me="mpvc-equalizer" alias mtt="mpvc-tui" + alias mtth="mpvc-tui -H" alias mm="mpvc-mpris" alias mw="mpvc-web" alias mff="mpvc-fzf" # fzf on mpvc @@ -405,7 +407,8 @@

    Introducing mpvc-web: a mpvc-tui like hack for the web alias mffo="mpvc-fzf -o" # fzf search and return first ytid URL alias mffp="mpvc-fzf -p" # fzf search and add ytid URLs from Invidious alias xargn="xargs -n1" # xargn mpvc cmd - rseq() { seq "$@" | tac; } # rseq | xargn mpvc cmd + rseq() { seq "$@" | tac; } # rseq | xargn mpvc cmd + mffo1() { mpvc add $(mpvc-fzf -o "$@" | mpvc-fzf -1); }

    @@ -542,20 +545,20 @@

    On the security of mpvc-web, 17 Nov 2023

    So, now the following alternatives are available, ordered from less to more secure:
    1. - For local purposes, just run mpvc-web that defaults to `localhost` with: `mpvc-web`. + For local purposes, just run mpvc-web that defaults to `localhost` with: `mpvc-web`.
    2. - If its safe running plain HTTP on the home LAN, then use: `MPVC_WEB_HOST=0 mpvc-web`. + If its safe running plain HTTP on the home LAN, then use: `MPVC_WEB_HOST=0 mpvc-web`.
    3. - Otherwise, if its not safe for running plain HTTP on the LAN, then use: - `MPVC_WEB_HOST=0 MPVC_WEB_SSL_ENABLE=1 mpvc-web` to require HTTPS. + Otherwise, if its not safe for running plain HTTP on the LAN, then use: + `MPVC_WEB_HOST=0 MPVC_WEB_SSL_ENABLE=1 mpvc-web` to require HTTPS.
    4. - If additionally, the environment can get attacks from malicious users, then - require the use of peer certificates, therefore, limiting access only to those - clients/peers that have present valid `stunnel(1)` certificate with: - `MPVC_WEB_HOST=0 MPVC_WEB_SSL_ENABLE=1 MPVC_WEB_SSL_VERIFY=2 mpvc-web` + If additionally, the environment can get attacks from malicious users, then + require the use of peer certificates, therefore, limiting access only to those + clients/peers that have present valid `stunnel(1)` certificate with: + `MPVC_WEB_HOST=0 MPVC_WEB_SSL_ENABLE=1 MPVC_WEB_SSL_VERIFY=2 mpvc-web`

    @@ -645,7 +648,46 @@

    Introducing mpvc-osd: interfacing mpvc with a 4x20 USB mpvc-tui -S 'echo $(date +"T%H:%M") $(mpvc -f "[%status%] #%position%/%playlistlength% %time% %artist% - %title% - %path%")' 'false' And this is how it looks: -mpvc-osd usblcd +

    +mpvc-osd usblcd +

    +

    + +

    Some notes on my current mpvc setup, 4 July 2024

    +

    + +Some notes on my current mpvc setup, I've setled on having the following commands continuosly running on background: mpvc-tui, mpvc-web, mpvc-autostart, and mpvc-osd: + +

    + +For the record, this is the list of commands currently running: + +
    +mpvc-tui -T
    +mpvc-web -b 0 -s 1 -a 1 -R 60 -t dark -c start
    +mpvc-autostart -p 600 -n 6 -i [local_ip]
    +# mpvc-osd mpvcosd
    +
    + +Using mpvc-web, on a device with a HDMI display, opens news possibilities of displaying video media, that is beyond just acting as a jukebox for playing music. +For setups where the mediacenter has a video display with X11 x2x(1) might come handy to send X11 input events from a ssh-client to control the remote mpv running on X11, an example invocation is: +
    +ssh -X $USER@$HOST x2x -west -to :0 # be sure to read x2x(1)
    +
    +

    @@ -653,7 +695,7 @@

    Introducing mpvc-osd: interfacing mpvc with a 4x20 USB

    - Last-Modified: Sunday, 5 May 2024 by gmt4 + Last-Modified: Thursday, 4 July 2024 by gmt4 Powered by #HTML ๐Ÿงก ๐Ÿ’š ๐Ÿ’™ diff --git a/docs/now/index.html b/docs/now/index.html index a4a1f90c..2c04b9a3 100644 --- a/docs/now/index.html +++ b/docs/now/index.html @@ -68,6 +68,7 @@

    Now Listening

    +
    @@ -81,9 +82,12 @@

    Scrobbling Code

    const urlp = new URL(window.location.href).searchParams const dflt = [ 'ssDzysKLlpY', '667dtK7O89k', 'mEkZbWYUego', 'UzRFQ6pDqhk', '_nl3Oo4-IQ4', 'ypAIWyH13aM', 'Jls9wXOSjl4', 'Hwg7hJrDiRg', '6FJ7F6trvBc' ] const vids = urlp.getAll('v').length > 0 ? urlp.getAll('v') : dflt + const autoplay = urlp.getAll('autoplay').length > 0 ? 1 : 0 + const loop = urlp.getAll('loop').length > 0 ? 1 : 0 const cont = document.getElementById('container') const pre = document.getElementById('pre') pre.innerHTML = '\n' + for(i in vids) { if (/^([-_a-zA-Z0-9]{11})$/.test(vids[i])) @@ -91,7 +95,8 @@

    Scrobbling Code

    const video = vids[i] const url='https://www.youtube.com/watch?v='+video+'\n' const emb='https://www.youtube.com/embed/'+video - const html='' + const att='?autoplay='+( autoplay ? i == 0 : 0)+'&loop='+( loop ? 1 : 0 ) + const html='' const node = document.createElement('div') node.setAttribute('class', 'item') diff --git a/extras/mpvc-autostart b/extras/mpvc-autostart index b9b37919..295a73d1 100755 --- a/extras/mpvc-autostart +++ b/extras/mpvc-autostart @@ -4,6 +4,7 @@ # @description mpvc auto pause/resume audio based on device presence # @author gmt4 (c) Copyright 2022 GPLv2+ # @url github.com/gmt4/mpvc +# SPDX-License-Identifier: GPL-2.0-or-later # PROGNAME=${0##*/} @@ -18,7 +19,7 @@ mpvc_defaults() ARGS=${ARGS:-} } -mpvc_pingcheck() { ping -w 5 -c 5 "$@" | awk 'NR == 2 && /time=/ { sub(":.*time=",": time="); print }'; } +mpvc_pingcheck() { ping -c 5 "$@" | awk 'NR == 2 && /time=/ { sub(":.*time=",": time="); print }'; } mpvc_btcheck() { hcitool scan | awk "/$@/ {print}"; } # monitor presence of your phone (eg LAN IP/BT): if device is present resume audio, otherwise, pause audio. @@ -45,7 +46,7 @@ mpvc_autoscan() [ "$ncheck" -gt 0 ] && mpvc -q resume # n>0 pings up: resume [ "$ncheck" -le -$NCHECK ] && mpvc -q pause # n<0 pings down: pause fi - echo "# $(date -Imin) PERIOD=$PERIOD NCHECK=$NCHECK pause=$pause c=${#check} n=${ncheck} $check" # $@ + echo "# $(date) PERIOD=$PERIOD NCHECK=$NCHECK pause=$pause c=${#check} n=${ncheck} $check" # $@ done } diff --git a/extras/mpvc-chapter b/extras/mpvc-chapter index dbfd0c31..30fe565c 100755 --- a/extras/mpvc-chapter +++ b/extras/mpvc-chapter @@ -4,6 +4,7 @@ # @description mpvc chapter helper utils (see mpvc chapter-list instead) # @author gmt4 (c) Copyright 2022 GPLv2+ # @url github.com/gmt4/mpvc +# SPDX-License-Identifier: GPL-2.0-or-later # PROGNAME=${0##*/} diff --git a/extras/mpvc-cut b/extras/mpvc-cut index 9a608c6d..f35cac8b 100755 --- a/extras/mpvc-cut +++ b/extras/mpvc-cut @@ -4,6 +4,7 @@ # @description mpvc cuts playing media between ab-loop points (idea from lwillets) # @author gmt4 (c) Copyright 2022 GPLv2+ # @url github.com/gmt4/mpvc +# SPDX-License-Identifier: GPL-2.0-or-later # PROGNAME=${0##*/} @@ -51,6 +52,35 @@ mpvc_cutfile() esac } +mpvc_cut() +{ + mpvc_cutfile "$operation" "$(mpvc g 'path')" "$(mpvc g 'ab-loop-a')" "$(mpvc g 'ab-loop-b')" +} + +mpvc_screencast() +{ + vres=$(xrandr | awk ' + /^Screen 0: .* current .*/ { + r=$0; sub("^.* current ","",r); sub(", maximum .*$","",r); gsub(" ","",r); print r; exit + }' + ) + + asrc=$(pactl list sources | awk ' + /^Source #.*/ { + s=$2; sub("#","",s);} / *Description: Monitor of Built-in Audio Analog Stereo/ {print s; exit + }' + ) + + fout="${fout:-mpvc-cast-$(date -Isec | sed 's/:/-/g').mkv}" + loglevel=${loglevel:-warning} + framerate=${framerate:-25} + + if [ -z "$vres" ]; then usage; fi + if [ -z "$asrc" ]; then usage; fi + + echo "# $PROGNAME: recording vres $vres asrc $asrc to $fout (ctl+c to finish)" + ffmpeg -hide_banner -loglevel "$loglevel" -video_size "$vres" -framerate "$framerate" -f x11grab -i :0.0 -f pulse -ac 2 -i "$asrc" "$fout" +} usage() { echo "usage: $PROGNAME -[vdlLh] args # @version $PROGVERSION (c) $PROGAUTHOR $PROGURL" @@ -63,14 +93,13 @@ main() case "${1:-}" in -h|--help|help) usage ;; - -l|--lossy|lossy) operation="lossy" ;; - -L|--lossless|lossless) operation="lossless" ;; - -v|--vidcord|vidcord) operation="vidcord" ;; - -d|--default|default|'') operation="default" ;; + -l|--lossy|lossy) operation="lossy" mpvc_cut ;; + -L|--lossless|lossless) operation="lossless" mpvc_cut ;; + -v|--vidcord|vidcord) operation="vidcord" mpvc_cut ;; + -d|--default|default|'') operation="default" mpvc_cut ;; + cast) mpvc_screencast "$@" ;; *) usage ;; esac - - mpvc_cutfile "$operation" "$(mpvc g 'path')" "$(mpvc g 'ab-loop-a')" "$(mpvc g 'ab-loop-b')" } main "$@" diff --git a/extras/mpvc-equalizer b/extras/mpvc-equalizer index 9e35623b..68aec9c4 100755 --- a/extras/mpvc-equalizer +++ b/extras/mpvc-equalizer @@ -4,6 +4,7 @@ # @description mpvc equalizer based on firequalizer15.lua # @author gmt4 (c) Copyright 2022 GPLv2+ # @url github.com/gmt4/mpvc +# SPDX-License-Identifier: GPL-2.0-or-later # PROGNAME=${0##*/} @@ -12,23 +13,25 @@ PROGVERSION="v1.5" PROGAUTHOR=gmt4 PROGURL="https://github.com/gmt4/mpvc" -MPVC_LABEL="${MPVC_LABEL:-mpvc-equalizer}" - set -euf +MPVC_LABEL="${MPVC_LABEL:-mpvc-equalizer}" +MPVC_FREQ_TABLE="0 65 157 288 472 733 1k1 1k6 2k4 3k4 4k9 7k0 10k 14k 20k" +MPVC_GAIN_TABLE="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0" + mpvc() { "$PROGDIR/mpvc" "$@"; } # mpvc-web? mpvc_genfilter() { - awk -v quote="'" -v gain_curr="$*" \ + awk -v quote="'" -v gain_curr="$*" -v freq_table_str="MPVC_FREQ_TABLE" -v gain_table_str="$MPVC_GAIN_TABLE" \ ' BEGIN { num_entry=15 min_val = -360 max_val = 120 - n=split("0 65 157 288 472 733 1k1 1k6 2k4 3k4 4k9 7k0 10k 14k 20k", freq_table) - n=split("0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", gain_table) + n=split(freq_table_str, freq_table) + n=split(gain_table_str, gain_table) if (gain_curr) n=split(gain_curr, gain_table) } @@ -92,7 +95,7 @@ mpvc_presets() rock) echo "4.8 2.8 -3.4 -4.8 -2.0 2.4 5.3 6.7 6.7 6.7";; # preset: rock techno) echo "4.8 3.3 0.0 -3.4 -2.9 0.0 4.8 5.7 5.8 5.3";; # preset: techno - ''|help|list) awk '/# preset: / { print }' $0;; + ''|help|list) awk '/# preset: / { print }' "$0";; esac } @@ -101,7 +104,7 @@ mpvc_values() mpvc getr af | jq '.data | .[] | .params.graph' | grep -o "gain_entry = '.*':" | - sed -n 's/gain_entry = .//; s/.:$//; s|entry([0-9]\{1,2\},\([-.0-9]\+\));\?|\n\1 |gp' + sed -n 's/gain_entry = .//; s/.:$//; s|entry([0-9]\{1,2\},\([-.0-9]*\));*|\n\1 |gp' } mpvc_setvals() @@ -114,11 +117,12 @@ mpvc_bars() { mpvc_values="$(mpvc_values)" if [ -z "$mpvc_values" ]; then usage; fi - freq_table="0\n65\n157\n288\n472\n733\n1k1\n1k6\n2k4\n3k4\n4k9\n7k0\n10k\n14k\n20k\n" + freq_table="$MPVC_FREQ_TABLE" gain_table="$(printf "$mpvc_values" | sed '/^$/d')" - preset=$(awk /"$(echo "$gain_table" | awk 'NR<10{s=s""$0} END{print s}')"/' {print $NF}' $0) + preset=$(awk /"$(echo "$gain_table" | awk 'NR<10{s=s""$0} END{print s}')"/' {print $NF}' "$0") + gain_table=$(echo $gain_table) - awk -v freq="$freq_table" -v gain="$gain_table" -v cols=$(mpvc ttycols) -v preset=$preset ' + awk -v freq="$freq_table" -v gain="$gain_table" -v cols="$(mpvc ttycols)" -v preset="$preset" ' function mpvc_bar_line(val) { valf=val diff --git a/extras/mpvc-fzf b/extras/mpvc-fzf index dc870041..2a10b8a4 100755 --- a/extras/mpvc-fzf +++ b/extras/mpvc-fzf @@ -4,6 +4,7 @@ # @description mpvc fzf, mpv terminal user interface # @author gmt4 (c) Copyright 2022 GPLv2+ # @url github.com/gmt4/mpvc +# SPDX-License-Identifier: GPL-2.0-or-later # PROGNAME=${0##*/} @@ -44,6 +45,11 @@ mpvcfzf_config() fi } +mpvcfzf_getvideo_id() +{ + echo "${1##*/}" +} + mpvcfzf_isearch_once() { mpvcfzf_isearch "$@" | awk 'NR==2 {sub(" +", " # "); print}' @@ -84,9 +90,47 @@ mpvcfzf_isearch() ' } +mpvcfzf_ssearch() +{ + id=${1:-$(mpvc get filename)} + id=$(mpvcfzf_getvideo_id "$id") + output=$(curl -fsSL -A '' "https://yewtu.be/watch?v=$id") + echo "$output" | + awk ' + /
    / { c++; next } + c && c-- { + sub("^ *

    "," "); + sub("

    $",""); + print $0 + }' +} + +mpvcfzf_splay() +{ + mpvcfzf_ssearch "$1" | + mpvcfzf_preview --prompt="(similar) " | + mpvcfzf_awk1 +} + +mpvcfzf_lyrics() +{ + id=${1:-$(mpvc get filename)} + id=$(mpvcfzf_getvideo_id "$id") + output=$(curl -fsSL -A '' "https://yewtu.be/watch?v=$id") + echo "$output" | + awk -v id=$id ' + c==0 && / (c) Copyright 2022 GPLv2+ # @url github.com/gmt4/mpvc +# SPDX-License-Identifier: GPL-2.0-or-later # PROGNAME=${0##*/} @@ -141,19 +142,26 @@ mpvc_check_update() fi } +mpvc_version() +{ + echo "usage: $PROGNAME args # @version $PROGVERSION (c) $PROGAUTHOR $PROGURL" +} + usage() { echo "usage: $PROGNAME args # @version $PROGVERSION (c) $PROGAUTHOR $PROGURL" echo " check-update : Check for updates" echo " check-reqs : Check for required packages" echo " config : Fetch mpv config" + echo " config-user : Fetch mpv config to BINDIR=$HOME/bin" + echo " config-sys : Fetch mpv config to BINDIR=$PREFIX/bin" echo " fetch-user : Fetch to BINDIR=$HOME/bin" echo " link-user : Symlink to BINDIR=$HOME/bin" echo " install-user : Install to BINDIR=$HOME/bin" echo " install-sys : Install to BINDIR=$PREFIX/bin" echo " uninstall-sys : Uninstall from BINDIR=$PREFIX/bin" echo " uninstall-user : Uninstall from BINDIR=$HOME/bin}" - echo "*tips: If unsure where to start, start with: $PROGNAME link-user" + echo "*tips: If unsure where to start, start with: $PROGNAME fetch-user" exit } @@ -165,9 +173,9 @@ main() case "$SHELL" in *'zsh') SHELL="/bin/sh";; esac case "$1" in + version) shift; mpvc_version;; check-reqs) shift; mpvc_check_requirements;; check-update) shift; mpvc_check_update;; - config) shift; mpvc_config "$@";; docs) shift; mpvc_docs "$@";; licenses) shift; mpvc_licenses "$@";; fetch) shift; mpvc_fetch "$@";; @@ -175,7 +183,9 @@ main() install) shift; mpvc_install "$@";; uninstall) shift; mpvc_uninstall "$@";; - fetch-config) shift; PREFIX=$HOME $SHELL "$0" config;; + config) shift; mpvc_config "$@";; + config-user) shift; PREFIX=$HOME $SHELL "$0" config;; + config-sys) shift; PREFIX=/usr/local $SHELL "$0" config;; fetch-user) shift; PREFIX=$HOME $SHELL "$0" fetch;; fetch-sys) shift; PREFIX=/usr/local $SHELL "$0" fetch;; diff --git a/extras/mpvc-mpris b/extras/mpvc-mpris index 18fd469a..c2d25665 100755 --- a/extras/mpvc-mpris +++ b/extras/mpvc-mpris @@ -4,6 +4,7 @@ # @description mpvc-mpris speaks MPRIS to control mplayer through key-bindings # @author gmt4 (c) Copyright 2022 GPLv2+ # @url github.com/gmt4/mpvc +# SPDX-License-Identifier: GPL-2.0-or-later # PROGNAME=${0##*/} diff --git a/extras/mpvc-now b/extras/mpvc-now index 4b78af57..222a8983 100755 --- a/extras/mpvc-now +++ b/extras/mpvc-now @@ -4,6 +4,7 @@ # @description mpvc-now get a shareable URL to the "now listening" playlist # @author gmt4 (c) Copyright 2024 GPLv2+ # @url github.com/gmt4/mpvc +# SPDX-License-Identifier: GPL-2.0-or-later # PROGNAME=${0##*/} diff --git a/extras/mpvc-tui b/extras/mpvc-tui index 3b207649..564922fa 100755 --- a/extras/mpvc-tui +++ b/extras/mpvc-tui @@ -4,6 +4,7 @@ # @description mpvc tui, mpv terminal user interface # @author gmt4 (c) Copyright 2022 GPLv2+ # @url github.com/gmt4/mpvc +# SPDX-License-Identifier: GPL-2.0-or-later # PROGNAME=${0##*/} @@ -268,7 +269,7 @@ mpvctui_notify() if (do_print) print tn, $0, "notify" } - /playback-restart|metadata-update/ { + /playback-restartproperty-change||metadata-update/ { t=systime() if (t - ot > 1) system(cmd_scrobble); @@ -328,7 +329,7 @@ mpvctui_usage() exit; } -optflags="d:hHktTm:nsSP:u:x" +optflags="d:hHktTm:nNsSP:u:x" mpvctui_main() { mpvctui_config @@ -349,6 +350,7 @@ mpvctui_main() ;; m) shift; mpvctui_mouse "$OPTARG" ;; n) shift; mpvctui_notify_loop "${1:-}" ;; + N) shift; mpvctui_notify "${@}" ;; k) shift; pkill -f "$PROGNAME" ;; s) shift; mpvctui_suggest ;; S) shift; mpvctui_notify_loop_cli "${1:-}" ;; diff --git a/extras/mpvc-web b/extras/mpvc-web index 5337bc63..f949d589 100755 --- a/extras/mpvc-web +++ b/extras/mpvc-web @@ -4,6 +4,7 @@ # @description mpvc web, A hack to remotely control mpvc from web/http # @author gmt4 (c) Copyright 2022 GPLv2+ # @url github.com/gmt4/mpvc +# SPDX-License-Identifier: GPL-2.0-or-later # # REMEMBER This is a hack, DISCLAIMER * Use at Your Own Risk * @@ -14,6 +15,7 @@ # like a laptop, tablet, or phone. PROGNAME=${0##*/} +PROGDIR=${0%/*} PROGVERSION="v1.5" PROGAUTHOR=gmt4 PROGURL="https://github.com/gmt4/mpvc" @@ -28,10 +30,10 @@ mpvc_web_defaults() XDG_CONFIG_HOME=${XDG_CONFIG_HOME:-"$HOME/.config"} MPVC_CONFIG="${MPVC_CONFIG:-$XDG_CONFIG_HOME/mpvc/mpvc.conf}" + MPVC_WEB_HOSTNAME=${MPVC_WEB_HOSTNAME:-$(hostname)} MPVC_WEB_HOST=${MPVC_WEB_HOST:-localhost} MPVC_WEB_PORT=${MPVC_WEB_PORT:-8000} MPVC_WEB_ROOT=${MPVC_WEB_ROOT:-/tmp/mpvc-web/root} - MPVC_WEB_HOSTNAME=$(hostname) MPVC_WEB_SSL_PORT=${MPVC_WEB_SSL_PORT:-8443} MPVC_WEB_SSL_PEM=${MPVC_WEB_SSL_PEM:-$MPVC_WEB_ROOT/../stunnel.pem} MPVC_WEB_SSL_CFG=${MPVC_WEB_SSL_CFG:-$MPVC_WEB_ROOT/../stunnel.cfg} @@ -39,7 +41,9 @@ mpvc_web_defaults() MPVC_WEB_SSL_ENABLE=${MPVC_WEB_SSL_ENABLE:-} MPVC_WEB_SSL_VERIFY=${MPVC_WEB_SSL_VERIFY:-0} MPVC_WEB_ARCHIVE_ENABLE=${MPVC_WEB_ARCHIVE_ENABLE:-} + MPVC_WEB_CAST_URL=${MPVC_WEB_CAST_URL:-} MPVC_WEB_HTML_THEME=${MPVC_WEB_HTML_THEME:-} + MPVC_WEB_HTML_REFRESH=${MPVC_WEB_HTML_REFRESH:-} # accesskey keyboard shortcuts MPVC_WEB_SHORTCUT_REFRESH=${MPVC_WEB_SHORTCUT_REFRESH:-accesskey=m} @@ -55,6 +59,7 @@ mpvc_web_defaults() MPVC_WEB_SHORTCUT_EQUALIZER=${MPVC_WEB_SHORTCUT_EQUALIZER:-accesskey=e} MPVC_WEB_SHORTCUT_ARCHIVE=${MPVC_WEB_SHORTCUT_ARCHIVE:-accesskey=f} MPVC_WEB_SHORTCUT_MUTE=${MPVC_WEB_SHORTCUT_MUTE:-accesskey=g} + MPVC_WEB_SHORTCUT_YTSEARCH=${MPVC_WEB_SHORTCUT_YTSEARCH:-accesskey=y} MPVC_WEB_SHORTCUT_HELP=${MPVC_WEB_SHORTCUT_HELP:-accesskey=h} MPVC_CGI="$MPVC_WEB_ROOT/cgi-bin/mpvc" @@ -67,14 +72,14 @@ mpvc_web_defaults() mpvc_web_config() { - if ! command -v python3 >/dev/null; then - echo "$PROGNAME: Error: No python3 found, install to continue." - exit - fi if ! command -v mpvc >/dev/null; then echo "$PROGNAME: Error: No mpvc found, install to continue." exit fi + if ! command -v python3 >/dev/null; then + echo "$PROGNAME: Error: No python3 found, install to continue." + exit + fi if ! command -v stunnel >/dev/null; then echo "$PROGNAME: Warning: No stunnel found, install to support SSL." fi @@ -91,15 +96,145 @@ mpvc_web_select_form() arg="${2:-}" echo "
    " - echo "$cmd" - awk -v cmd="$cmd" -v arg="$arg" ' - BEGIN { print ""} + echo "" + echo "' echo '
    ' } +mpvc_web_cli() +{ +cat < + + +
    +
    + +
    +EOF +} + +mpvc_web_index_js() +{ + cat <= 0; i--) + { + rule = document.styleSheets[0].rules[i] + if (!("media" in rule)) + continue; + rule = document.styleSheets[0].rules[i].media; + if (! rule.mediaText.includes("prefers-color-scheme")) + continue; + switch (mode) { + case "light": + rule.appendMedium("original-prefers-color-scheme"); + if (rule.mediaText.includes("light")) rule.deleteMedium("(prefers-color-scheme: light)"); + if (rule.mediaText.includes("dark")) rule.deleteMedium("(prefers-color-scheme: dark)"); + break; + case "dark": + rule.appendMedium("(prefers-color-scheme: light)"); + rule.appendMedium("(prefers-color-scheme: dark)"); + if (rule.mediaText.includes("original")) rule.deleteMedium("original-prefers-color-scheme"); + break; + default: + rule.appendMedium("(prefers-color-scheme: dark)"); + if (rule.mediaText.includes("light")) rule.deleteMedium("(prefers-color-scheme: light)"); + if (rule.mediaText.includes("original")) rule.deleteMedium("original-prefers-color-scheme"); + } + break; + } +} + +function mpvcOnKeyDownEvent(event, that) +{ + if (event.keyCode == 13) + { + if (! that.value.startsWith('http')) + { + var datalist=document.getElementById('mpvc-yts-datalist') + var url='/cgi-bin/mpvc?mpvc-fzf+-s+'+that.value; + data=mpvcHttpGet(url); + + lines=data.split('\n'); + for (i in lines) + { + var option = '

    - $PROGNAME $(mpvc-installer check-update | awk -v progurl=$PROGURL '{ print ""$NF""; }') mpvc-tui for the web + $PROGNAME + $PROGVERSION + @$PROGAUTHOR (c) 2024 /h + #top EOF } -mpvc_web_index_js() -{ - cat <= 0; i--) - { - rule = document.styleSheets[0].rules[i] - if (!("media" in rule)) - continue; - rule = document.styleSheets[0].rules[i].media; - if (! rule.mediaText.includes("prefers-color-scheme")) - continue; - switch (mode) { - case "light": - rule.appendMedium("original-prefers-color-scheme"); - if (rule.mediaText.includes("light")) rule.deleteMedium("(prefers-color-scheme: light)"); - if (rule.mediaText.includes("dark")) rule.deleteMedium("(prefers-color-scheme: dark)"); - break; - case "dark": - rule.appendMedium("(prefers-color-scheme: light)"); - rule.appendMedium("(prefers-color-scheme: dark)"); - if (rule.mediaText.includes("original")) rule.deleteMedium("original-prefers-color-scheme"); - break; - default: - rule.appendMedium("(prefers-color-scheme: dark)"); - if (rule.mediaText.includes("light")) rule.deleteMedium("(prefers-color-scheme: light)"); - if (rule.mediaText.includes("original")) rule.deleteMedium("original-prefers-color-scheme"); - } - break; - } -} -EOF -} - -mpvc_web_cgi() -{ - cat < ๐ŸŽง cat < ๐ŸŽง EOF } @@ -392,11 +469,12 @@ cert = ${MPVC_WEB_SSL_PEM} key = ${MPVC_WEB_SSL_PEM} cafile = ${MPVC_WEB_SSL_PEM} verify=$MPVC_WEB_SSL_VERIFY +#protocol = proxy TIMEOUTclose = 0 EOF } -mpvc_web() +mpvc_web_setup() { mpvc_web_config echo "# $PROGNAME $PROGVERSION running (beta version: might contain bugs!) SSL=${MPVC_WEB_SSL_ENABLE}" @@ -406,8 +484,9 @@ mpvc_web() echo "# $PROGNAME Setup $MPVC_WEB_ROOT" mkdir -p "$MPVC_WEB_ROOT" || return mkdir -p "$MPVC_WEB_ROOT/cgi-bin/" || return + mkdir -p "$MPVC_WEB_ROOT/extras/" || return cd "$MPVC_WEB_ROOT" || return - chmod u+w -R "${MPVC_WEB_ROOT%/*}" + chmod -R u+w "${MPVC_WEB_ROOT%/*}" # setup streamable mpvc archive if requested if [ -n "${MPVC_WEB_ARCHIVE_ENABLE}" ]; then @@ -443,53 +522,63 @@ mpvc_web() echo "# $PROGNAME Setup development/cli features (MPVC_WEB_DEV=${MPVC_WEB_DEV:-} is not set)" fi - chmod a-w -R "$MPVC_WEB_ROOT/" + chmod -R a-w "$MPVC_WEB_ROOT/" + ) +} + +mpvc_web() +{ + mpvc_web_setup + ( + cd "$MPVC_WEB_ROOT" || return # XXX handle cli commands, rewrite this mess python3 -u -m http.server --cgi --bind "$MPVC_WEB_HOST" "$MPVC_WEB_PORT" "$@" 2>&1 | awk -v mpvc="$MPVC_CGI" \ ' - /GET \/\?cmd=mpvc%20mpv/ { system(mpvc" -q mpv") } - /GET \/\?cmd=mpvc%20clear/ { system(mpvc" -q clear") } - /GET \/\?cmd=mpvc%20kill/ { system(mpvc" -q kill") } - /GET \/\?cmd=mpvc%20vol%20-5/ { system(mpvc" -q vol -5") } - /GET \/\?cmd=mpvc%20vol%20\+5/ { system(mpvc" -q vol +5") } - - /GET \/\?cmd=mpvc%20--mute/ { system(mpvc" -q --mute") } - /GET \/\?cmd=mpvc%20toggle/ { system(mpvc" -q toggle") } - /GET \/\?cmd=mpvc%20play/ { system(mpvc" -q play") } - /GET \/\?cmd=mpvc%20start%200/ { system(mpvc" -q start 0") } - /GET \/\?cmd=mpvc%20start%20$/ { system(mpvc" -q start $") } - /GET \/\?cmd=mpvc%20stop/ { system(mpvc" -q stop") } - /GET \/\?cmd=mpvc%20prev/ { system(mpvc" -q prev") } - /GET \/\?cmd=mpvc%20next/ { system(mpvc" -q next") } - /GET \/\?cmd=mpvc%20playrand/ { system(mpvc" -q playrand") } - - /GET \/\?cmd=mpvc%20shuffle/ { system(mpvc" -q shuffle") } - /GET \/\?cmd=mpvc%20unshuffle/ { system(mpvc" -q unshuffle") } - - /GET \/\?cmd=mpvc%20repeat/ { system(mpvc" -q repeat") } - /GET \/\?cmd=mpvc%20single/ { system(mpvc" -q single") } - /GET \/\?cmd=mpvc%20replay/ { system(mpvc" -q replay") } - - /GET \/\?cmd=mpvc%20togglev/ { system(mpvc" -q togglev") } - /GET \/\?cmd=mpvc%20aspect/ { system(mpvc" -q aspect") } - /GET \/\?cmd=mpvc%20togglew/ { system(mpvc" -q togglew") } - /GET \/\?cmd=mpvc%20togglef/ { system(mpvc" -q togglef") } - /GET \/\?cmd=mpvc%20togglei/ { system(mpvc" -q togglei") } - - /GET \/\?cmd=mpvc%20cstart/ { system(mpvc" -q cplay 0") } - /GET \/\?cmd=mpvc%20creplay/ { system(mpvc" -q chapter-replay") } - /GET \/\?cmd=mpvc%20cloop/ { system(mpvc" -q chapter-loop") } - /GET \/\?cmd=mpvc%20cprev/ { system(mpvc" -q chapter-prev") } - /GET \/\?cmd=mpvc%20cnext/ { system(mpvc" -q chapter-next") } - /GET \/\?cmd=mpvc%20cplayrand/ { system(mpvc" -q cplayrand") } + BEGIN { quiet=1 } + + /GET \/\?cmd=mpvc%20mpv/ { system(mpvc" mpvc -q mpv") } + /GET \/\?cmd=mpvc%20clear/ { system(mpvc" mpvc -q clear") } + /GET \/\?cmd=mpvc%20kill/ { system(mpvc" mpvc -q kill") } + /GET \/\?cmd=mpvc%20vol%20-5/ { system(mpvc" mpvc -q vol -5") } + /GET \/\?cmd=mpvc%20vol%20\+5/ { system(mpvc" mpvc -q vol +5") } + + /GET \/\?cmd=mpvc%20--mute/ { system(mpvc" mpvc -q --mute") } + /GET \/\?cmd=mpvc%20toggle/ { system(mpvc" mpvc -q toggle") } + /GET \/\?cmd=mpvc%20play/ { system(mpvc" mpvc -q play") } + /GET \/\?cmd=mpvc%20start%200/ { system(mpvc" mpvc -q start 0") } + /GET \/\?cmd=mpvc%20start%20$/ { system(mpvc" mpvc -q start $") } + /GET \/\?cmd=mpvc%20stop/ { system(mpvc" mpvc -q stop") } + /GET \/\?cmd=mpvc%20prev/ { system(mpvc" mpvc -q prev") } + /GET \/\?cmd=mpvc%20next/ { system(mpvc" mpvc -q next") } + /GET \/\?cmd=mpvc%20playrand/ { system(mpvc" mpvc -q playrand") } + + /GET \/\?cmd=mpvc%20shuffle/ { system(mpvc" mpvc -q shuffle") } + /GET \/\?cmd=mpvc%20unshuffle/ { system(mpvc" mpvc -q unshuffle") } + + /GET \/\?cmd=mpvc%20repeat/ { system(mpvc" mpvc -q repeat") } + /GET \/\?cmd=mpvc%20single/ { system(mpvc" mpvc -q single") } + /GET \/\?cmd=mpvc%20replay/ { system(mpvc" mpvc -q replay") } + + /GET \/\?cmd=mpvc%20togglev/ { system(mpvc" mpvc -q togglev") } + /GET \/\?cmd=mpvc%20aspect/ { system(mpvc" mpvc -q aspect") } + /GET \/\?cmd=mpvc%20togglew/ { system(mpvc" mpvc -q togglew") } + /GET \/\?cmd=mpvc%20togglef/ { system(mpvc" mpvc -q togglef") } + /GET \/\?cmd=mpvc%20togglei/ { system(mpvc" mpvc -q togglei") } + + /GET \/\?cmd=mpvc%20cstart/ { system(mpvc" mpvc -q cplay 0") } + /GET \/\?cmd=mpvc%20creplay/ { system(mpvc" mpvc -q chapter-replay") } + /GET \/\?cmd=mpvc%20cloop/ { system(mpvc" mpvc -q chapter-loop") } + /GET \/\?cmd=mpvc%20cprev/ { system(mpvc" mpvc -q chapter-prev") } + /GET \/\?cmd=mpvc%20cnext/ { system(mpvc" mpvc -q chapter-next") } + /GET \/\?cmd=mpvc%20cplayrand/ { system(mpvc" mpvc -q cplayrand") } /GET \/\?cli=mpvc/ { r=$0; gsub("HTTP.*$", "", r); - gsub("^.*GET \\/\\?cli=mpvc\\+", mpvc" ", r); - gsub("^.*GET \\/\\?cli=mpvc-", mpvc" ", r); + gsub("^.*GET \\/\\?cli=(mpvc-)", mpvc" mpvc-", r); + gsub("^.*GET \\/\\?cli=(mpvc)\\+", mpvc" mpvc ", r); if (ENVIRON["MPVC_WEB_DEV"] && match(r, "^"mpvc)) { @@ -498,8 +587,8 @@ mpvc_web() gsub("%22", "\"", r); gsub("%2B", "+", r); gsub("%23", "#", r); - gsub("%2F", "/",r); - gsub("%3A", ":",r); + gsub("%2F", "/", r); + gsub("%3A", ":", r); #print(r); system(r); # XXX @@ -511,7 +600,7 @@ mpvc_web() ) } -optflags="ha:b:c:d:p:P:r:s:S:t:" +optflags="ha:b:c:C:d:p:P:r:R:s:S:t:" usage() { echo "usage: $PROGNAME -[$optflags] args # @version $PROGVERSION (c) $PROGAUTHOR $PROGURL" @@ -519,6 +608,7 @@ usage() echo " -b : Set $PROGNAME HTTP server bind address (default $MPVC_WEB_HOST)" echo " -p : Set $PROGNAME HTTP server port (default $MPVC_WEB_PORT)" echo " -r : Set $PROGNAME HTTP server root dir (default $MPVC_WEB_ROOT)" + echo " -R : Set $PROGNAME HTTP server HTML refresh (default $MPVC_WEB_HTML_REFRESH)" echo " -s : Set $PROGNAME HTTP server SSL/TLS (default $MPVC_WEB_SSL_ENABLE)" echo " -a : Set $PROGNAME HTTP server to include ytdl-archive/ (default $MPVC_WEB_ARCHIVE_ENABLE)" echo "*tips: If unsure where to begin, run: $PROGNAME -p 8000 -c start # serves @ http://localhost:8000" @@ -536,11 +626,13 @@ main() case "$flag" in h) usage ;; c) MPVC_WEB_CMD="$OPTARG"; ;; + C) MPVC_WEB_CAST_URL="$OPTARG"; ;; d) MPVC_WEB_DEV="$OPTARG"; ;; b) MPVC_WEB_HOST="$OPTARG" ;; p) MPVC_WEB_PORT="$OPTARG" ;; P) MPVC_WEB_SSL_PORT="$OPTARG" ;; r) MPVC_WEB_ROOT="$OPTARG" ;; + R) MPVC_WEB_HTML_REFRESH="$OPTARG" ;; s) MPVC_WEB_SSL_ENABLE="$OPTARG" ;; S) MPVC_WEB_SSL_PEM="$OPTARG" ;; t) MPVC_WEB_HTML_THEME="$OPTARG" ;; @@ -551,9 +643,9 @@ main() shift $((OPTIND - 1)) case "${MPVC_WEB_CMD:-}" in + status) ps auxww | grep "$PROGNAME" ;; start) mpvc_web ;; stop) pkill -f "$PROGNAME" ;; - status) ps auxww | grep 'mpvc-web' ;; *) usage ;; esac } diff --git a/extras/win32/socat.bat b/extras/win32/socat.bat index 7a865da8..a5dd2162 100644 --- a/extras/win32/socat.bat +++ b/extras/win32/socat.bat @@ -3,6 +3,7 @@ :: @description mimic socat over win32 named pipe for mpvc :: @author gmt4 (c) Copyright 2022 GPLv2+ :: @url github.com/gmt4/mpvc +:: SPDX-License-Identifier: GPL-2.0-or-later :: @echo off diff --git a/extras/win32/socat.ps1 b/extras/win32/socat.ps1 index 3f5e23ab..085831dd 100644 --- a/extras/win32/socat.ps1 +++ b/extras/win32/socat.ps1 @@ -3,6 +3,7 @@ # @description mimic socat over win32 named pipe for mpvc # @author gmt4 (c) Copyright 2022 GPLv2+ # @url github.com/gmt4/mpvc +# SPDX-License-Identifier: GPL-2.0-or-later # # Disclaimer: this is a kludge written because I could not find any other tool that did the job. diff --git a/mpvc b/mpvc index 6ef18d0c..1ade46aa 100755 --- a/mpvc +++ b/mpvc @@ -83,6 +83,7 @@ EOF -R | --searchrm : Search the playlist and remove matching entries. -M | --searchmv : Search the playlist and move matching entries. stash : Manage mpv playing state as in git-stash(1) + wait : Wait until MPV setups $PROGNAME socket (timeout after 10s) delay : Sleep delay, as in: $PROGNAME play 0 delay seek 20% vol 60 (--)?expand-text : Expand text as documented in mpv(1) Property Expansion @@ -105,11 +106,12 @@ Formatting: %name%, %path%, %dir%, %title%, %artist%, %album%, %albumartist%, comment%, %genre%, %year%, %percentage%, %playlistlength%, %position%, %repeat%, %single, %status%, %time%, %precisetime%, %speed%, %length%, %remaining%, - %volume%, %muted%, %frame%, %width%, %height%, %ab-loop-a%, %ab-loop-b% - %video%, %aspect%, %force-window%, %fullscreen%, %idle%, %chapter%, %chapters% + %volume%, %muted%, %frame%, %width%, %height%, %ab-loop-a%, %ab-loop-b%, + %video%, %screen%, %aspect%, %force-window%, %fullscreen%, %idle%, + %chapter%, %chapters% MPC compatibility layer: - mpvc features a nearly complete compatibility layer for mpc commands in + mpvc features nearly complete compatibility for mpc(1) commands, in addition to GNU style arguments. https://linux.die.net/man/1/mpc Exit codes: @@ -162,9 +164,9 @@ mpvc_defaults() FORMATSTRING="\ %artist% - %title% \r\ [%status%] #%position%/%playlistlength% %time%/%length% (%percentage%%%) \r\ -speed:%speed%x vol:%volume%%% mute:%muted% repeat:%repeat% single:%single% \r\ -video:%video% aspect:%aspect% win:%force-window% fs:%fullscreen% idle:%idle% \r\ -chapter:%chapter% %=chapter%/%chapters%" +vol:%volume%%% mute:%muted% repeat:%repeat% single:%single% \r\ +vid:%video% scr:%screen% win:%force-window% fs:%fullscreen% \r\ +chapter:%chapter% %=chapter%/%chapters% idle:%idle%" fi } @@ -216,13 +218,6 @@ mpvc_curl_cache_json() mpvc_curl_cache -sL "https://youtube.com/oembed?url=$1" } -mpvc_curl_cache_metadata_json() { - for i in "$@" - do - mpvc_curl_cache_metadata_json_once "$i" - done -} - mpvc_curl_cache_metadata_json_once() { filename="${1:-}" result="${1:-}" @@ -249,6 +244,10 @@ mpvc_curl_cache_metadata_json_once() { printf "$result\n" } +mpvc_curl_cache_metadata_json() { + for i in "$@"; do mpvc_curl_cache_metadata_json_once "$i"; done +} + # fn args: given a file/url return its title (may use curl to query YT) mpvc_curl_cache_title_clean() { mpvc_curl_cache_metadata_json "$@" | mpvc_getjson 'title' @@ -263,12 +262,8 @@ mpvc_sockcmd_() { echo "$@" | mpvc_sockrepl; } mpvc_sockcmd() { oquiet mpvc_sockcmd_ "$@"; } mpvc_socklist() { for f in $(find "$MPVC_CONFIG_DIR" -type s); do - idle=$(MPVC_SOCKET=$f mpvc_get idle-active) - if [ -z "$idle" ]; then - echo "$f: active=no" - else - echo "$f: active=yes idle=$idle" - fi + idle_active=$(MPVC_SOCKET=$f mpvc_get idle-active) + echo "$f: idle-active=${idle_active:-}" done } @@ -293,7 +288,7 @@ mpvc_setr() { mpvc_ecmdr "set_property" "$@"; } mpvc_get_pause_status() { case "$(mpvc_get pause)" in - yes) echo "paused";; no) echo "playing" ;; *) echo "NA";; + yes) echo "paused";; no) echo "play" ;; *) echo "NA";; esac } @@ -306,7 +301,7 @@ mpvc_get_playlist_json() { mpvc_get_playlist_once() { mpvc_get_playlist_json | - sed 's|,"current":true||; s|,"playing":true||; s|,"id":[0-9]\+||; s|{"filename":"\(.*\)"}|\1|; s|","title":.*||; s/,$//; /^\[$/d; /\]$/d' | + sed 's|,"current":true||; s|,"playing":true||; s|,"id":[0-9]*||; s|{"filename":"\(.*\)"}|\1|; s|","title":.*||; s/,$//; /^\[$/d; /\]$/d' | awk -v numbered="${1:-}" ' { gsub("^[ \t]*", " ") @@ -475,8 +470,8 @@ mpvc_stash() { fi ;; edit|ed) ${EDITOR:-vi} "$MPVC_STASH_DIR/$1" ;; - drop) rm -i "$MPVC_STASH_DIR/$1" ;; - push) + drop|rm) rm -i "$MPVC_STASH_DIR/$1" ;; + push|cp) stashid="${1:-}" if [ -z "$stashid" ]; then stashid="${1:-stash-$(date -Imin)}" @@ -488,7 +483,7 @@ mpvc_stash() { fi mpvc_stash current "$stashid" > "$MPVC_STASH_DIR/$stashid" ;; - apply) # if no stash given, default to stdin + apply|do) # if no stash given, default to stdin stashid="${1:-}" if [ -z "$stashid" ]; then mpvc_stash apply_current @@ -534,6 +529,7 @@ mpvc_stash() { echo "mpvc set volume-max $(mpvc_get volume-max)" echo "mpvc set video-zoom $(mpvc_get video-zoom)" echo "mpvc set video $(mpvc_get video)" + echo "mpvc set screen $(mpvc_get screen)" echo "mpvc wait" echo "mpvc set playback-time $(mpvc_get playback-time)" echo "mpvc set pause $(mpvc_get pause)" @@ -571,7 +567,8 @@ mpvc_appendtrack() { filename="$*" # require absolute paths case "$filename" in - /*) ;; *) if [ -e "$filename" ]; then filename="$(pwd)/$filename"; fi ;; + /*) if [ ! -e "$filename" ]; then warn "Warning: ${filename##*/} not found."; fi ;; + *) if [ -e "$filename" ]; then filename="$(pwd)/$filename"; fi ;; esac # skip over various other filetypes and images unless wanted case "$filename" in @@ -862,7 +859,7 @@ mpvc_print_status() { F=$(echo "$FORMATSTRING" | awk -v status=$(mpvc_get_pause_status) ' { - split("year genre album comment volume path height width playback-time ab-loop-[ab] speed force-window video aspect idle fullscreen chapter chapters =chapter", RE) + split("year genre album comment volume path height width playback-time ab-loop-[ab] speed force-window video screen aspect idle fullscreen chapter chapters =chapter", RE) for (i in RE) { re=RE[i]; gsub("%"re"%", "${"re":NA}"); } gsub("%title%", "${media-title}") @@ -888,7 +885,7 @@ mpvc_print_status() { } ' ) - mpvc_cmd "expand-text" "${F}" | sed 's/ \\r/\n/g' + mpvc_cmd "expand-text" "${F}" | awk '{gsub(" \\\\r","\n");print}' } mpvc_print_status_final() { @@ -906,8 +903,8 @@ isInt() { printf '%d' "$1" >/dev/null 2>&1 && [ -n "$1" ]; } mpvc_tty_size() { # this is convoluted as mpvc is run as cgi by mpvc-web without an actual tty - ttydev="${ttydev:-$(if tty -s; then tty; else ps -hp $$ -o tty | sed 's|^|/dev/|'; fi)}" - ttysize=${ttysize:-$(equiet stty -F "$ttydev" size || equiet stty -f "$ttydev" size || stty)} + ttydev="${ttydev:-$(if tty -s; then tty; else ps -hp $$ -o tty | awk '{sub("^","/dev/");gsub(" ","");l=$0} END{print l}'; fi)}" + ttysize=${ttysize:-$(equiet stty -F "$ttydev" size || equiet stty -f "$ttydev" size || equiet stty size || stty)} echo "$ttysize" } @@ -1002,7 +999,7 @@ mpvc_idle() { mpvc_observe_property "$1" | awk "/$1/ { print; exit }"; } mpvc_observe_property() { q='' mpvc_cmdr_ '"observe_property_string"' 1 "\"$1\"" | mpvc_idleloop; } mpvc_delay() { sleep "${1:-0.1}"; } -mpvc_wait() { until [ -n "$(mpvc_get idle-active)" ]; do mpvc_delay "${1:-}"; done; } +mpvc_wait() { for i in $(seq 0 100); do mpvc_delay "${1:-}"; [ -n "$(mpvc_get idle-active)" ] && break; done; } mpvc_mpv() { mpvc_startmpv --really-quiet --idle=once; } # mpvc_mpv: exec & wait until mpv starts up mpvc_startmpv() { @@ -1020,7 +1017,7 @@ main() { mpvc_config arg1=${1:-} case "$arg1" in - ytquery|ytqueryjson) ;; + ytquery|ytqueryjson|--tac|tac) ;; -k|--kill|kill|-K|--killall|killall) ;; -c|--crop|crop|-C|--clear|clear|cmd|sockcmd|socklist|--socklist) ;; -a|add|append|-A|playnext|--playnext|-n|playnow|--playnow|mpv|--mpv|stash|--stash|--toggle|toggle|-q|--quiet) ;; @@ -1099,6 +1096,7 @@ main() { --togglev|togglev) shift; mpvc_cycle "video" ;; --togglew|togglew) shift; mpvc_cycle "force-window" ;; --togglei|togglei) shift; mpvc_cycle "idle" ;; + --togglef|togglef) shift; mpvc_cycle "fullscreen" ;; --idle|idle) shift; mpvc_idle "${1:-}"; QUIETFLAG=true ;; --idleloop|idleloop) shift; mpvc_idleloop "${1:-}"; QUIETFLAG=true ;; --observe|observe) shift; mpvc_observe_property "${1:-}"; QUIETFLAG=true ;; @@ -1156,6 +1154,7 @@ main() { -C|--clear|clear) mpvc_clear_playlist; QUIETFLAG=true;; --delay|delay) mpvc_delay;; --wait|wait) mpvc_wait;; + --tac|tac) mpvc_tac; exit 0;; --ttysize|ttysize) mpvc_tty_size; QUIETFLAG=true;; --ttycols|ttycols) mpvc_tty_cols; QUIETFLAG=true;;