Yay Emacs!
Stream notes
CANCELLED FOR NOW - experimenting with minimal screen time during the day since that seems to make the kiddo's life easier, so I don't get to have screentime too
Watch previous videos at at https://youtube.com/@sachactube/live - iCalendar file - RSS
Overall goals
2024-01-20-04 My Evil Plan for Yay Emacs! #EvilPlan #planning #emacs #YayEmacs.png
I want to work out loud so that:
- I can get more stuff out of my head and into code/videos/blog posts
- people can pick up ideas from things I might overlook
- I can learn from people's ideas and suggestions
I want to share my notes file so that:
- people who join mid-way can catch up
- people can copy-and-paste instead of trying to re-type
- people can chime in with things they want me to explore
CANCELLED Yay Emacs! 2024-02-11
Past livestreams
You can find notes at https://sachachua.com/blog/category/yay-emacs/ .
- 2024-01-28 Yay Emacs: closed captions and synchronized highlights for audio clips; exploring Emacs Lisp functions
- 2024-01-21 Yay Emacs: copy link, Spookfox + Org Babel, choosing what to hack on, SVG highlighting, ical
- My Evil Plan for Yay Emacs!
- Yay Emacs: Using elisp: links in Org Mode to note the time and display messages on stream
- Yay Emacs 2024-01-12: EmacsConf 2023 report, SVG animation, Embark, Org Mode links
- Quick notes on livestreaming to YouTube with FFmpeg on a Lenovo X230T
Ideas for future sessions
debugging YayEmacs
@sachac re: the stream comment, I haven't done much debugging in Emacs via its debugger – or it's not a natural part of my elisp flow – so seeing that at the end made me think about debugging wins as potential "Yay emacs" moments.
https://mastodon.social/@charliemac/111794178311111100
*
:CREATED:
TODO Clip evil plans from 2024-01-21 Yay Emacs YayEmacs
TODO Transcribe 2024-01-21 Yay Emacs YayEmacs
SOMEDAY iCalendar Export (The Org Manual) YayEmacs emacs
Refiling YayEmacs
refile for navigation refile to current file refile to a subset
news refiling
Workflow
Process
- ☐ Download: yt-dlp –prefer-free-formats $URL
TODO automatically determine the VTT from the filename
SOMEDAY @matthewstott3493 4 minutes ago Fantastic job on your live streams! Loving the faces and themes (ef-themes?), it is highly legible! Would recommend Prot's spacious-mode and some buffers [5:16 the line wrapping would look better with fill-paragraph. Presentation mode might be beneficial unless you are demonstrating. Using a variable pitch face on non-code buffers would be nice. Would prefer 1080p but am guessing you find 720p to be less of an impact on your hardware and streaming. Can you document your setup for recording and live streaming? am sure you learned a lot over the last couple of Emacs Conferences. YayEmacs workflow
Youtube comment
TODO switch to command log mode since keycast isn't seen in my modeline YayEmacs workflow
TODO consider refresh for OBS web source YayEmacs workflow
TODO Get the audio clip about evil plans for Yay Emacs and turn it into an animated blog post YayEmacs toclip workflow
TODO Figure out how to get live caption text YayEmacs workflow
Options:
- Send phone screen through quick OCR for once-in-a-while copies
- See if I can stream the 608/708 embedded captions from YouTube's autocaptions
- Use Deepgram's streaming API
SOMEDAY Send URL to Youtube chat YayEmacs workflow
- https://developers.google.com/youtube/v3/live/docs/liveChatMessages
- or use Spookfox?
Figure out how to properly show EMMS track info
Update the category description
(let ((time (my-org-closest-future-time))) (with-temp-file "~/proj/static-blog/_data/term-descriptions/yay-emacs.html" (insert (format "<div>The next stream is on %s. <a href=\"https://yayemacs.com\">Find details and watch here.</a></div> <iframe width=\"560\" height=\"315\" src=\"https://www.youtube-nocookie.com/embed/live_stream?channel=UClT2UAbC6j7TqOWurVhkuHQ\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen></iframe>" (format-time-string "%a %Y-%m-%d %-H:%M %Z (%z)" (org-timestamp-to-time (org-timestamp-from-string time)))))))
DONE Yay Emacs: Using elisp: links in Org Mode to note the time and display messages on stream YayEmacs org
I like adding chapters to my videos so that people can jump to sections. I can figure out the sections by reading the transcript, adding NOTE
comments, and extracting the times for those with my-youtube-copy-chapters. It could be nice to capture the times on the fly. org-timer
could let me insert relative timestamps, but I think it might need some tweaking to synchronize that with when the stream starts according to YouTube. I've set up a capture, too, so I can take notes with timestamps.
It turns out that I don't have a lot of mental bandwidth when I'm on stream, so it's hard to remember keyboard shortcuts. (Maybe if I practise using the hydra I set up…) Fortunately, Org Mode's elisp:
link type makes it easy to set up executable shortcuts. For example, I can add links like [[elisp:my-stream-message-link][TODO]]
to my livestream plans like this:
I can then click on the links or use C-c C-o
(org-open-link-at-point
) to run the function. When I follow the TODO link in the first item, Emacs displays a clock and a message based on the rest of the line after the link.
In the background, the code also sets the description of the link to the wall-clock time.
If I start the livestream with a clock displayed on screen, I can use that to translate wall-clock times to relative time offsets. I'll probably figure out some Elisp to translate the times automatically at some point, maybe based on something like org-timer-change-times-in-region
.
I figured it might be fun to add a QR code automatically if we detect a URL, taking advantage of that qrencode package I started playing around with. That way, people might be able to just scan it off the screen.
You can also use elisp:
links for more complicated Emacs Lisp functions, like this: elisp:(progn ... ...)
.
Here's the code that makes it happen. It's based on emacsconf-stream.el.
(defvar my-stream-message-buffer "*Yay Emacs*") (defvar my-stream-message-timer nil) (defun my-stream-message-link () (interactive) (save-excursion (when (and (derived-mode-p 'org-mode) (eq (org-element-type (org-element-context)) 'link)) (my-stream-update-todo-description-with-time) (goto-char (org-element-end (org-element-context))) (my-stream-message (org-export-string-as (buffer-substring (point) (line-end-position)) 'ascii t))))) (defun my-stream-update-todo-description-with-time () (when (and (derived-mode-p 'org-mode) (eq (org-element-type (org-element-context)) 'link)) (my-org-update-link-description (format-time-string "%-I:%M:%S %p")))) (defun my-stream-message (&optional message) (interactive "MMessage: ") ;; update the description of the link at point to be the current time, if any (switch-to-buffer (get-buffer-create my-stream-message-buffer)) (erase-buffer) (delete-other-windows) (when (string= message "") (setq message nil)) (face-remap-add-relative 'default :height 200) (insert "Yay Emacs! - Sacha Chua (sacha@sachachua.com)\n" (propertize "date" 'stream-time (lambda () (format-time-string "%Y-%m-%d %H:%M:%S %Z (%z)"))) "\n\n" message) ;; has a URL? Let's QR encode it! (when-let ((url (save-excursion (when (re-search-backward ffap-url-regexp nil t) (thing-at-point-url-at-point))))) (insert (propertize (qrencode url) 'face '(:height 50)) "\n")) (insert "\nYayEmacs.com\n") (when (timerp my-stream-message-timer) (cancel-timer my-stream-message-timer)) (my-stream-update-time) (setq my-stream-message-timer (run-at-time t 1 #'my-stream-update-time)) (goto-char (point-min))) (defun my-stream-update-time () "Update the displayed time." (if (get-buffer my-stream-message-buffer) (when (get-buffer-window my-stream-message-buffer) (with-current-buffer my-stream-message-buffer (save-excursion (goto-char (point-min)) (let (match) (while (setq match (text-property-search-forward 'stream-time)) (goto-char (prop-match-beginning match)) (add-text-properties (prop-match-beginning match) (prop-match-end match) (list 'display (funcall (get-text-property (prop-match-beginning match) 'stream-time)))) (goto-char (prop-match-end match))))))) (when (timerp my-stream-message-timer) (cancel-timer my-stream-message-timer))))
Let's see if that makes it easy enough for me to remember to actually do it!
TODO Make alternate timezone org files
- Like the way we did it in EmacsConf
- General-purpose way to translate all the times? Do I need to execute all the code, though?
SOMEDAY Tweak stream page theme, add hook YayEmacs
SOMEDAY Stream page, timezone versions, just use Syncthing YayEmacs
Schedule for current one Schedule for next one Timezone links Previous livestreams