From 33e3132386c319fdd83012e49f8e17256a25776d Mon Sep 17 00:00:00 2001 From: aboutdavid <62346025+aboutdavid@users.noreply.github.com> Date: Thu, 28 Mar 2024 23:04:41 -0400 Subject: [PATCH] Improve mpv launching + make /stop work --- README.md | 9 ++- browser.js | 24 ++----- mpvc-installer | 192 +++++++++++++++++++++++++++++++++++++++++++++++++ stream.js | 13 +++- 4 files changed, 218 insertions(+), 20 deletions(-) create mode 100644 mpvc-installer diff --git a/README.md b/README.md index 0d78098..7f0ec32 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Orpheaux is very much in alpha. It also has only been tested on Fedora 39 Deskto - bun - node.js - mpv +- mpvc - an icecast2 server ## Get started @@ -32,4 +33,10 @@ node stream # Start the slack bot (won't work in bun) node index -``` \ No newline at end of file +``` + +## Structure +- `stream.js` - Streams music to the icecast server. +- `index.js` - Slack bot which controls the icecast server. +- `browser.js` - Connect to slack and plays music. +- `pipewire.js` - Called by `browser.js` to link `mpv` and Slack together. \ No newline at end of file diff --git a/browser.js b/browser.js index 14c0bb7..52f1e8a 100644 --- a/browser.js +++ b/browser.js @@ -35,26 +35,16 @@ console.log("[browser] [Info] Joining huddle.") await page2.click(`button[data-qa="huddle_from_link_speed_bump_modal_go"]`) - async function mpvSpawn() { - const mpv = spawn('mpv', [config.icecast.url], { + + try { + spawn('bun', ['pipewire.js'], { detached: true - }) - try { - spawn('bun', ['pipewire.js'], { - detached: true - }); - } catch (e) { - console.error("[browser] [Warn] Linking to pipewire has not worked. This usually happens because it has already been linked.") - console.error(e) - } - await fetch(`${config.api.base_url}/start?`) - - mpv.on('exit', async (code) => { - await mpvSpawn() }); + } catch (e) { + console.error("[browser] [Warn] Linking to pipewire has not worked. This usually happens because it has already been linked.") + console.error(e) } - - await mpvSpawn() + await fetch(`${config.api.base_url}/start?`) })(); diff --git a/mpvc-installer b/mpvc-installer new file mode 100644 index 0000000..4edfd05 --- /dev/null +++ b/mpvc-installer @@ -0,0 +1,192 @@ +#!/bin/sh +# +# @file mpvc-installer +# @version v1.0 +# @description mpvc installer +# @author gmt4 (c) Copyright 2022 GPLv2+ +# @url github.com/gmt4/mpvc +# + +PROGNAME=${0##*/} +PROGVERSION="v1.5" +PROGAUTHOR=gmt4 +PROGURL="https://github.com/gmt4/mpvc" + +set -euf + +SHELL="${SHELL:-/bin/sh}" +PREFIX="${PREFIX:-/usr/local}" +BINDIR="${BINDIR:-$PREFIX/bin}" +DOCDIR="${DOCDIR:-$PREFIX/docs}" +LICDIR="${LICDIR:-$PREFIX/licenses}" + +MPV_CONFDIR="${CONFIGDIR:-$HOME/.config/mpv}" + +DOCS="README.md docs/mpv.conf docs/logbook.html" +LICENSES="LICENSE.md" +SCRIPT="mpvc extras/mpvc-tui extras/mpvc-fzf extras/mpvc-cut extras/mpvc-chapter extras/mpvc-mpris extras/mpvc-equalizer extras/mpvc-web extras/mpvc-autostart extras/mpvc-now extras/mpvc-installer" +CONFIG="docs/mpv.conf" + +mpvc_config() +{ + mkdir -p "$MPV_CONFDIR/scripts/" + echo "Fetching mpv.conf from $PROGURL" + for config in ${CONFIG}; + do + file="$MPV_CONFDIR/${config##*/}" + url="$PROGURL/raw/master/$config" + echo "Fetch $file" + if [ -e "$file" ]; then + echo "$PROGNAME: $file exists. Not overwriting." + else + curl -fsSL -o "$file" "$url" + fi + done + + for bin in "yt-dlp" + do + echo "Fetch $bin" + curl -fsSL -o "$BINDIR/$bin" "https://github.com/$bin/$bin/releases/latest/download/$bin" + chmod a+rx "$BINDIR/$bin" + done +} + +mpvc_fetch() +{ + mkdir -p "$BINDIR" + echo "Fetching mpvc from $PROGURL" + for script in $SCRIPT; + do + file="$BINDIR/${script##*/}" + url="$PROGURL/raw/master/$script" + echo "Fetch $file" + curl -fsSL -o "$file" "$url" + chmod u+x "$file" + done +} + +mpvc_docs() +{ + mkdir -p "$DOCDIR" + for doc in ${DOCS}; + do + install -Dvm640 "$(pwd)/$doc" "$DOCDIR"; + done +} + +mpvc_licenses() +{ + mkdir -p "$LICDIR" + for license in ${LICENSES}; + do + install -Dvm644 "$(pwd)/$license" "$LICDIR"; + done +} + +mpvc_link() +{ + mkdir -p "$BINDIR" + for script in $SCRIPT; + do + ln -svfn "$(pwd)/$script" "$BINDIR"; + done +} + +mpvc_install() +{ + echo 'Installing mpvc...' + mkdir -p "$BINDIR" + for script in $SCRIPT; + do + install -Dvm755 "$(pwd)/$script" "$BINDIR"; + done +} + +mpvc_uninstall() +{ + echo 'Un-installing mpvc...' + for script in $SCRIPT; + do + rm -v "$BINDIR/${script##*/}"; + done +} + +mpvc_check_requirements() +{ + # attempt at listing packages required by mpvc & extras/ to work + command -v "mpv" || echo "$PROGNAME: Error: No mpv found. Install to continue." + command -v "fzf" || echo "$PROGNAME: Error: No fzf found, Install to continue" + command -v "awk" || echo "$PROGNAME: Error: No awk found, Install to continue" # gawk ??? + command -v "sed" || echo "$PROGNAME: Error: No sed found, Install to continue" # gsed ??? + command -v "socat" || echo "$PROGNAME: Error: No socat found, Install to continue" + # recommened, and good to have, but not required + command -v "curl" || echo "$PROGNAME: Warning: No curl found, Install to search streaming services" + command -v "rlwrap" || echo "$PROGNAME: Warning: No rlwrap, Install to get history, filename & completion support!" + command -v "notify-send" || echo "$PROGNAME: Warning: No notify-send, Install to get mpv desktop notifications" + command -v "jq" || echo "$PROGNAME: Warning: No jq found, Install to parse JSON" + command -v "yt-dlp" || echo "$PROGNAME: Warning: No yt-dlp, Install to get youtube-dl support (*hint: check $PROGNAME config)" +} + +mpvc_check_update() +{ + master=$(curl -fsSL "$PROGURL/raw/master/extras/mpvc-installer" | + sed -n '/^PROGVERSION/ { s/"//g; s/PROGVERSION=//p }') + + if [ "$PROGVERSION" = "$master" ] + then + echo "$PROGNAME: Up-to-date, no new version > $PROGVERSION available at $PROGURL" + else + echo "$PROGNAME: Found new version $master available at $PROGURL" + fi +} + +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 " 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" + exit +} + +main() +{ + if [ $# -lt 1 ]; then usage; fi + + # hack to force SHELL back to posix-sh in macOS + case "$SHELL" in *'zsh') SHELL="/bin/sh";; esac + + case "$1" in + 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 "$@";; + link) shift; mpvc_link "$@";; + install) shift; mpvc_install "$@";; + uninstall) shift; mpvc_uninstall "$@";; + + fetch-config) shift; PREFIX=$HOME $SHELL "$0" config;; + + fetch-user) shift; PREFIX=$HOME $SHELL "$0" fetch;; + fetch-sys) shift; PREFIX=/usr/local $SHELL "$0" fetch;; + link-user) shift; PREFIX=$HOME $SHELL "$0" link;; + install-user) shift; PREFIX=$HOME $SHELL "$0" install;; + install-sys) shift; PREFIX=/usr/local $SHELL "$0" install;; + + uninstall-user) shift; PREFIX=$HOME $SHELL "$0" uninstall;; + uninstall-sys) shift; PREFIX=/usr/local $SHELL "$0" uninstall;; + + *) usage;; + esac +} + +main "$@" diff --git a/stream.js b/stream.js index 4374f41..22da97b 100644 --- a/stream.js +++ b/stream.js @@ -31,7 +31,16 @@ async function main() { shout.setAudioInfo('channels', '2'); shout.open(); - + function mpvSpawn() { + const mpv = spawn('mpv', [config.icecast.url, "--input-ipc-server=.config/mpvc/mpvsocket0"], { + detached: true + }) + + mpv.on('exit', async (code) => { + await mpvSpawn() + }); + } + mpvSpawn() async function play(metadata) { console.log(metadata) const fileHandle = await fsp.open(metadata.file); @@ -49,7 +58,7 @@ async function main() { const { bytesRead } = await fileHandle.read(buf, 0, readLength, totalBytesRead); totalBytesRead = totalBytesRead + bytesRead; - if (bytesRead === 0) break; + if (bytesRead === 0 || !global.isPlaying) break; shout.send(buf, bytesRead); shout.sync(); }