diff options
-rw-r--r-- | emacsconf-hyperlist.el | 37 | ||||
-rw-r--r-- | emacsconf-pad.el | 111 | ||||
-rw-r--r-- | emacsconf-stream.el | 141 | ||||
-rw-r--r-- | emacsconf.el | 14 |
4 files changed, 252 insertions, 51 deletions
diff --git a/emacsconf-hyperlist.el b/emacsconf-hyperlist.el index d65979a..ac095a7 100644 --- a/emacsconf-hyperlist.el +++ b/emacsconf-hyperlist.el @@ -21,6 +21,18 @@ ;;; Commentary: +(defun emacsconf-hyperlist-audio (source) + (format + "%s: pamix (F3 output) [[elisp:(emacsconf-stream-audio-quieter \"${track}\" \"%s\")][quieter]] [[elisp:(emacsconf-stream-audio-louder \"${track}\" \"%s\")][louder]] %s" + source + source source + (mapconcat (lambda (val) + (format "[[elisp:(emacsconf-stream-audio-set \"${track}\" \"%s\" \"%d%%\")][%d]]" + source + val val)) + '(70 80 90 100 110 120) + " "))) + (defun emacsconf-hyperlist-format-talk-streamer (talk) (setq talk (emacsconf-resolve-talk talk)) (emacsconf-replace-plist-in-string @@ -29,7 +41,8 @@ :intro-type (if (plist-get talk :recorded-intro) "recorded" "live") :talk-type (if (plist-get talk :video-file) "recorded" "live") :qa-type (or (plist-get talk :q-and-a) "none") - ) + :qa-adjust (emacsconf-hyperlist-audio "qa") + :mumble-adjust (emacsconf-hyperlist-audio "mumble")) talk) (concat "- ${hhmm} ${track-id} ${slug} (intro: ${intro-type}, talk: ${talk-type}, Q&A: ${qa-type}) [[${absolute-url}][talk page]]\n" @@ -38,12 +51,16 @@ ;; Intro (cond ((plist-get talk :recorded-intro) - " - [[elisp:(emacsconf-stream-play-intro \"${slug}\")][backup: play intro]]\n") + " - [[elisp:(emacsconf-stream-play-intro \"${slug}\")][backup: play intro]] + - if that still doesn't work, [[elisp:(emacsconf-stream-open-in-between-slide \"${slug}\"][open in-between slide]] and ask the host to intro it over Mumble\n" + ) ((plist-get talk :video-file) ;; recorded talk, so intro comes from Mumble - " - [[elisp:(emacsconf-play-intro \"${slug}\")][backup: open in-between slide]]\n") + " - [[elisp:(emacsconf-play-intro \"${slug}\")][backup: open in-between slide]] + - [ ] adjust audio as needed ${mumble-adjust}\n") (t ;; live talk and intro, join BBB " - [[elisp:(emacsconf-stream-bbb \"${slug}\")][backup: join BBB for live intro and talk]] - - [ ] adjust audio as needed\n")) + - [[elisp:(emacsconf-stream-xdotool-set-up-bbb \"${slug}\"][backup: xdotool BBB]] + - [ ] adjust audio as needed ${qa-adjust}\n")) ;; Talk (cond ;; video should already have played @@ -55,7 +72,8 @@ ;; recorded intro, live talk ((plist-get talk :recorded-intro) " - [ ] [[elisp:(emacsconf-stream-bbb \"${slug}\")][join BBB for live talk]] - - [ ] adjust audio as needed\n" + - [ ] [[elisp:(emacsconf-stream-xdotool-set-up-bbb \"${slug}\"][xdotool BBB]] + - [ ] adjust audio as needed ${qa-adjust}\n" )) (if (plist-get talk :video-file) "" @@ -78,6 +96,8 @@ :intro-type (if (plist-get talk :recorded-intro) "recorded" "live") :talk-type (if (plist-get talk :video-file) "recorded" "live") :qa-type (or (plist-get talk :q-and-a) "none") + :qa-adjust (emacsconf-hyperlist-audio "qa") + :mumble-adjust (emacsconf-hyperlist-audio "mumble") ) talk) (concat @@ -88,8 +108,10 @@ ((rx "live") " - [[elisp:(emacsconf-stream-bbb \"${slug}\")][backup: join BBB]] - [[elisp:(emacsconf-stream-open-pad \"${slug}\")][backup: open pad]] - - [ ] Check that streaming has started + - [ ] [[elisp:(emacsconf-stream-xdotool-set-up-bbb \"${slug}\"][xdotool BBB]] + - [ ] Check that streaming has started AND RECORDING HAS STARTED - [ ] Give the host the go-ahead via Mumble or #emacsconf-org + - [ ] ${qa-adjust} - [ ] [[elisp:(emacsconf-update-talk-status-with-hooks \"${slug}\" \".\" \"OPEN_Q\")][set talk open q]] - [ ] Confirm BBB redirect at ${bbb-redirect} goes to BBB room, let host know ") @@ -100,7 +122,8 @@ ") ((rx "Mumble") " - - [ ] Bring the speaker's Mumble login over to the ${channel} channel in Mumble. Confirm that Mumble is audible and adjust audio as needed: ssh emacsconf-${track-id}@res.emacsconf.org -p 46668 \"mum-vol 85%%\" (or mum-louder, mum-quieter) + - [ ] Bring the speaker's Mumble login over to the ${channel} channel in Mumble. + - [ ] Confirm that Mumble is audible and adjust audio as needed: ${mumble-adjust}\n - [ ] [[elisp:(emacsconf-update-talk-status-with-hooks \"${slug}\" \".\" \"OPEN_Q\")][set talk open q]] ") ((rx "after") diff --git a/emacsconf-pad.el b/emacsconf-pad.el index c0f84d5..c40cf6c 100644 --- a/emacsconf-pad.el +++ b/emacsconf-pad.el @@ -413,6 +413,10 @@ ${next-talk-list} </ul>")) ))) +(defun emacsconf-pad-prepopulate-shift-host (shift info) + + ) + (defun emacsconf-pad-format-checkin-hyperlist (talk) (emacsconf-replace-plist-in-string (append (list @@ -424,6 +428,7 @@ ${next-talk-list} (format-time-string "%H:%M" (plist-get talk :start-time) emacsconf-timezone) :bbb-checklist "<ul><li>Checklist<ul> +<li>[ ] Speaker is set as a moderator</li> <li>[ ] Speaker can be heard</li> <li>[ ] Speaker can hear others</li> <li>[ ] No audio feedback issues (may need headphones or earphones)</li> @@ -439,17 +444,17 @@ ${next-talk-list} <li>It can take some time for people to think of questions, or you might have a quiet Q&A. Please feel free to demo other things you couldn't fit in your talk, or start with questions people might be thinking about.</li> <li>We'll let you know when the stream is going to move on to the next talk. Even after the streamer switches over to the next talk, you can still stay and chat here for as long as you like. When you're done, you can wrap up and leave.</li></ul>") talk) - (if (plist-get talk :video-duration) + (if (plist-get talk :video-file) (pcase (or (plist-get talk :q-and-a) "") ((rx "live") - "<li>[ ] <strong>${time}</strong> ${speakers} (${irc}) should be checked into ${bbb-backstage} and set as moderator(s) to go live at ${live} ${absolute-url} + "<li>[ ] <strong>${time}</strong> Q&A: BBB: ${speakers} (${irc}) should be checked into ${bbb-backstage} and set as moderator(s) to go live at ${live} ${absolute-url} ${bbb-checklist}</li>") ((or (rx "IRC") (rx "pad")) - "<li>[ ] <strong>${time}</strong> ${speakers} (${irc}) should be in #${channel} to go live at ${live} ${absolute-url}</li>") + "<li>[ ] <strong>${time}</strong> Q&A: IRC/pad: ${speakers} (${irc}) should be in #${channel} to go live at ${live} ${absolute-url}</li>") ((rx "Mumble") - "<li>[ ] <strong>${time}</strong> ${speakers} (${irc}) should be in Mumble to go live at ${live} ${absolute-url}</li>") + "<li>[ ] <strong>${time}</strong> Q&A: Mumble: ${speakers} (${irc}) should be in Mumble to go live at ${live} ${absolute-url}</li>") (_ "")) - "<li>[ ] <strong>${time}</strong> LIVE: ${speakers} (${irc}) should be checked into ${bbb-backstage} and set as moderator(s) for ${absolute-url}${bbb-checklist} to go live at ${start}</li>"))) + "<li>[ ] <strong>${time}</strong> LIVE: ${speakers} (${irc}) should be checked into ${bbb-backstage} and set as moderator(s) for ${absolute-url} to go live at ${start}${bbb-checklist}</li>"))) (defun emacsconf-pad-prepopulate-checkins (&optional info) (interactive) @@ -464,7 +469,8 @@ ${bbb-checklist}</li>") "<em>${checkin}:</em> " "" (concat (car day) - "<ul>" + "<p>If anyone's still missing by the specified time, please let us know in #emacsconf-org so we can call them.</p>" + "<ul>" (mapconcat (lambda (talk) (emacsconf-pad-format-checkin-hyperlist talk)) @@ -494,6 +500,95 @@ ${bbb-checklist}</li>") pad-id (emacsconf-pad-format-shift-hyperlist shift info))))) +(defun emacsconf-pad-prepopulate-host-hyperlists () + (interactive) + (mapc #'emacsconf-pad-prepopulate-shift-hyperlist-host emacsconf-shifts)) +(defun emacsconf-pad-prepopulate-shift-hyperlist-host (shift &optional info) + (interactive (list (completing-read "Shift: " + (mapcar (lambda (o) (plist-get o :id)) emacsconf-shifts)))) + (when (stringp shift) + (setq shift (seq-find (lambda (o) (string= (plist-get o :id) shift)) emacsconf-shifts))) + (unless info (setq info (emacsconf-prepare-for-display (emacsconf-get-talk-info)))) + (let ((info (emacsconf-prepare-for-display (emacsconf-get-talk-info)))) + (let* ((pad-id (format "host-%s" + (plist-get shift :id))) + (shift-talks + (seq-filter + (lambda (talk) (string= (plist-get talk :track) (plist-get shift :track))) + (emacsconf-filter-talks-by-time (plist-get shift :start) (plist-get shift :end) info)))) + (emacsconf-pad-create-pad pad-id) + (emacsconf-pad-set-html + pad-id + (concat + " + <p>Ctrl-5 is the shortcut for striking through on Etherpad.</p> + <p>Don't use this for notes since it gets overwritten.</p> + + <strong>Setup:</strong> + <ul> + <li>Join Mumble</li> + <li>Join the IRC channel for your track (optional)</li> + </ul> + " + "<strong>Talks</strong> + <ul>" + (mapconcat + (lambda (talk) + (let ((next-talk (car (plist-get talk :next-talks)))) + (emacsconf-replace-plist-in-string + (append + (list :start-hhmm (format-time-string "%H:%M" (plist-get talk :start-time) emacsconf-timezone) + :expanded-intro (emacsconf-pad-expand-intro talk) + :mumble (concat emacsconf-id "-" (plist-get (emacsconf-get-track talk) :id)) + :qa-hhmm (format-time-string "%H:%M" (plist-get talk :qa-time) emacsconf-timezone) + :next-talk-in-5 (if next-talk (format-time-string "%H:%M" (time-subtract (plist-get next-talk :start-time) (seconds-to-time 300)) emacsconf-timezone) "") + :next-talk-in-1 (if next-talk (format-time-string "%H:%M" (time-subtract (plist-get next-talk :start-time) (seconds-to-time 60)) emacsconf-timezone) "")) + talk) + (concat + (cond + (;; live talk, join BBB + (and (null (plist-get talk :recorded-intro)) + (null (plist-get talk :video-file))) + "<li>[ ] ${start-hhmm} ${slug}: Join ${bbb-backstage}. START RECORDING. Introduce talk, then turn over to speaker for live talk: <strong>${expanded-intro}</strong></li>") + (;; live talk, join BBB + (and (null (plist-get talk :recorded-intro)) + (plist-get talk :video-file)) + "<li>[ ] ${start-hhmm} ${slug}: Join ${mumble} in Mumble and introduce talk: <strong>${expanded-intro}</strong></li>") + (;; live talk, join BBB + (and (plist-get talk :recorded-intro) + (null (plist-get talk :video-file))) + "<li>Backup: ${start-hhmm} ${slug}: it should play a prerecorded intro, but if it doesn't, join ${bbb-backstage} and introduce talk, then turn it over to speaker for live talk: ${expanded-intro}</li>") + (t ;; prerecorded intro + "<li>Backup: ${start-hhmm} ${slug}: it should play a prerecorded intro, but if it doesn't, join ${mumble} in Mumble and introduce talk: ${expanded-intro}</li>")) + ;; Q&A + (if (and (null (plist-get talk :video-file)) (not (string= (or (plist-get talk :q-and-a) "none") "none"))) + "<li>Continue in the BBB room for live Q&A because the talk was live</li>" + (pcase (plist-get talk :q-and-a) + ((or 'nil "" "none" (rx "after")) + (if (plist-get talk :video-file) + "<li>[ ] ${qa-hhmm} ${slug}: Join ${mumble} in Mumble and say that the speaker will follow up with answers on the talk page afterwards. Read questions. ${pad-url}</li>" + "")) + ((rx "IRC") + "<li>[ ] ${qa-hhmm} ${slug}: Join ${mumble} in Mumble. Invite people to put their questions in the ${channel} IRC channel and read questions and answers from there. ${webchat-url} ${pad-url}</li>") + ((rx "pad") + "<li>[ ] ${qa-hhmm} ${slug}: Join ${mumble} in Mumble. Invite people to put their questions in the Etherpad and read questions and answers from there. ${pad-url}</li>") + ((rx "Mumble") + "<li>[ ] ${qa-hhmm} ${slug}: Join ${mumble} in Mumble. Bring the speaker into the right channel if needed. Invite people to put their questions in the Etherpad and read questions and answers from there. ${pad-url} Paste questions into Mumble chat or read them out loud.</li>") + ((rx "live") + "<li>[ ] ${qa-hhmm} ${slug}: Join ${bbb-backstage}. START RECORDING. Invite people to put their questions in the Etherpad, and read questions from there. ${pad-url}</li> + <li>Decide when to open the Q&A BBB up to everyone. Let the streamer know.</li> +<li>${next-talk-in-5} [? Open Q&A is still going on and it's about five minutes before the next talk] + <ul><li>[ ] Let the speaker know about the time and that the Q&A can continue off-stream if people want to join</li></ul></li> +<li>${next-talk-in-1} [? Open Q&A is still going on and it's about a minute before the next talk] + <ul><li>[ ] Announce that the Q&A will continue if people want to join the BBB room from the talk page, and the stream will now move to the next talk</li></ul></li> + "))))))) + (emacsconf-include-next-talks shift-talks 1) + "\n") + "</ul>" + ) + ) + ))) + (defun emacsconf-pad-prepopulate-hyperlists () (interactive) (let ((info (emacsconf-prepare-for-display (emacsconf-get-talk-info)))) @@ -514,7 +609,7 @@ ${bbb-checklist}</li>") ((or 'nil "nil" (rx string-start "he") (rx "him")) "He") ((rx "they") "They") (_ (or (plist-get talk :pronouns) ""))))) - (format "The next talk is called \"%s\"\", by %s.%s" (plist-get talk :title) + (format "The next talk is called \"%s\", by %s.%s" (plist-get talk :title) (replace-regexp-in-string ", \\([^,]+\\)$" ", and \\1" (plist-get talk :speakers)) @@ -608,7 +703,7 @@ ${bbb-checklist}</li>") "<li>Live intro and talk:<ul>" "<li>[ ] ${stream}: Mark the talk as playing: ${ssh-playing} (Backup URL to join in case it doesn't automatically join: ${bbb-backstage})</li>" "<li>[ ] ${host}: Join ${bbb-backstage} and introduce the talk: <strong>${intro-note}</strong>.</li></ul></li>" - "<li>[ ] ${stream}: Adjust audio as needed.</li>")) + "<li>[ ] ${stream}: Adjust audio as needed</li>")) ) (pcase (or (plist-get talk :q-and-a) "") diff --git a/emacsconf-stream.el b/emacsconf-stream.el index 69b01d1..0daab10 100644 --- a/emacsconf-stream.el +++ b/emacsconf-stream.el @@ -177,31 +177,34 @@ while OTHER-FILENAME will be displayed at other times." (save-window-excursion (emacsconf-stream-set-talk-info talk)))) -(defun emacsconf-stream-track-ssh (talk &rest commands) - "SSH to the track account for TALK and run COMMANDS. +(defun emacsconf-stream-track-ssh (track &rest commands) + "SSH to the account for TRACK and run COMMANDS. This might be more reliable than using TRAMP to call file processes, especially when two things need to happen close together." - (setq talk (emacsconf-resolve-talk talk)) - (let ((info (tramp-dissect-file-name (emacsconf-stream-track-login talk)))) + (setq track + (if (stringp track) + (or (emacsconf-get-track track) + (emacsconf-get-track (emacsconf-resolve-talk track))) + (emacsconf-get-track track))) + (let ((info (tramp-dissect-file-name (emacsconf-stream-track-login track)))) (apply #'start-process (delq nil (append (list - (concat "ssh-" (plist-get (emacsconf-get-track talk) :id)) - (concat "*" (plist-get talk :track) "*") "ssh" + (concat "ssh-" (plist-get track :id)) + (concat "*" (plist-get track :name) "*") "ssh" (concat (tramp-file-name-user info) "@" (tramp-file-name-host info)) "-p" (tramp-file-name-port info) - (format "DISPLAY=%s" (plist-get (emacsconf-get-track talk) :vnc-display)) - "nohup") + (format "DISPLAY=%s" (plist-get track :vnc-display))) (if (listp (car commands)) (car commands) commands)))))) (defun emacsconf-stream-play-intro (talk) "Play the recorded intro or display the in-between slide for TALK." (interactive (list (emacsconf-complete-talk-info))) (setq talk (emacsconf-resolve-talk talk)) - (emacsconf-stream-track-ssh talk "intro" (plist-get talk :slug))) + (emacsconf-stream-track-ssh talk "nohup" "intro" (plist-get talk :slug))) (defun emacsconf-stream-play-talk-on-change (talk) "Play the talk." @@ -210,27 +213,29 @@ especially when two things need to happen close together." (when (or (not (boundp 'org-state)) (string= org-state "PLAYING")) (emacsconf-stream-track-ssh talk - (cond - ((and - (plist-get talk :recorded-intro) - (plist-get talk :video-file)) ;; recorded intro and recorded talk - (message "should automatically play intro and recording") - (list "play-with-intro" (plist-get talk :slug))) ;; todo deal with stream files - ((and - (plist-get talk :recorded-intro) - (null (plist-get talk :video-file))) ;; recorded intro and live talk; play the intro and join BBB - (message "should automatically play intro; join %s" (plist-get talk :bbb-backstage)) - (list "intro" (plist-get talk :slug))) - ((and - (null (plist-get talk :recorded-intro)) - (plist-get talk :video-file)) ;; live intro and recorded talk, show slide and use Mumble; manually play talk - (message "should show intro slide; play %s afterwards" (plist-get talk :slug)) - (list "intro" (plist-get talk :slug))) - ((and - (null (plist-get talk :recorded-intro)) - (null (plist-get talk :video-file))) ;; live intro and live talk, join the BBB - (message "join %s for live intro and talk" (plist-get talk :bbb-backstage)) - (list "bbb" (plist-get talk :slug))))))) + (cons + "nohup" + (cond + ((and + (plist-get talk :recorded-intro) + (plist-get talk :video-file)) ;; recorded intro and recorded talk + (message "should automatically play intro and recording") + (list "play-with-intro" (plist-get talk :slug))) ;; todo deal with stream files + ((and + (plist-get talk :recorded-intro) + (null (plist-get talk :video-file))) ;; recorded intro and live talk; play the intro and join BBB + (message "should automatically play intro; join %s" (plist-get talk :bbb-backstage)) + (list "intro" (plist-get talk :slug))) + ((and + (null (plist-get talk :recorded-intro)) + (plist-get talk :video-file)) ;; live intro and recorded talk, show slide and use Mumble; manually play talk + (message "should show intro slide; play %s afterwards" (plist-get talk :slug)) + (list "intro" (plist-get talk :slug))) + ((and + (null (plist-get talk :recorded-intro)) + (null (plist-get talk :video-file))) ;; live intro and live talk, join the BBB + (message "join %s for live intro and talk" (plist-get talk :bbb-backstage)) + (list "bbb" (plist-get talk :slug)))))))) (defun emacsconf-stream-get-filename (talk) "Return the local filename for the video file for TALK. @@ -247,6 +252,7 @@ Final files should be stored in /data/emacsconf/stream/YEAR/video-slug--main.web talk (append (list + "nohup" "play" (plist-get talk :slug)) (if (stringp (plist-get talk :stream-files)) @@ -259,11 +265,13 @@ Final files should be stored in /data/emacsconf/stream/YEAR/video-slug--main.web (apply #'emacsconf-stream-track-ssh talk + "nohup" "overlay" (plist-get talk :slug)) (apply #'emacsconf-stream-track-ssh talk + "nohup" "mpv" filename)) @@ -272,6 +280,7 @@ Final files should be stored in /data/emacsconf/stream/YEAR/video-slug--main.web (setq talk (emacsconf-resolve-talk talk)) (emacsconf-stream-track-ssh talk + "nohup" "firefox" (plist-get talk :pad-url))) @@ -279,7 +288,7 @@ Final files should be stored in /data/emacsconf/stream/YEAR/video-slug--main.web "Open the BBB room for TALK." (interactive (list (emacsconf-complete-talk-info))) (setq talk (emacsconf-resolve-talk talk)) - (emacsconf-stream-track-ssh talk "bbb" (plist-get talk :slug))) + (emacsconf-stream-track-ssh talk "nohup" "bbb" (plist-get talk :slug))) (defun emacsconf-stream-join-qa (talk) "Join the Q&A for TALK. @@ -289,11 +298,13 @@ This uses the BBB room if available, or the IRC channel if not." (string-match "live" (plist-get talk :q-and-a))) (emacsconf-stream-track-ssh talk + "nohup" "firefox" "-new-window" (plist-get talk :pad-url)) (emacsconf-stream-track-ssh talk + "nohup" "firefox" "-new-window" (pcase (plist-get talk :q-and-a) @@ -313,6 +324,7 @@ This uses the BBB room if available, or the IRC channel if not." (setq talk (emacsconf-resolve-talk talk)) (emacsconf-stream-track-ssh talk + "nohup" "firefox" (plist-get talk :webchat-url))) @@ -832,5 +844,72 @@ ffplay URL (time-add (current-time) (seconds-to-time (- duration playback-position))) emacsconf-timezone)))) +;;; xdotool + +(defun emacsconf-stream-xdotool (track command) + (setq track (emacsconf-get-track track)) + (let ((default-directory (plist-get track :tramp))) + (shell-command-to-string (concat "DISPLAY=" (plist-get track :vnc-display) " xdotool " command)))) + +(defun emacsconf-stream-xdotool-set-up-bbb (track) + (interactive (list (emacsconf-complete-track))) + (when (stringp track) + (setq track (or (emacsconf-get-track track) + (emacsconf-get-track (emacsconf-resolve-talk track))))) + (emacsconf-stream-xdotool track "mousemove 806 385 click 1 sleep 2") + ;; type emacsconf + (emacsconf-stream-xdotool track "mousemove 791 512 click 1 sleep 1 key Ctrl+a type emacsconf") + (emacsconf-stream-xdotool track "mousemove 1043 521 click 1 sleep 4") + ;; listen only + (emacsconf-stream-xdotool track "mousemove 720 461 click 1 sleep 2") + ;; hide the chat + (emacsconf-stream-xdotool track "mousemove 553 157 click 1") + ;; go full-screen + (emacsconf-stream-xdotool track "key F11")) + +;;; audio levels + +(defun emacsconf-stream-audio-louder (track source) + (interactive (list (emacsconf-complete-track) (completing-read "Source: " '("qa" "mumble")))) + (emacsconf-stream-audio-set track source "+5%")) + +(defun emacsconf-stream-audio-quieter (track source) + (interactive (list (emacsconf-complete-track) (completing-read "Source: " '("qa" "mumble")))) + (emacsconf-stream-audio-set track source "-5%")) + +(defun emacsconf-stream-audio-set (track source volume) + (interactive (list (emacsconf-complete-track) (completing-read "Source: " '("qa" "mumble")) + (read-string "Volume: "))) + (setq track + (if (stringp track) + (or (emacsconf-get-track track) + (emacsconf-get-track (emacsconf-resolve-talk track))) + (emacsconf-get-track track))) + (let ((default-directory (plist-get track :tramp))) + (message "%s volume %s" + source + (string-trim + (shell-command-to-string + (format + "pactl set-sink-volume %s %s; pactl list sinks | perl -000ne 'if(/%s/){/Volume:.*?([0-9]+%%)/;print \"$1\n\"}'" + source volume source)))))) + +(defun emacsconf-stream-audio-get-volume (track source) + (interactive (list (emacsconf-complete-track) (completing-read "Source: " '("qa" "mumble")))) + (setq track + (if (stringp track) + (or (emacsconf-get-track track) + (emacsconf-get-track (emacsconf-resolve-talk track))) + (emacsconf-get-track track))) + (let ((default-directory (plist-get track :tramp))) + (string-trim + (shell-command-to-string + (format + "pactl list sinks | perl -000ne 'if(/%s/){/Volume:.*?([0-9]+%%)/;print \"$1\n\"}'" + source))))) + +;; (emacsconf-stream-audio-get-volume "General" "qa") +;; (emacsconf-stream-audio-louder "General" "qa") +;; (emacsconf-stream-audio-quieter "General" "qa") (provide 'emacsconf-stream) ;;; emacsconf-stream.el ends here diff --git a/emacsconf.el b/emacsconf.el index a5a9a0e..ea9b0b1 100644 --- a/emacsconf.el +++ b/emacsconf.el @@ -104,7 +104,8 @@ (let* ((org-agenda-custom-commands `(("a" "Agenda" ((tags-todo "-PRIORITY=\"C\"-SCHEDULED={.}-nextyear" - ((org-agenda-files (list ,emacsconf-notebook)))) + ((org-agenda-files (list ,emacsconf-notebook)) + (org-agenda-sorting-strategy '(priority-down effort-up)))) (agenda "" ((org-agenda-files (list ,emacsconf-notebook)) (org-agenda-span 7))) @@ -1064,10 +1065,13 @@ (setq emacsconf-shifts (list (list :id "sat-am-gen" :track "General" :start "2022-12-03T08:00:00-0500" :end "2022-12-03T12:00:00-0500" :host "zaeph" :streamer "sachac" :checkin "corwin" :irc "dto" :pad "publicvoit" :coord "sachac") (list :id "sat-pm-gen" :track "General" :start "2022-12-03T13:00:00-0500" :end "2022-12-03T18:00:00-0500" :host "zaeph" :streamer "sachac" :checkin "FlowyCoder" :irc "bandali" :pad "publicvoit" :coord "sachac") (list :id "sat-am-dev" :track "Development" :start "2022-12-03T08:00:00-0500" :end "2022-12-03T12:00:00-0500" :host "bandali" :streamer "sachac" :checkin "corwin" :irc "dto" :coord "sachac") (list :id "sat-pm-dev" :track "Development" :start "2022-12-03T13:00:00-0500" :end "2022-12-03T18:00:00-0500" :host "vetrivln" :streamer "bandali" :checkin "FlowyCoder" :irc "vetrivln" :coord "sachac") (list :id "sun-am-gen" :track "General" :start "2022-12-04T08:00:00-0500" :end "2022-12-04T12:00:00-0500" :host "zaeph" :streamer "sachac" :checkin "corwin" :irc "dto" :pad "publicvoit" :coord "sachac") (list :id "sun-pm-gen" :track "General" :start "2022-12-04T13:00:00-0500" :end "2022-12-04T18:00:00-0500" :host "zaeph" :streamer "jman" :checkin "FlowyCoder" :irc "bandali" :pad "publicvoit" :coord "sachac") (list :id "sun-am-dev" :track "Development" :start "2022-12-04T08:00:00-0500" :end "2022-12-04T12:00:00-0500" :host "bandali" :streamer "sachac" :checkin "corwin" :irc "dto" :coord "sachac") (list :id "sun-pm-dev" :track "Development" :start "2022-12-04T13:00:00-0500" :end "2022-12-04T18:00:00-0500" :host "vetrivln" :streamer "bandali" :checkin "FlowyCoder" :irc "vetrivln" :coord "sachac"))) (defun emacsconf-get-track (name) - (when (listp name) (setq name (plist-get name :track))) - (seq-find (lambda (track) (or (string= name (plist-get track :name)) - (string= name (plist-get track :id)))) - emacsconf-tracks)) + (when (and (listp name) (plist-get name :track)) + (setq name (plist-get name :track))) + (if (stringp name) + (seq-find (lambda (track) (or (string= name (plist-get track :name)) + (string= name (plist-get track :id)))) + emacsconf-tracks) + name)) (defun emacsconf-by-track (info) (mapcar (lambda (track) |