summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmacsConf <emacsconf-org@gnu.org>2023-12-03 13:00:26 -0500
committerEmacsConf <emacsconf-org@gnu.org>2023-12-03 13:00:26 -0500
commitc68e8efa9477cf4fd6dcaaf4ce34e6641ebda0a7 (patch)
treeeb856583f73ab895df7b5a03f1680fccf3995cdf
parentf17a3b0a8c4c6b98bdccc0092d744a070dfd337e (diff)
downloademacsconf-wiki-c68e8efa9477cf4fd6dcaaf4ce34e6641ebda0a7.tar.xz
emacsconf-wiki-c68e8efa9477cf4fd6dcaaf4ce34e6641ebda0a7.zip
Automated commit
-rw-r--r--2023/captions/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--main--chapters.vtt80
-rw-r--r--2023/captions/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--main.vtt2048
-rw-r--r--2023/info/emms-after.md673
-rw-r--r--2023/info/emms-before.md30
4 files changed, 2830 insertions, 1 deletions
diff --git a/2023/captions/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--main--chapters.vtt b/2023/captions/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--main--chapters.vtt
new file mode 100644
index 00000000..f183a115
--- /dev/null
+++ b/2023/captions/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--main--chapters.vtt
@@ -0,0 +1,80 @@
+WEBVTT
+
+
+00:00:00.000 --> 00:01:03.319
+Introduction
+
+00:01:03.320 --> 00:01:21.319
+The structure of this talk
+
+00:01:21.320 --> 00:08:04.239
+Introduction to Emms: The practical part
+
+00:08:04.240 --> 00:11:01.199
+The modeline
+
+00:11:01.200 --> 00:11:29.859
+Meta-playlist mode
+
+00:11:29.860 --> 00:13:19.919
+The browser
+
+00:13:19.920 --> 00:16:23.819
+How Emms works: The technical part
+
+00:16:23.820 --> 00:16:36.439
+The Emms core
+
+00:16:36.440 --> 00:17:18.459
+Tracks
+
+00:17:18.460 --> 00:18:22.079
+Playlist
+
+00:18:22.080 --> 00:19:22.159
+Sources
+
+00:19:22.160 --> 00:20:20.519
+Players
+
+00:20:20.520 --> 00:21:36.659
+Info
+
+00:21:36.660 --> 00:22:51.619
+The cache
+
+00:22:51.620 --> 00:23:31.559
+Healthy back and forth: mpv, mpd, and GNU.FM
+
+00:23:31.560 --> 00:24:47.469
+MPV
+
+00:24:47.470 --> 00:26:07.439
+MPD
+
+00:26:07.440 --> 00:27:12.559
+GNU FM and Libre FM
+
+00:27:12.560 --> 00:28:52.589
+How we work: Emms development
+
+00:28:52.590 --> 00:29:06.079
+The Rime Of The Ancient Maintainer
+
+00:29:06.080 --> 00:31:24.079
+The life and times of an Emms patch
+
+00:31:24.080 --> 00:32:23.399
+Let It Go: The release process
+
+00:32:23.400 --> 00:34:44.848
+It Is Not In Our Stars, But In Ourselves: Future directions
+
+00:34:44.849 --> 00:36:05.979
+Development policies: Interface language
+
+00:36:05.980 --> 00:38:12.369
+Development policies: Freedom
+
+00:38:12.370 --> 00:38:38.040
+Acknowledgements
diff --git a/2023/captions/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--main.vtt b/2023/captions/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--main.vtt
new file mode 100644
index 00000000..ecbed3fb
--- /dev/null
+++ b/2023/captions/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--main.vtt
@@ -0,0 +1,2048 @@
+WEBVTT captioned by yoni, checked by sachac
+
+NOTE Introduction
+
+00:00:00.000 --> 00:00:05.399
+The Sound of Emacs, Emms, The Emacs Multimedia System.
+
+00:00:05.400 --> 00:00:09.159
+Hi, I'm Yoni Rabkin and I'll be talking about Emms;
+
+00:00:09.160 --> 00:00:11.519
+the Emacs Multimedia System.
+
+00:00:11.520 --> 00:00:14.559
+What is Emms?
+
+00:00:14.560 --> 00:00:18.119
+Emms displays and plays media from within Emacs
+
+00:00:18.120 --> 00:00:20.519
+using a variety of external players
+
+00:00:20.520 --> 00:00:23.539
+and from different media sources.
+
+00:00:23.540 --> 00:00:26.679
+Emms can run as a minimalistic player
+
+00:00:26.680 --> 00:00:28.559
+which is controlled with no more than
+
+00:00:28.560 --> 00:00:31.119
+a handful of simple M-x commands,
+
+00:00:31.120 --> 00:00:36.059
+or as a fully-fledged interactive media browser and player.
+
+00:00:36.060 --> 00:00:40.639
+Emms can display album art, play streaming audio,
+
+00:00:40.640 --> 00:00:43.439
+tag music files, search for lyrics,
+
+00:00:43.440 --> 00:00:46.679
+provide MPD connectivity, control the volume,
+
+00:00:46.680 --> 00:00:49.619
+and more. Much more.
+
+00:00:49.620 --> 00:00:53.879
+The Emms project acts like Emacs in microcosm.
+
+00:00:53.880 --> 00:00:56.559
+It slowly but surely grows bigger
+
+00:00:56.560 --> 00:00:58.479
+and gets ever more features.
+
+00:00:58.480 --> 00:01:03.319
+Perhaps Emms will one day even have a text editor.
+
+NOTE The structure of this talk
+
+00:01:03.320 --> 00:01:05.599
+The structure of this talk:
+
+00:01:05.600 --> 00:01:08.159
+We'll start with an introduction to Emms.
+
+00:01:08.160 --> 00:01:10.559
+This is the practical part.
+
+00:01:10.560 --> 00:01:15.879
+Then, a bit about how Emms works. That's the technical part.
+
+00:01:15.880 --> 00:01:21.319
+Finally, how we work. All about Emms development.
+
+NOTE Introduction to Emms: The practical part
+
+00:01:21.320 --> 00:01:25.020
+Introduction to Emms: The practical part:
+
+00:01:25.021 --> 00:01:28.679
+I want this talk to be of immediate use to people,
+
+00:01:28.680 --> 00:01:33.519
+so I'm going to present a quick TL;DR of the Emms manual
+
+00:01:33.520 --> 00:01:36.399
+concerning installation and use.
+
+00:01:36.400 --> 00:01:38.439
+By the end of this part you should be able to
+
+00:01:38.440 --> 00:01:45.279
+install, configure, and use Emms in a variety of ways.
+
+00:01:45.280 --> 00:01:48.119
+Where can I get Emms?
+
+00:01:48.120 --> 00:01:54.319
+Emms is distributed primarily via GNU ELPA.
+
+00:01:54.320 --> 00:02:02.079
+So it's really only a M-x list-packages away at any moment.
+
+00:02:02.080 --> 00:02:07.719
+There's also a website hosted at gnu.org.
+
+00:02:07.720 --> 00:02:11.019
+Among other things on the website, you'll find
+
+00:02:11.020 --> 00:02:21.279
+a copy of the friendly, robust, and up-to-date user manual.
+
+00:02:21.280 --> 00:02:25.919
+Installing Emms has become progressively easier over time
+
+00:02:25.920 --> 00:02:28.719
+and will continue to get easier.
+
+00:02:28.720 --> 00:02:32.559
+In the bad old days, it required downloading a tarball
+
+00:02:32.560 --> 00:02:35.059
+and compiling a C language shim
+
+00:02:35.060 --> 00:02:38.919
+to enable reading metadata from media files.
+
+00:02:38.920 --> 00:02:43.359
+But those days are long gone, and installing Emms is now
+
+00:02:43.360 --> 00:02:47.039
+as easy as invoking M-x list-packages,
+
+00:02:47.040 --> 00:02:51.839
+installing the Emms package, and placing as few as
+
+00:02:51.840 --> 00:02:57.719
+2 or 3 lines of configuration in your Emacs initialization.
+
+00:02:57.720 --> 00:03:02.839
+So after the package is installed via ELPA,
+
+00:03:02.840 --> 00:03:08.439
+you can add these few lines.
+
+00:03:08.440 --> 00:03:12.359
+`emms-all` will make available all of the stable features
+
+00:03:12.360 --> 00:03:15.739
+which are shipped with Emms.
+
+00:03:15.740 --> 00:03:20.839
+The `emms-player-list` variable is a list of players
+
+00:03:20.840 --> 00:03:25.599
+like MPV, MPlayer, VLC, etc.
+
+00:03:25.600 --> 00:03:29.399
+Emms will call and control these external players
+
+00:03:29.400 --> 00:03:31.999
+to play your media.
+
+00:03:32.000 --> 00:03:36.659
+The variable `emms-info-functions` is a list of ways
+
+00:03:36.660 --> 00:03:40.959
+for Emms to read the metadata in your media files
+
+00:03:40.960 --> 00:03:45.279
+so that Emms can display song title, artist name,
+
+00:03:45.280 --> 00:03:49.479
+year of production, etc.
+
+00:03:49.480 --> 00:03:55.199
+The `emms-info-native` feature in the setup example
+
+00:03:55.200 --> 00:03:58.159
+is the built-in metadata reader
+
+00:03:58.160 --> 00:04:01.799
+written entirely in Emacs Lisp.
+
+00:04:01.800 --> 00:04:04.239
+But there are also other backends
+
+00:04:04.240 --> 00:04:07.719
+which can call external programs for info
+
+00:04:07.720 --> 00:04:14.719
+such as TinyTag, the TagLib library, exiftool, and so on.
+
+00:04:14.720 --> 00:04:17.559
+You can then old-school restart your Emacs
+
+00:04:17.560 --> 00:04:22.799
+or simply evaluate the above couple of lines to get going.
+
+00:04:22.800 --> 00:04:26.279
+Now that we have Emms installed and configured,
+
+00:04:26.280 --> 00:04:29.239
+we should load some media for player.
+
+00:04:29.240 --> 00:04:32.719
+There are multiple ways to load media into Emms for playing.
+
+00:04:32.720 --> 00:04:36.279
+They can be directories with local files,
+
+00:04:36.280 --> 00:04:38.519
+synchronized from a remote instance of
+
+00:04:38.520 --> 00:04:44.719
+a music player daemon, PLS or M3U playlists,
+
+00:04:44.720 --> 00:04:47.439
+a list of URLs for streaming,
+
+00:04:47.440 --> 00:04:51.119
+or even Emms' own native playlist format
+
+00:04:51.120 --> 00:04:57.199
+which is unsurprisingly a just serialized Emacs Lisp.
+
+00:04:57.200 --> 00:05:00.199
+No matter how you add tracks to Emms,
+
+00:05:00.200 --> 00:05:03.879
+you'll end up with a playlist.
+
+00:05:03.880 --> 00:05:08.959
+A fundamental strength of Emms is that each playlist
+
+00:05:08.960 --> 00:05:13.479
+is a regular Emacs buffer and the track listing therein
+
+00:05:13.480 --> 00:05:17.859
+is nothing more than text lines with property overlays.
+
+00:05:17.860 --> 00:05:21.359
+This means that you can navigate, search, copy,
+
+00:05:21.360 --> 00:05:24.879
+and edit an Emms playlist buffer
+
+00:05:24.880 --> 00:05:28.679
+just as you would any Emacs buffer.
+
+00:05:28.680 --> 00:05:31.319
+If you want to reorganize the tracks in the playlist,
+
+00:05:31.320 --> 00:05:33.959
+then you can simply kill yank the tracks
+
+00:05:33.960 --> 00:05:36.759
+just as you would any buffer with lines of text,
+
+00:05:36.760 --> 00:05:42.959
+and the same can be done between multiple playlist buffers.
+
+00:05:42.960 --> 00:05:46.119
+One of the most straightforward ways to add media
+
+00:05:46.120 --> 00:05:51.939
+is to invoke a command like `M-x emms-add-directory-tree`.
+
+00:05:51.940 --> 00:05:55.679
+You can point it to the top of a set of directories
+
+00:05:55.680 --> 00:06:00.279
+with playable files for Emms to traverse.
+
+00:06:00.280 --> 00:06:05.199
+Another rather convenient method is to mark files in Dired
+
+00:06:05.200 --> 00:06:09.679
+and to invoke `emms-add-dired`.
+
+00:06:09.680 --> 00:06:11.679
+I definitely use this one a lot.
+
+00:06:11.680 --> 00:06:16.119
+The Emms playlist mode binds
+
+00:06:16.120 --> 00:06:19.879
+a number of useful keys and commands.
+
+00:06:19.880 --> 00:06:23.959
+It's highly recommended that you either
+
+00:06:23.960 --> 00:06:25.959
+read the friendly manual
+
+00:06:25.960 --> 00:06:32.319
+or hit "C-h m" in a playlist buffer to discover them.
+
+00:06:32.320 --> 00:06:35.959
+Now we have a playlist buffer with a number of tracks,
+
+00:06:35.960 --> 00:06:40.819
+so the next step is going to be playback.
+
+00:06:40.820 --> 00:06:44.399
+Emms can be used as a minimalistic player
+
+00:06:44.400 --> 00:06:48.319
+with nothing more than a handful of commands.
+
+00:06:48.320 --> 00:06:51.359
+Once there is a current Emms playlist,
+
+00:06:51.360 --> 00:06:57.559
+invoking emms-start will begin playing the current track.
+
+00:06:57.560 --> 00:07:00.039
+Now of course in a new playlist
+
+00:07:00.040 --> 00:07:02.579
+that would be the first track.
+
+00:07:02.580 --> 00:07:07.199
+Now emms-next, emms-pause, and emms-stop
+
+00:07:07.200 --> 00:07:11.259
+do exactly what you think they do.
+
+00:07:11.260 --> 00:07:13.199
+To visit the current playlist,
+
+00:07:13.200 --> 00:07:17.639
+you can invoke M-x emms-playlist-mode-go,
+
+00:07:17.640 --> 00:07:22.699
+which is a long command I personally bind to "M-f12".
+
+00:07:22.700 --> 00:07:25.319
+You'll be taken to the current playlist buffer.
+
+00:07:25.320 --> 00:07:29.239
+While you can have multiple playlist buffers,
+
+00:07:29.240 --> 00:07:35.779
+only one is current for the purposes of playback commands.
+
+00:07:35.780 --> 00:07:38.119
+The playlist buffer has keys bound
+
+00:07:38.120 --> 00:07:39.919
+to control the media being played.
+
+00:07:39.920 --> 00:07:44.199
+`emms-seek-forward` and `emms-seek-backwards` allow you
+
+00:07:44.200 --> 00:07:49.039
+to scrub along the media being played.
+
+00:07:49.040 --> 00:07:51.719
+Which commands are available is a function of
+
+00:07:51.720 --> 00:07:54.199
+the player backend being employed.
+
+00:07:54.200 --> 00:07:56.599
+The simplest of players may have nothing more
+
+00:07:56.600 --> 00:07:59.559
+than the ability to play, stop, and seek,
+
+00:07:59.560 --> 00:08:04.239
+but others may implement a plethora of commands.
+
+NOTE The modeline
+
+00:08:04.240 --> 00:08:08.879
+The Modeline: Emms will by default display
+
+00:08:08.880 --> 00:08:11.839
+the name of the currently playing track in the mode line
+
+00:08:11.840 --> 00:08:14.999
+with information such as playing time.
+
+00:08:15.000 --> 00:08:15.559
+The mode line format is controlled
+
+00:08:15.560 --> 00:08:20.639
+via the `emms-mode-line-format` variable
+
+00:08:20.640 --> 00:08:27.139
+and the `emms-mode-line-playlist-current` function.
+
+00:08:27.140 --> 00:08:31.039
+Metadata and the cache.
+
+00:08:31.040 --> 00:08:34.799
+It would be sufficient for emms to simply list
+
+00:08:34.800 --> 00:08:38.619
+the file names or urls of each piece of media,
+
+00:08:38.620 --> 00:08:40.999
+but unless you name your music and media
+
+00:08:41.000 --> 00:08:43.939
+with obsessive consistency and precision,
+
+00:08:43.940 --> 00:08:46.679
+not that there is anything wrong with that
+
+00:08:46.680 --> 00:08:50.859
+then the resulting list will be a bit of an eyesore.
+
+00:08:50.860 --> 00:08:54.119
+Moreover, there are a lot of other useful metadata
+
+00:08:54.120 --> 00:08:58.619
+in the media files, including cool stuff like album art.
+
+00:08:58.620 --> 00:09:01.919
+So instead of just files, Emms will try
+
+00:09:01.920 --> 00:09:04.399
+to extract metadata from each track
+
+00:09:04.400 --> 00:09:08.219
+and display a nicely-formatted track listing.
+
+00:09:08.220 --> 00:09:10.799
+The format can be controlled by customizing
+
+00:09:10.800 --> 00:09:15.459
+the variable `emms-track-description-function`.
+
+00:09:15.460 --> 00:09:19.639
+Emms uses so-called info methods to extract
+
+00:09:19.640 --> 00:09:22.439
+the metadata from each file.
+
+00:09:22.440 --> 00:09:25.679
+`emms-info-native`, which I mentioned before,
+
+00:09:25.680 --> 00:09:30.359
+is the built-in metadata reader written in Emacs Lisp.
+
+00:09:30.360 --> 00:09:37.659
+It provides support for Ogg Vorbis, Ogg Opus, FLAC, and MP3.
+
+00:09:37.660 --> 00:09:40.359
+However, if you have media in other formats,
+
+00:09:40.360 --> 00:09:42.439
+you can also add info methods
+
+00:09:42.440 --> 00:09:45.239
+to the `emms-info-functions` list,
+
+00:09:45.240 --> 00:09:48.699
+which call external programs such as exiftool,
+
+00:09:48.700 --> 00:09:55.419
+the LibTag library, tiny-tag, etc. to read file metadata.
+
+00:09:55.420 --> 00:09:58.199
+Since reading metadata takes time
+
+00:09:58.200 --> 00:10:01.339
+and that metadata doesn't change very often,
+
+00:10:01.340 --> 00:10:04.079
+Emms builds a cache as it extracts
+
+00:10:04.080 --> 00:10:06.859
+the information from each file.
+
+00:10:06.860 --> 00:10:09.879
+The first time loading of thousands of tracks
+
+00:10:09.880 --> 00:10:13.259
+into the emms cache may take a while,
+
+00:10:13.260 --> 00:10:16.999
+but as is the nature of caching, subsequent loads
+
+00:10:17.000 --> 00:10:20.059
+will be nearly instantaneous.
+
+00:10:20.060 --> 00:10:22.719
+To ease loading huge media collections,
+
+00:10:22.720 --> 00:10:26.519
+emms also can populate the cache asynchronously,
+
+00:10:26.520 --> 00:10:30.519
+so that your emacs isn't locked up in the interim.
+
+00:10:30.520 --> 00:10:33.779
+Let's talk about streams and URLs.
+
+00:10:33.780 --> 00:10:37.619
+Not all playlist entries need to be associated with files.
+
+00:10:37.620 --> 00:10:39.839
+It's possible to add streaming playlists
+
+00:10:39.840 --> 00:10:42.639
+and URLs to any playlist.
+
+00:10:42.640 --> 00:10:46.119
+Emms also comes with a built-in eclectic list
+
+00:10:46.120 --> 00:10:50.039
+of streaming audio stations to get you started.
+
+00:10:50.040 --> 00:10:52.639
+Any playlist entry can be a URL,
+
+00:10:52.640 --> 00:10:56.719
+and that URL will be passed on to the media player backend,
+
+00:10:56.720 --> 00:11:01.199
+which can play it, if any.
+
+NOTE Meta-playlist mode
+
+00:11:01.200 --> 00:11:03.679
+Meta-playlist mode:
+
+00:11:03.680 --> 00:11:08.299
+Emms also has meta-playlist mode
+
+00:11:08.300 --> 00:11:11.959
+to help manage multiple playlists.
+
+00:11:11.960 --> 00:11:13.879
+When you invoke meta-playlist mode,
+
+00:11:13.880 --> 00:11:16.959
+you will see a listing of all of the current Emms playlists,
+
+00:11:16.960 --> 00:11:21.999
+and this mode binds a handful of useful keybindings
+
+00:11:22.000 --> 00:11:29.859
+to help manage those playlists.
+
+NOTE The browser
+
+00:11:29.860 --> 00:11:31.759
+The Browser:
+
+00:11:31.760 --> 00:11:35.439
+Music doesn't always lend itself to being viewed
+
+00:11:35.440 --> 00:11:38.199
+as a series of discrete files.
+
+00:11:38.200 --> 00:11:41.559
+While there may be a good taxonomy of music
+
+00:11:41.560 --> 00:11:45.459
+that can be reflected using directories and filenames,
+
+00:11:45.460 --> 00:11:49.099
+there are other aspects which cannot.
+
+00:11:49.100 --> 00:11:51.599
+This is especially true when you consider that
+
+00:11:51.600 --> 00:11:55.299
+unlike many computer file taxonomies,
+
+00:11:55.300 --> 00:11:56.719
+music files may contain
+
+00:11:56.720 --> 00:11:58.759
+a lot of self-descriptive information
+
+00:11:58.760 --> 00:12:00.619
+in the form of metadata,
+
+00:12:00.620 --> 00:12:04.279
+such as the year a work was published, the composer,
+
+00:12:04.280 --> 00:12:07.519
+the performing artist, etc.
+
+00:12:07.520 --> 00:12:11.079
+Therefore, it makes sense for Emms to enable
+
+00:12:11.080 --> 00:12:13.199
+a different view into a media collection
+
+00:12:13.200 --> 00:12:17.059
+which is based on the cached metadata.
+
+00:12:17.060 --> 00:12:19.839
+The browser interface binds a host of keys
+
+00:12:19.840 --> 00:12:22.079
+to help navigate the tree structure
+
+00:12:22.080 --> 00:12:24.539
+of the metadata information.
+
+00:12:24.540 --> 00:12:25.839
+Since browser display
+
+00:12:25.840 --> 00:12:28.279
+is not predicated upon directory structure,
+
+00:12:28.280 --> 00:12:32.939
+you can invoke functions such as `emms-browse-by-album`,
+
+00:12:32.940 --> 00:12:35.639
+or `emms-browse-by-artist`, etc.
+
+00:12:35.640 --> 00:12:42.179
+to view the collection in different ways.
+
+00:12:42.180 --> 00:12:43.759
+Emms can do a lot more,
+
+00:12:43.760 --> 00:12:46.319
+but covering it all would take too much time.
+
+00:12:47.020 --> 00:12:50.239
+I do recommend opening the fine Emms manual
+
+00:12:50.240 --> 00:12:52.319
+and getting to know some additional features
+
+00:12:52.320 --> 00:12:54.999
+such as sorting tracks in playlists,
+
+00:12:55.000 --> 00:12:57.199
+sorting and filtering in the browser,
+
+00:12:57.200 --> 00:12:59.079
+editing track information,
+
+00:12:59.080 --> 00:13:01.919
+deriving a new playlist from an existing playlist,
+
+00:13:01.920 --> 00:13:07.039
+the music player daemon, lyrics display, volume control,
+
+00:13:07.040 --> 00:13:13.359
+bookmarks, GNU FM, and Dbus/Mpris support.
+
+00:13:13.360 --> 00:13:19.919
+I hope this was a useful introduction to Emms.
+
+NOTE How Emms works: The technical part
+
+00:13:19.920 --> 00:13:23.219
+How Emms Works: The technical part:
+
+00:13:23.220 --> 00:13:26.819
+This part is an overview of how Emms works.
+
+00:13:26.820 --> 00:13:29.759
+By the end of this, you should be familiar enough
+
+00:13:29.760 --> 00:13:34.739
+with Emms internals to hack on it. Hint hint.
+
+00:13:34.740 --> 00:13:37.679
+A short history of Emms
+
+00:13:37.680 --> 00:13:42.939
+Emms is 20 years old as of the time of writing.
+
+00:13:42.940 --> 00:13:45.399
+Old enough to drink in many countries.
+
+00:13:45.400 --> 00:13:48.879
+This means it was developed back in 2003
+
+00:13:48.880 --> 00:13:53.439
+for emacs 21.2 or thereabouts.
+
+00:13:53.440 --> 00:13:56.279
+As developers, we don't go around looking to
+
+00:13:56.280 --> 00:13:58.839
+replace code just because it's old.
+
+00:13:58.840 --> 00:14:01.839
+On the other hand, some parts were inadequate
+
+00:14:01.840 --> 00:14:04.919
+or just didn't age gracefully.
+
+00:14:04.920 --> 00:14:10.359
+And we have been partially or completely rewriting those.
+
+00:14:10.360 --> 00:14:13.719
+I became the maintainer of Emms about a decade ago,
+
+00:14:13.720 --> 00:14:16.099
+but I didn't start the project.
+
+00:14:16.100 --> 00:14:21.019
+Jorgen Schäfer started the project.
+
+00:14:21.020 --> 00:14:22.519
+I reached out to Jorgen
+
+00:14:22.520 --> 00:14:25.619
+and he kindly shared some of his recollections.
+
+00:14:25.620 --> 00:14:28.199
+Jorgen states that Emms was born back
+
+00:14:28.200 --> 00:14:31.279
+when the music format wars raged.
+
+00:14:31.280 --> 00:14:38.699
+MP3 was the standard, but overshadowed with patent issues.
+
+00:14:38.700 --> 00:14:42.479
+In fact, Technicolor and Fraunhofer IIS
+
+00:14:42.480 --> 00:14:45.559
+only stopped licensing their patents for MP3
+
+00:14:45.560 --> 00:14:49.359
+as recently as April of 2017.
+
+00:14:49.360 --> 00:14:53.539
+Jorgen said that, and I quote,
+
+00:14:53.540 --> 00:14:56.079
+"I needed a tool that was player agnostic
+
+00:14:56.080 --> 00:14:59.439
+and that could deal with a large collection of music files.
+
+00:14:59.440 --> 00:15:02.799
+And I did not want any of the GUI music players
+
+00:15:02.800 --> 00:15:04.039
+that existed back then.
+
+00:15:04.040 --> 00:15:07.519
+Primarily, actually, because I did not want
+
+00:15:07.520 --> 00:15:11.399
+to be switching windows to skip to the next song.
+
+00:15:11.400 --> 00:15:12.879
+If I remember correctly,
+
+00:15:12.880 --> 00:15:16.279
+I had just a shell script before that.
+
+00:15:16.280 --> 00:15:20.159
+But I figured I lived in Emacs, so why not write a tool
+
+00:15:20.160 --> 00:15:23.039
+that I can control my music from Emacs
+
+00:15:23.040 --> 00:15:27.759
+without ever having to leave Emacs?" Unquote.
+
+00:15:27.760 --> 00:15:32.119
+We can see that Jorgen's motivations were of the best kind,
+
+00:15:32.120 --> 00:15:35.319
+to stay in Emacs.
+
+00:15:35.320 --> 00:15:40.679
+Emms, an architecture of sensible abstractions.
+
+00:15:40.680 --> 00:15:44.039
+Emms can be divided into a number of parts.
+
+00:15:44.040 --> 00:15:48.119
+The core, tracks, playlists, sources, players,
+
+00:15:48.120 --> 00:15:51.759
+info, cache, and ancillary.
+
+00:15:51.760 --> 00:15:53.679
+Now David J. Wheeler once said
+
+00:15:53.680 --> 00:15:55.999
+that all problems in computer science
+
+00:15:56.000 --> 00:15:59.799
+can be solved by another level of indirection,
+
+00:15:59.800 --> 00:16:01.639
+except of course for the problem
+
+00:16:01.640 --> 00:16:04.419
+of too many layers of indirection.
+
+00:16:04.420 --> 00:16:06.999
+Emms core has survived this long
+
+00:16:07.000 --> 00:16:11.619
+because it makes sensible and flexible coding abstractions.
+
+00:16:11.620 --> 00:16:15.499
+Keep this in mind as we explore the implementation.
+
+00:16:15.500 --> 00:16:18.879
+This following part of the talk will also be invaluable
+
+00:16:18.880 --> 00:16:21.559
+if you want to hack on Emacs.
+
+00:16:21.560 --> 00:16:23.819
+Another hint.
+
+NOTE The Emms core
+
+00:16:23.820 --> 00:16:25.359
+The Emms core.
+
+00:16:25.360 --> 00:16:29.079
+The core defines tracks, playlists,
+
+00:16:29.080 --> 00:16:31.759
+a way to start and stop playback,
+
+00:16:31.760 --> 00:16:36.439
+as well as ways to proceed to the next track.
+
+NOTE Tracks
+
+00:16:36.440 --> 00:16:38.459
+Tracks:
+
+00:16:38.460 --> 00:16:44.779
+Emms tracks consist of a list whose CAR is the symbol track,
+
+00:16:44.780 --> 00:16:47.079
+and CADR is an alist starting with
+
+00:16:47.080 --> 00:16:50.639
+the association of `type'.
+
+00:16:50.640 --> 00:16:56.739
+Type can be something like file, streamlist, URL, etc.
+
+00:16:56.740 --> 00:17:00.079
+A track of classical music from Bach's Art of Fugue
+
+00:17:00.080 --> 00:17:04.379
+may look something like this.
+
+00:17:04.380 --> 00:17:07.599
+While a track may contain many associations,
+
+00:17:07.600 --> 00:17:11.079
+the number of associations remains a small constant
+
+00:17:11.080 --> 00:17:14.199
+from the perspective of computational steps required
+
+00:17:14.200 --> 00:17:18.459
+to find any particular association.
+
+NOTE Playlist
+
+00:17:18.460 --> 00:17:20.619
+Playlist:
+
+00:17:20.620 --> 00:17:23.479
+An Emms playlist consists of an Emacs buffer
+
+00:17:23.480 --> 00:17:26.459
+with a buffer-local non-nil variable,
+
+00:17:26.460 --> 00:17:29.819
+`emms-playlist-buffer-p`.
+
+00:17:29.820 --> 00:17:33.719
+The buffer can contain anything, any amount or type of text,
+
+00:17:33.720 --> 00:17:35.959
+or anything else.
+
+00:17:35.960 --> 00:17:40.499
+Emms tracks are stored in text properties within the buffer,
+
+00:17:40.500 --> 00:17:46.399
+with the unimaginatively named text property `emms-track`.
+
+00:17:46.400 --> 00:17:49.239
+For Emms, to go to the next track consists of
+
+00:17:49.240 --> 00:17:52.839
+nothing more than looking for the next text property change
+
+00:17:52.840 --> 00:17:57.179
+containing `emms-track`, wherever that is.
+
+00:17:57.180 --> 00:18:00.239
+That means that there is a healthy decoupling between
+
+00:18:00.540 --> 00:18:03.839
+the visual representation of a playlist
+
+00:18:03.840 --> 00:18:08.259
+and its contents as far as Emms is concerned.
+
+00:18:08.260 --> 00:18:11.599
+This decoupling allows Emms playlist buffers
+
+00:18:11.600 --> 00:18:15.319
+to look like anything as long as that anything consists of
+
+00:18:15.320 --> 00:18:22.079
+one or more `emms-track` text properties.
+
+NOTE Sources
+
+00:18:22.080 --> 00:18:23.579
+Sources:
+
+00:18:23.580 --> 00:18:25.839
+A source is how you tell Emms:
+
+00:18:25.840 --> 00:18:29.779
+"Go and get those things and turn them into tracks."
+
+00:18:29.780 --> 00:18:34.479
+More specifically, an Emms source is a function called in
+
+00:18:34.480 --> 00:18:37.259
+a playlist buffer in order to add tracks.
+
+00:18:37.260 --> 00:18:40.199
+And even more specifically, a source is really
+
+00:18:40.200 --> 00:18:42.679
+a family of related functions
+
+00:18:42.680 --> 00:18:47.679
+defined by the macro `define-emms-source`.
+
+00:18:47.680 --> 00:18:49.959
+A straightforward example
+
+00:18:49.960 --> 00:18:52.959
+is the function `emms-add-directory`,
+
+00:18:52.960 --> 00:18:55.879
+which adds an entire directory of files
+
+00:18:55.880 --> 00:18:57.439
+to the current playlist.
+
+00:18:57.440 --> 00:19:02.319
+It accepts, or interactively queries for, a directory
+
+00:19:02.320 --> 00:19:06.119
+and iterates over each file in that directory,
+
+00:19:06.120 --> 00:19:10.759
+adding them as tracks to the playlist buffer as it goes.
+
+00:19:10.760 --> 00:19:15.039
+Emms comes with sources for files, directories, URLs,
+
+00:19:15.040 --> 00:19:17.319
+playlists of various formats,
+
+00:19:17.320 --> 00:19:22.159
+files from dired mode, and etc.
+
+NOTE Players
+
+00:19:22.160 --> 00:19:24.879
+Players:
+
+00:19:24.880 --> 00:19:28.959
+An Emms player is, at its simplest, a data structure
+
+00:19:28.960 --> 00:19:30.839
+with three functions.
+
+00:19:30.840 --> 00:19:34.519
+One to start playing, one to stop,
+
+00:19:34.520 --> 00:19:38.179
+and one which returns true if the player knows
+
+00:19:38.180 --> 00:19:41.279
+how to play a given track.
+
+00:19:41.280 --> 00:19:44.759
+However, if your player also knows how to pause, resume,
+
+00:19:44.760 --> 00:19:48.279
+seek, etc, then additional functions can be added
+
+00:19:48.280 --> 00:19:51.319
+to the player data structure.
+
+00:19:51.320 --> 00:19:55.399
+This is abstract enough to be able to, for example,
+
+00:19:55.400 --> 00:19:58.839
+define a simple player for images with the help of
+
+00:19:58.840 --> 00:20:04.579
+the `define-emms-simple-player` macro.
+
+00:20:04.580 --> 00:20:09.559
+The above will define a player called `emms-player-display`,
+
+00:20:09.560 --> 00:20:12.959
+which would call ImageMagick's `display` command
+
+00:20:12.960 --> 00:20:15.639
+on each file in our playlist
+
+00:20:15.640 --> 00:20:20.519
+with the image file extension we listed.
+
+NOTE Info
+
+00:20:20.520 --> 00:20:23.059
+Info:
+
+00:20:23.060 --> 00:20:28.019
+As previously described, Emms comes with info methods,
+
+00:20:28.020 --> 00:20:29.639
+which are functions to add
+
+00:20:29.640 --> 00:20:32.339
+descriptive information to tracks.
+
+00:20:32.340 --> 00:20:34.639
+Emms is set up so that
+
+00:20:34.640 --> 00:20:37.719
+the hook `emms-track-initialize-functions` is called
+
+00:20:37.720 --> 00:20:41.639
+when a track is created, and that ends up calling
+
+00:20:41.640 --> 00:20:46.279
+the info methods listed in the `emms-info-functions` list.
+
+00:20:46.280 --> 00:20:51.199
+These will modify the track data structure to add metadata.
+
+00:20:51.200 --> 00:20:54.319
+One of the coolest recent features of Emms
+
+00:20:54.320 --> 00:20:58.699
+is `emms-info-native`, written by Petteri Hintsanen;
+
+00:20:58.700 --> 00:21:01.325
+again, sorry for the pronunciation.
+
+00:21:01.326 --> 00:21:06.519
+`emms-info-native` is a purely Emacs Lisp implementation
+
+00:21:06.520 --> 00:21:11.439
+which reads Ogg Vorbis, Ogg Opus, FLAC, and MP3 files
+
+00:21:11.440 --> 00:21:14.679
+and parses out the metadata.
+
+00:21:14.680 --> 00:21:17.519
+This is in comparison with other info readers
+
+00:21:17.520 --> 00:21:20.559
+which Emms supports, which all involve calling out
+
+00:21:20.560 --> 00:21:25.619
+to external processes and parsing the values returned.
+
+00:21:25.620 --> 00:21:29.319
+`emms-info-native` works by unpacking and examining
+
+00:21:29.320 --> 00:21:32.039
+the binary data in the media file headers
+
+00:21:32.040 --> 00:21:36.659
+and parsing the data layout specifications.
+
+NOTE The cache
+
+00:21:36.660 --> 00:21:38.879
+The Cache:
+
+00:21:38.880 --> 00:21:43.279
+The Emms cache is a mapping between a full path name
+
+00:21:43.280 --> 00:21:45.719
+and its associated information.
+
+00:21:45.720 --> 00:21:48.199
+Once information is extracted from a file
+
+00:21:48.200 --> 00:21:50.759
+using an info method, that information is then
+
+00:21:50.760 --> 00:21:53.979
+associated with that file in the cache.
+
+00:21:53.980 --> 00:21:57.159
+One thing to bear in mind is that the caching system
+
+00:21:57.160 --> 00:21:58.359
+was originally written back
+
+00:21:58.360 --> 00:22:00.759
+when slow spinning disks were common.
+
+00:22:00.760 --> 00:22:07.519
+A 32GB SSD drive cost close to $700 in 2006,
+
+00:22:07.520 --> 00:22:10.279
+which is the equivalent of about $1,000
+
+00:22:10.280 --> 00:22:12.439
+at the time of writing.
+
+00:22:12.440 --> 00:22:15.259
+But despite the speed of modern drives,
+
+00:22:15.260 --> 00:22:17.439
+the caching system is still worth using
+
+00:22:17.440 --> 00:22:19.679
+for larger music collections.
+
+00:22:19.680 --> 00:22:22.439
+The caching system is also a prerequisite
+
+00:22:22.440 --> 00:22:26.599
+for being able to use the Emms browser.
+
+00:22:26.600 --> 00:22:30.379
+The cache implementation is relatively naive.
+
+00:22:30.380 --> 00:22:33.199
+For instance, moving a file will invalidate
+
+00:22:33.200 --> 00:22:35.799
+that cache entry for that file
+
+00:22:35.800 --> 00:22:37.579
+and will require a refresh.
+
+00:22:37.580 --> 00:22:40.599
+However, relatively little work has been done
+
+00:22:40.600 --> 00:22:42.779
+to the cache implementation over the years
+
+00:22:42.780 --> 00:22:44.999
+since it has proven to be good enough
+
+00:22:45.000 --> 00:22:47.059
+for the majority of situations.
+
+00:22:47.060 --> 00:22:51.619
+Which is to say, nobody complained.
+
+NOTE Healthy back and forth: mpv, mpd, and GNU.FM
+
+00:22:51.620 --> 00:22:56.239
+Healthy back and forth. MPV, MPD, GNU.FM
+
+00:22:56.240 --> 00:23:00.119
+Process communication with a simple media player
+
+00:23:00.120 --> 00:23:01.759
+can be as straightforward
+
+00:23:01.760 --> 00:23:03.799
+as starting an asynchronous process
+
+00:23:03.800 --> 00:23:05.799
+and waiting for that process to complete
+
+00:23:05.800 --> 00:23:07.919
+in order to move to the next track.
+
+00:23:08.620 --> 00:23:10.879
+This is how the example above
+
+00:23:10.880 --> 00:23:13.359
+with ImageMagick's display binary worked.
+
+00:23:13.760 --> 00:23:17.439
+However, Emms also handles asynchronous
+
+00:23:17.440 --> 00:23:20.299
+two-way communication with processes.
+
+00:23:20.300 --> 00:23:23.959
+A simple example of this would be sending strings
+
+00:23:23.960 --> 00:23:31.559
+to a running process such as the pause command to VLC.
+
+NOTE MPV
+
+00:23:31.560 --> 00:23:33.379
+MPV:
+
+00:23:33.380 --> 00:23:37.039
+MPV is a popular media player forked
+
+00:23:37.040 --> 00:23:39.899
+in a roundabout way from mplayer.
+
+00:23:39.900 --> 00:23:42.079
+One of its most notable features is
+
+00:23:42.080 --> 00:23:46.599
+support for a robust client API.
+
+00:23:46.600 --> 00:23:52.959
+Mike Kazantsev has been working since 2018
+
+00:23:52.960 --> 00:23:58.349
+to develop the excellent `emms-player-mpv.el'.
+
+00:23:58.350 --> 00:24:01.999
+It can communicate with a long running MPV process
+
+00:24:02.000 --> 00:24:07.179
+via Unix sockets or IP sockets.
+
+00:24:07.180 --> 00:24:11.169
+This allows for MPV to do things
+
+00:24:11.170 --> 00:24:14.889
+like update ICY metadata for streaming audio.
+
+00:24:14.890 --> 00:24:17.639
+So that, for example, when a song changes
+
+00:24:17.640 --> 00:24:22.049
+while you're listening to a streaming audio via Emms,
+
+00:24:22.050 --> 00:24:24.679
+the song title displayed in the mode line
+
+00:24:24.680 --> 00:24:28.329
+and track listing can update as well.
+
+00:24:28.330 --> 00:24:30.399
+This means that deep inside the code
+
+00:24:30.400 --> 00:24:35.629
+there is an Emacs `make-network-process` call.
+
+00:24:35.630 --> 00:24:37.919
+The fact that Mike has put this together
+
+00:24:37.920 --> 00:24:42.639
+in fewer than 1,000 lines of legible Emacs Lisp
+
+00:24:42.640 --> 00:24:47.469
+is a testament to some serious coding ability.
+
+NOTE MPD
+
+00:24:47.470 --> 00:24:49.609
+MPD:
+
+00:24:49.610 --> 00:24:52.399
+Similar to MPV but potentially
+
+00:24:52.400 --> 00:24:54.119
+on a completely different machine
+
+00:24:54.120 --> 00:24:58.459
+is Emms support for the Music Player Daemon.
+
+00:24:58.460 --> 00:25:01.519
+Music Player Daemon or MPD is a media player
+
+00:25:01.520 --> 00:25:03.959
+with an explicit client-server design
+
+00:25:03.960 --> 00:25:09.949
+and communicates with Emms via a network process.
+
+00:25:09.950 --> 00:25:16.089
+Unfortunately, MPD support has never been all that great.
+
+00:25:16.090 --> 00:25:20.469
+But this isn't the emms developers fault!
+
+00:25:20.470 --> 00:25:25.599
+Because unlike every other media player
+
+00:25:25.600 --> 00:25:29.729
+that Emms interfaces with MPD is designed around
+
+00:25:29.730 --> 00:25:31.929
+its own internal playlist database.
+
+00:25:31.930 --> 00:25:35.269
+This is a surprising design decision
+
+00:25:35.270 --> 00:25:37.649
+on the MPD developers' part
+
+00:25:37.650 --> 00:25:41.749
+since it goes against the client-server mindset.
+
+00:25:41.750 --> 00:25:45.959
+A consequence is that we end up having to try and coordinate
+
+00:25:45.960 --> 00:25:51.399
+and harmonize the MPD playlist with the Emms playlist.
+
+00:25:51.400 --> 00:25:56.689
+I can foresee writing a completely new MPD mode for Emms
+
+00:25:56.690 --> 00:26:01.509
+which is designed to be a true pure MPD client.
+
+00:26:01.510 --> 00:26:05.339
+Unless of course someone volunteers to beat me to it.
+
+00:26:05.340 --> 00:26:07.439
+Hint hint.
+
+NOTE GNU FM and Libre FM
+
+00:26:07.440 --> 00:26:10.959
+GNU FM and Libre FM:
+
+00:26:10.960 --> 00:26:13.639
+Libre FM is a music community which allows you
+
+00:26:13.640 --> 00:26:17.449
+to share your listening habits with other users of the site.
+
+00:26:17.450 --> 00:26:21.269
+A kind of online listening party.
+
+00:26:21.270 --> 00:26:25.649
+In the case of `emms-librefm-scrobber.el`
+
+00:26:25.650 --> 00:26:28.639
+we use Emacs' `url-retrieve` function
+
+00:26:28.640 --> 00:26:32.449
+to asynchronously send to a URL
+
+00:26:32.450 --> 00:26:40.049
+and then fire a callback function to process the response.
+
+00:26:40.050 --> 00:26:42.679
+This represents numerous challenges
+
+00:26:42.680 --> 00:26:45.089
+to implement within Emacs.
+
+00:26:45.090 --> 00:26:47.399
+The primary issue being that Emacs itself
+
+00:26:47.400 --> 00:26:50.099
+is pretty weak at doing anything
+
+00:26:50.100 --> 00:26:54.219
+truly and really asynchronously.
+
+00:26:54.220 --> 00:26:56.399
+I can say with confident sarcasm
+
+00:26:56.400 --> 00:26:59.529
+and with tongue firmly planted in cheek
+
+00:26:59.530 --> 00:27:02.879
+that it is almost as if the original designers
+
+00:27:02.880 --> 00:27:05.839
+of Emacs didn't foresee their text editor
+
+00:27:05.840 --> 00:27:07.039
+needing to play music
+
+00:27:07.040 --> 00:27:09.819
+while interacting with a remote network server.
+
+00:27:09.820 --> 00:27:12.559
+How myopic!
+
+NOTE How we work: Emms development
+
+00:27:12.560 --> 00:27:15.699
+How we work: Emms development:
+
+00:27:15.700 --> 00:27:19.619
+This part is an overview of how Emms is developed.
+
+00:27:19.620 --> 00:27:23.899
+By the end of this part you should be able to understand
+
+00:27:23.900 --> 00:27:28.719
+how we hacked this project, and how you can too.
+
+00:27:28.720 --> 00:27:29.949
+Where it's at.
+
+00:27:29.950 --> 00:27:32.369
+How to find our forge.
+
+00:27:32.370 --> 00:27:36.499
+Emms has been hosted at the FSF's forge, Savannah,
+
+00:27:36.500 --> 00:27:39.839
+since around 2003.
+
+00:27:39.840 --> 00:27:46.229
+Emms is distributed via GNU ELPA and integrated into Emacs.
+
+00:27:46.230 --> 00:27:49.799
+Before ELPA it was distributed as a tarball
+
+00:27:49.800 --> 00:27:55.139
+via ftp.gnu.org but that stopped back in 2020.
+
+00:27:55.140 --> 00:27:58.719
+I was initially resistant to ELPA but around the time
+
+00:27:58.720 --> 00:28:03.849
+when the thousandth person asked me why Emms isn't on ELPA,
+
+00:28:03.850 --> 00:28:07.209
+I realized that it had to happen.
+
+00:28:07.210 --> 00:28:10.599
+Emms can also be found in other places
+
+00:28:10.600 --> 00:28:16.079
+such as Melpa or GitHub but we, the developers of Emms,
+
+00:28:16.080 --> 00:28:17.999
+have nothing to do with that
+
+00:28:18.000 --> 00:28:21.759
+and we don't monitor those channels.
+
+00:28:21.760 --> 00:28:26.299
+If you want the source straight from, well, the source,
+
+00:28:26.300 --> 00:28:30.369
+then go to the Savannah Git repository.
+
+00:28:30.370 --> 00:28:34.989
+Look who's talking: Where development discussion happens.
+
+00:28:34.990 --> 00:28:37.999
+If you want to talk to us, discussions all happen
+
+00:28:38.000 --> 00:28:41.429
+on emms-help@gnu.org.
+
+00:28:41.430 --> 00:28:45.559
+We used to use emms-patches@gnu.org
+
+00:28:45.560 --> 00:28:48.279
+but didn't feel like the volume of incoming patches
+
+00:28:48.280 --> 00:28:52.589
+justified a separate mailing list.
+
+NOTE The Rime Of The Ancient Maintainer
+
+00:28:52.590 --> 00:28:55.719
+The Rime Of The Ancient Maintainer:
+
+00:28:55.720 --> 00:28:57.479
+There are a number of activities
+
+00:28:57.480 --> 00:29:00.099
+particular to being a maintainer.
+
+00:29:00.100 --> 00:29:03.389
+These are all part of a project's lifecycle.
+
+00:29:03.390 --> 00:29:06.079
+Let's review some of them.
+
+NOTE The life and times of an Emms patch
+
+00:29:06.080 --> 00:29:09.999
+The life and times of an Emms patch:
+
+00:29:10.000 --> 00:29:13.239
+A maintainer needs to be able to accept, critique,
+
+00:29:13.240 --> 00:29:17.559
+and integrate patches from contributors and developers.
+
+00:29:17.560 --> 00:29:20.559
+This means, among other things, that the maintainer
+
+00:29:20.560 --> 00:29:24.469
+needs to keep on top of copyright issues.
+
+00:29:24.470 --> 00:29:29.359
+Before being able to add Emms to GNU/ELPA,
+
+00:29:29.360 --> 00:29:31.879
+we had to make sure that the copyright situation
+
+00:29:31.880 --> 00:29:33.849
+was in order.
+
+00:29:33.850 --> 00:29:37.519
+This long process required reaching out to people
+
+00:29:37.520 --> 00:29:39.959
+and having them assign the copyright
+
+00:29:39.960 --> 00:29:42.509
+for their work to the FSF,
+
+00:29:42.510 --> 00:29:45.199
+or even removing their code entirely
+
+00:29:45.200 --> 00:29:47.969
+if they couldn't be reached.
+
+00:29:47.970 --> 00:29:50.629
+The experience left me with the conviction
+
+00:29:50.630 --> 00:29:52.399
+that the easiest way to fix
+
+00:29:52.400 --> 00:29:54.519
+the copyright situation of your package
+
+00:29:54.520 --> 00:30:00.639
+is to ensure that it never gets broken in the first place.
+
+00:30:00.640 --> 00:30:04.439
+Often a person will write in to the emms-help mailing list,
+
+00:30:04.440 --> 00:30:08.029
+or perhaps raise an issue on IRC.
+
+00:30:08.030 --> 00:30:11.679
+If it's a bug report or feature request, we'll discuss it,
+
+00:30:11.680 --> 00:30:14.159
+and when it's fixed, we'll ask the reporter
+
+00:30:14.160 --> 00:30:17.639
+to test the result and provide feedback.
+
+00:30:17.640 --> 00:30:22.039
+If it's a patch, then we'll typically go one of three ways.
+
+00:30:22.040 --> 00:30:24.799
+A trivial patch, such as fixing a typo
+
+00:30:24.800 --> 00:30:27.279
+or corrections on a single line of code,
+
+00:30:27.280 --> 00:30:32.039
+will simply be applied by one of the developers.
+
+00:30:32.040 --> 00:30:34.519
+A non-trivial, but one-time patch,
+
+00:30:34.520 --> 00:30:37.989
+will have to be cleared from a copyright perspective.
+
+00:30:37.990 --> 00:30:42.419
+This means assigning copyright for the changes to the FSF.
+
+00:30:42.420 --> 00:30:46.319
+Once that's cleared, then the patch will be applied.
+
+00:30:46.320 --> 00:30:49.879
+Finally, if it's a non-trivial patch,
+
+00:30:49.880 --> 00:30:52.079
+which looks like it would be the start
+
+00:30:52.080 --> 00:30:56.009
+of a long-term development work (my favorite),
+
+00:30:56.010 --> 00:30:57.879
+then after copyright is cleared,
+
+00:30:57.880 --> 00:31:00.799
+that person will be offered to be added
+
+00:31:00.800 --> 00:31:05.019
+to the members with Git repo access on Savannah.
+
+00:31:05.020 --> 00:31:08.199
+From there, we usually use a dedicated branch
+
+00:31:08.200 --> 00:31:09.639
+to do all the playing around
+
+00:31:09.640 --> 00:31:13.629
+before merging it with the main Git repo.
+
+00:31:13.630 --> 00:31:16.879
+If you have ever sent a patch, feature request,
+
+00:31:16.880 --> 00:31:24.079
+or bug report into Emms (small or large), we thank you.
+
+NOTE Let It Go: The release process
+
+00:31:24.080 --> 00:31:27.789
+Let It Go, The Release Process:
+
+00:31:27.790 --> 00:31:31.609
+The maintainer is responsible for the release process.
+
+00:31:31.610 --> 00:31:35.129
+I found that a consistent schedule works well,
+
+00:31:35.130 --> 00:31:39.379
+which is not to say that we have to release on schedule,
+
+00:31:39.380 --> 00:31:42.759
+but that aiming for a consistent release schedule
+
+00:31:42.760 --> 00:31:46.049
+provides structure and a goal.
+
+00:31:46.050 --> 00:31:50.159
+The main Git branch in the repository is stable
+
+00:31:50.160 --> 00:31:53.239
+and more often than not of release quality.
+
+00:31:53.240 --> 00:31:56.649
+Releases are done about every three months.
+
+00:31:56.650 --> 00:31:58.999
+And with such a stable main branch,
+
+00:31:59.000 --> 00:32:02.319
+the process of releasing often involves little more
+
+00:32:02.320 --> 00:32:05.059
+than writing a NEWS entry.
+
+00:32:05.060 --> 00:32:08.439
+As a consequence, new and wonderful features
+
+00:32:08.440 --> 00:32:11.439
+which aren't quite ready for prime time
+
+00:32:11.440 --> 00:32:13.499
+when a release comes around,
+
+00:32:13.500 --> 00:32:18.199
+will remain safely in their branch on the Git repo
+
+00:32:18.200 --> 00:32:23.399
+until after the ELPA release.
+
+NOTE It Is Not In Our Stars, But In Ourselves: Future directions
+
+00:32:23.400 --> 00:32:29.629
+It Is Not In Our Stars, But In Ourselves; Future Directions:
+
+00:32:29.630 --> 00:32:34.899
+One aspect of Emms that needs to improve is ease of setup.
+
+00:32:34.900 --> 00:32:37.719
+Now that might surprise you, since at the time of writing,
+
+00:32:37.720 --> 00:32:40.069
+it's already pretty easy.
+
+00:32:40.070 --> 00:32:43.879
+But my ideal is that the user would need to do
+
+00:32:43.880 --> 00:32:46.839
+nothing at all after installation.
+
+00:32:46.840 --> 00:32:49.359
+And with that, as a goal in mind,
+
+00:32:49.360 --> 00:32:52.749
+there is more work to be done.
+
+00:32:52.750 --> 00:32:55.499
+We are working on a player discovery feature.
+
+00:32:55.500 --> 00:32:57.039
+The idea is simple.
+
+00:32:57.040 --> 00:33:00.079
+The code looks for binaries of popular media players
+
+00:33:00.080 --> 00:33:01.639
+on the user's machine,
+
+00:33:01.640 --> 00:33:04.519
+and for each one found, it asks the user
+
+00:33:04.520 --> 00:33:07.519
+if they want the associated Emms player backend
+
+00:33:07.520 --> 00:33:09.809
+to be configured.
+
+00:33:09.810 --> 00:33:12.589
+In effect, this code is already working,
+
+00:33:12.590 --> 00:33:16.289
+but currently an undocumented, unofficial feature.
+
+00:33:16.290 --> 00:33:17.719
+You can try it for yourself with
+
+00:33:17.720 --> 00:33:21.079
+`emms-setup-discover-players`.
+
+00:33:21.080 --> 00:33:22.969
+So what's the holdup?
+
+00:33:22.970 --> 00:33:26.039
+`emms-setup-discover-players` currently configures
+
+00:33:26.040 --> 00:33:27.839
+the `emms-player-list` variable,
+
+00:33:27.840 --> 00:33:29.899
+but doesn't write it to disk.
+
+00:33:29.900 --> 00:33:31.679
+And that means that the configuration
+
+00:33:31.680 --> 00:33:35.039
+isn't preserved between Emacs sessions.
+
+00:33:35.040 --> 00:33:36.899
+The question then becomes,
+
+00:33:36.900 --> 00:33:40.309
+what is the best way to preserve this setting?
+
+00:33:40.310 --> 00:33:42.599
+I personally don't like anything
+
+00:33:42.600 --> 00:33:46.199
+to edit my .emacs except me,
+
+00:33:46.200 --> 00:33:49.279
+and I wouldn't do that to anyone else.
+
+00:33:49.280 --> 00:33:55.959
+Now we already write state to the .emacs.d/emms/ directory,
+
+00:33:55.960 --> 00:33:58.359
+but that would require care not to
+
+00:33:58.360 --> 00:34:01.909
+clobber a user's existing setup.
+
+00:34:01.910 --> 00:34:04.719
+Having the user set up their system in one place,
+
+00:34:04.720 --> 00:34:08.839
+such as a .emacs or a .emmsrc,
+
+00:34:08.840 --> 00:34:11.419
+while saving state to a different place
+
+00:34:11.420 --> 00:34:14.209
+is asking for confusion.
+
+00:34:14.210 --> 00:34:16.719
+This is a good example which I bring up
+
+00:34:16.720 --> 00:34:18.399
+of where a maintainer needs to
+
+00:34:18.400 --> 00:34:21.308
+solicit opinions from developers,
+
+00:34:21.309 --> 00:34:23.899
+both the Emacs developers,
+
+00:34:23.900 --> 00:34:28.169
+asking them where packages should save state,
+
+00:34:28.170 --> 00:34:33.169
+and the Emms developers, and also users.
+
+00:34:33.170 --> 00:34:35.439
+Then, the maintainer needs to
+
+00:34:35.440 --> 00:34:38.019
+carefully choose a path forward.
+
+00:34:38.020 --> 00:34:41.559
+It is typical of the kind of issue you have to have in mind
+
+00:34:41.560 --> 00:34:44.848
+when you're maintaining a package.
+
+NOTE Development policies: Interface language
+
+00:34:44.849 --> 00:34:49.159
+Development Policies: Interface Language.
+
+00:34:49.160 --> 00:34:52.359
+A maintainer of an interactive program such as Emms
+
+00:34:52.360 --> 00:34:55.359
+needs to think about user interaction.
+
+00:34:55.360 --> 00:34:58.399
+Emms doesn't use key bindings which are familiar
+
+00:34:58.400 --> 00:35:02.719
+to people who are used to GUI media players,
+
+00:35:02.720 --> 00:35:06.559
+and that can, and has, caused friction.
+
+00:35:06.560 --> 00:35:09.959
+Some new users are confused when they press the spacebar
+
+00:35:09.960 --> 00:35:12.529
+on an entry in the Emms browser,
+
+00:35:12.530 --> 00:35:15.459
+only to find that nothing starts playing.
+
+00:35:15.460 --> 00:35:18.679
+Indeed, all that does is to expand the browser tree
+
+00:35:18.680 --> 00:35:20.469
+at that point.
+
+00:35:20.470 --> 00:35:22.999
+Then they might press RET on the same entry,
+
+00:35:23.000 --> 00:35:28.259
+and be further frustrated at the continuing silence.
+
+00:35:28.260 --> 00:35:33.399
+Since what return does is just to add that entry at point
+
+00:35:33.400 --> 00:35:36.169
+to the current playlist.
+
+00:35:36.170 --> 00:35:37.759
+The discussion then arises
+
+00:35:37.760 --> 00:35:41.819
+about how Emms should handle that situation.
+
+00:35:41.820 --> 00:35:45.559
+On one hand, we want to make it as easy as possible
+
+00:35:45.560 --> 00:35:48.819
+for new users to learn Emms,
+
+00:35:48.820 --> 00:35:52.759
+and adopt a do-what-I-mean interface approach.
+
+00:35:52.760 --> 00:35:56.749
+On the other hand, this is an Emacs project.
+
+00:35:56.750 --> 00:35:59.439
+It isn't a stand-alone GUI media player,
+
+00:35:59.440 --> 00:36:01.399
+and should integrate into Emacs,
+
+00:36:01.400 --> 00:36:05.979
+and serve Emacs users first and foremost.
+
+NOTE Development policies: Freedom
+
+00:36:05.980 --> 00:36:10.289
+Development policies: Freedom.
+
+00:36:10.290 --> 00:36:14.999
+Another maintainer job is to think of Emms' posture
+
+00:36:15.000 --> 00:36:17.379
+in regards to software freedom.
+
+00:36:17.380 --> 00:36:19.729
+Here are a few examples.
+
+00:36:19.730 --> 00:36:23.759
+Back with MP3 was still a patent encumbered format,
+
+00:36:23.760 --> 00:36:26.080
+we pushed hard for Vorbis everywhere
+
+00:36:26.081 --> 00:36:29.639
+along with the PlayOgg campaign.
+
+00:36:29.640 --> 00:36:32.699
+A then popular music streaming service,
+
+00:36:32.700 --> 00:36:34.929
+which will remain unnamed,
+
+00:36:34.930 --> 00:36:38.619
+changed their stance towards third-party applications,
+
+00:36:38.620 --> 00:36:43.129
+and required individual API keys which could not be shared.
+
+00:36:43.130 --> 00:36:45.399
+We stood firm, said "no",
+
+00:36:45.400 --> 00:36:48.669
+and removed support for that service.
+
+00:36:48.670 --> 00:36:51.359
+A recent suggestion to add support for YouTube
+
+00:36:51.360 --> 00:36:53.889
+was also nixed,
+
+00:36:53.890 --> 00:36:55.679
+because the particular backend
+
+00:36:55.680 --> 00:36:58.959
+was found to download and run proprietary javascript
+
+00:36:58.960 --> 00:37:01.849
+on the user's machine.
+
+00:37:01.850 --> 00:37:05.399
+Saying no to potentially useful or wanted features
+
+00:37:05.400 --> 00:37:07.919
+because it involves non-free software
+
+00:37:07.920 --> 00:37:13.489
+is often an unpopular decision and can alienate people.
+
+00:37:13.490 --> 00:37:15.559
+A maintainer needs to think carefully
+
+00:37:15.560 --> 00:37:17.399
+about each of these decisions,
+
+00:37:17.400 --> 00:37:21.919
+as they are rarely straightforward and one-sided.
+
+00:37:21.920 --> 00:37:25.839
+And as you see above, they also change over time
+
+00:37:25.840 --> 00:37:30.299
+and need to be re-evaluated.
+
+00:37:30.300 --> 00:37:32.999
+One of the most useful things a maintainer can do
+
+00:37:33.000 --> 00:37:35.519
+is to coordinate the development effort
+
+00:37:35.520 --> 00:37:39.229
+and help new people join the project.
+
+00:37:39.230 --> 00:37:41.839
+In light of that, if you want to work on a project
+
+00:37:41.840 --> 00:37:44.059
+which has a bit of everything,
+
+00:37:44.060 --> 00:37:47.809
+you could do worse than hacking on Emms.
+
+00:37:47.810 --> 00:37:49.719
+There is inter-process communication,
+
+00:37:49.720 --> 00:37:52.479
+displaying graphics, parsing binary files,
+
+00:37:52.480 --> 00:37:56.529
+caching, asynchronous processes, user interface design.
+
+00:37:56.530 --> 00:37:59.599
+We also are a project that insists on
+
+00:37:59.600 --> 00:38:02.959
+keeping a well-written and up-to-date manual.
+
+00:38:02.960 --> 00:38:06.759
+If you can write English or hack Emacs Lisp at all,
+
+00:38:06.760 --> 00:38:09.939
+chances are that there is something you can do for Emms.
+
+00:38:09.940 --> 00:38:12.369
+Just saying.
+
+NOTE Acknowledgements
+
+00:38:12.370 --> 00:38:14.189
+Acknowledgements:
+
+00:38:14.190 --> 00:38:18.079
+I'd like to express my deep gratitude for all of the people
+
+00:38:18.080 --> 00:38:19.559
+who have hacked on Emms
+
+00:38:19.560 --> 00:38:23.169
+during my time as a maintainer and before it.
+
+00:38:23.170 --> 00:38:25.759
+It is often the case that I'm just the person
+
+00:38:25.760 --> 00:38:28.559
+holding the rudder and steering the ship,
+
+00:38:28.560 --> 00:38:30.039
+with all of these developers
+
+00:38:30.040 --> 00:38:33.179
+rowing furiously to provide the power
+
+00:38:33.180 --> 00:38:36.369
+which actually moves the ship forward.
+
+00:38:36.370 --> 00:38:38.040
+Thank you to all.
diff --git a/2023/info/emms-after.md b/2023/info/emms-after.md
index fc154d30..d73d8141 100644
--- a/2023/info/emms-after.md
+++ b/2023/info/emms-after.md
@@ -1,6 +1,679 @@
<!-- Automatically generated by emacsconf-publish-after-page -->
+<a name="emms-mainVideo-transcript"></a>
+# Transcript
+
+[[!template new="1" text="""The Sound of Emacs, Emms, The Emacs Multimedia System.""" start="00:00:00.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Hi, I'm Yoni Rabkin and I'll be talking about Emms;""" start="00:00:05.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the Emacs Multimedia System.""" start="00:00:09.160" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""What is Emms?""" start="00:00:11.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms displays and plays media from within Emacs""" start="00:00:14.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""using a variety of external players""" start="00:00:18.120" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and from different media sources.""" start="00:00:20.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms can run as a minimalistic player""" start="00:00:23.540" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which is controlled with no more than""" start="00:00:26.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""a handful of simple M-x commands,""" start="00:00:28.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""or as a fully-fledged interactive media browser and player.""" start="00:00:31.120" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms can display album art, play streaming audio,""" start="00:00:36.060" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""tag music files, search for lyrics,""" start="00:00:40.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""provide MPD connectivity, control the volume,""" start="00:00:43.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and more. Much more.""" start="00:00:46.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The Emms project acts like Emacs in microcosm.""" start="00:00:49.620" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""It slowly but surely grows bigger""" start="00:00:53.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and gets ever more features.""" start="00:00:56.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Perhaps Emms will one day even have a text editor.""" start="00:00:58.480" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""The structure of this talk:""" start="00:01:03.320" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""We'll start with an introduction to Emms.""" start="00:01:05.600" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This is the practical part.""" start="00:01:08.160" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Then, a bit about how Emms works. That's the technical part.""" start="00:01:10.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Finally, how we work. All about Emms development.""" start="00:01:15.880" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""Introduction to Emms: The practical part:""" start="00:01:21.320" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""I want this talk to be of immediate use to people,""" start="00:01:25.021" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""so I'm going to present a quick TL;DR of the Emms manual""" start="00:01:28.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""concerning installation and use.""" start="00:01:33.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""By the end of this part you should be able to""" start="00:01:36.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""install, configure, and use Emms in a variety of ways.""" start="00:01:38.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Where can I get Emms?""" start="00:01:45.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms is distributed primarily via GNU ELPA.""" start="00:01:48.120" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""So it's really only a M-x list-packages away at any moment.""" start="00:01:54.320" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""There's also a website hosted at gnu.org.""" start="00:02:02.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Among other things on the website, you'll find""" start="00:02:07.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""a copy of the friendly, robust, and up-to-date user manual.""" start="00:02:11.020" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Installing Emms has become progressively easier over time""" start="00:02:21.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and will continue to get easier.""" start="00:02:25.920" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""In the bad old days, it required downloading a tarball""" start="00:02:28.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and compiling a C language shim""" start="00:02:32.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to enable reading metadata from media files.""" start="00:02:35.060" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""But those days are long gone, and installing Emms is now""" start="00:02:38.920" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""as easy as invoking M-x list-packages,""" start="00:02:43.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""installing the Emms package, and placing as few as""" start="00:02:47.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""2 or 3 lines of configuration in your Emacs initialization.""" start="00:02:51.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""So after the package is installed via ELPA,""" start="00:02:57.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""you can add these few lines.""" start="00:03:02.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""`emms-all` will make available all of the stable features""" start="00:03:08.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which are shipped with Emms.""" start="00:03:12.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The `emms-player-list` variable is a list of players""" start="00:03:15.740" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""like MPV, MPlayer, VLC, etc.""" start="00:03:20.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms will call and control these external players""" start="00:03:25.600" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to play your media.""" start="00:03:29.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The variable `emms-info-functions` is a list of ways""" start="00:03:32.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""for Emms to read the metadata in your media files""" start="00:03:36.660" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""so that Emms can display song title, artist name,""" start="00:03:40.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""year of production, etc.""" start="00:03:45.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The `emms-info-native` feature in the setup example""" start="00:03:49.480" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""is the built-in metadata reader""" start="00:03:55.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""written entirely in Emacs Lisp.""" start="00:03:58.160" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""But there are also other backends""" start="00:04:01.800" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which can call external programs for info""" start="00:04:04.240" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""such as TinyTag, the TagLib library, exiftool, and so on.""" start="00:04:07.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""You can then old-school restart your Emacs""" start="00:04:14.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""or simply evaluate the above couple of lines to get going.""" start="00:04:17.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Now that we have Emms installed and configured,""" start="00:04:22.800" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""we should load some media for player.""" start="00:04:26.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""There are multiple ways to load media into Emms for playing.""" start="00:04:29.240" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""They can be directories with local files,""" start="00:04:32.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""synchronized from a remote instance of""" start="00:04:36.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""a music player daemon, PLS or M3U playlists,""" start="00:04:38.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""a list of URLs for streaming,""" start="00:04:44.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""or even Emms' own native playlist format""" start="00:04:47.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which is unsurprisingly a just serialized Emacs Lisp.""" start="00:04:51.120" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""No matter how you add tracks to Emms,""" start="00:04:57.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""you'll end up with a playlist.""" start="00:05:00.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A fundamental strength of Emms is that each playlist""" start="00:05:03.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""is a regular Emacs buffer and the track listing therein""" start="00:05:08.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""is nothing more than text lines with property overlays.""" start="00:05:13.480" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This means that you can navigate, search, copy,""" start="00:05:17.860" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and edit an Emms playlist buffer""" start="00:05:21.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""just as you would any Emacs buffer.""" start="00:05:24.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""If you want to reorganize the tracks in the playlist,""" start="00:05:28.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""then you can simply kill yank the tracks""" start="00:05:31.320" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""just as you would any buffer with lines of text,""" start="00:05:33.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and the same can be done between multiple playlist buffers.""" start="00:05:36.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""One of the most straightforward ways to add media""" start="00:05:42.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""is to invoke a command like `M-x emms-add-directory-tree`.""" start="00:05:46.120" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""You can point it to the top of a set of directories""" start="00:05:51.940" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""with playable files for Emms to traverse.""" start="00:05:55.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Another rather convenient method is to mark files in Dired""" start="00:06:00.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and to invoke `emms-add-dired`.""" start="00:06:05.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""I definitely use this one a lot.""" start="00:06:09.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The Emms playlist mode binds""" start="00:06:11.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""a number of useful keys and commands.""" start="00:06:16.120" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""It's highly recommended that you either""" start="00:06:19.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""read the friendly manual""" start="00:06:23.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""or hit &quot;C-h m&quot; in a playlist buffer to discover them.""" start="00:06:25.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Now we have a playlist buffer with a number of tracks,""" start="00:06:32.320" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""so the next step is going to be playback.""" start="00:06:35.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms can be used as a minimalistic player""" start="00:06:40.820" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""with nothing more than a handful of commands.""" start="00:06:44.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Once there is a current Emms playlist,""" start="00:06:48.320" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""invoking emms-start will begin playing the current track.""" start="00:06:51.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Now of course in a new playlist""" start="00:06:57.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""that would be the first track.""" start="00:07:00.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Now emms-next, emms-pause, and emms-stop""" start="00:07:02.580" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""do exactly what you think they do.""" start="00:07:07.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""To visit the current playlist,""" start="00:07:11.260" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""you can invoke M-x emms-playlist-mode-go,""" start="00:07:13.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which is a long command I personally bind to &quot;M-f12&quot;.""" start="00:07:17.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""You'll be taken to the current playlist buffer.""" start="00:07:22.700" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""While you can have multiple playlist buffers,""" start="00:07:25.320" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""only one is current for the purposes of playback commands.""" start="00:07:29.240" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The playlist buffer has keys bound""" start="00:07:35.780" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to control the media being played.""" start="00:07:38.120" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""`emms-seek-forward` and `emms-seek-backwards` allow you""" start="00:07:39.920" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to scrub along the media being played.""" start="00:07:44.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Which commands are available is a function of""" start="00:07:49.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the player backend being employed.""" start="00:07:51.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The simplest of players may have nothing more""" start="00:07:54.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""than the ability to play, stop, and seek,""" start="00:07:56.600" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""but others may implement a plethora of commands.""" start="00:07:59.560" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""The Modeline: Emms will by default display""" start="00:08:04.240" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the name of the currently playing track in the mode line""" start="00:08:08.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""with information such as playing time.""" start="00:08:11.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The mode line format is controlled""" start="00:08:15.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""via the `emms-mode-line-format` variable""" start="00:08:15.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and the `emms-mode-line-playlist-current` function.""" start="00:08:20.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Metadata and the cache.""" start="00:08:27.140" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""It would be sufficient for emms to simply list""" start="00:08:31.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the file names or urls of each piece of media,""" start="00:08:34.800" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""but unless you name your music and media""" start="00:08:38.620" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""with obsessive consistency and precision,""" start="00:08:41.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""not that there is anything wrong with that""" start="00:08:43.940" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""then the resulting list will be a bit of an eyesore.""" start="00:08:46.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Moreover, there are a lot of other useful metadata""" start="00:08:50.860" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""in the media files, including cool stuff like album art.""" start="00:08:54.120" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""So instead of just files, Emms will try""" start="00:08:58.620" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to extract metadata from each track""" start="00:09:01.920" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and display a nicely-formatted track listing.""" start="00:09:04.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The format can be controlled by customizing""" start="00:09:08.220" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the variable `emms-track-description-function`.""" start="00:09:10.800" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms uses so-called info methods to extract""" start="00:09:15.460" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the metadata from each file.""" start="00:09:19.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""`emms-info-native`, which I mentioned before,""" start="00:09:22.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""is the built-in metadata reader written in Emacs Lisp.""" start="00:09:25.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""It provides support for Ogg Vorbis, Ogg Opus, FLAC, and MP3.""" start="00:09:30.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""However, if you have media in other formats,""" start="00:09:37.660" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""you can also add info methods""" start="00:09:40.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to the `emms-info-functions` list,""" start="00:09:42.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which call external programs such as exiftool,""" start="00:09:45.240" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the LibTag library, tiny-tag, etc. to read file metadata.""" start="00:09:48.700" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Since reading metadata takes time""" start="00:09:55.420" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and that metadata doesn't change very often,""" start="00:09:58.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms builds a cache as it extracts""" start="00:10:01.340" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the information from each file.""" start="00:10:04.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The first time loading of thousands of tracks""" start="00:10:06.860" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""into the emms cache may take a while,""" start="00:10:09.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""but as is the nature of caching, subsequent loads""" start="00:10:13.260" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""will be nearly instantaneous.""" start="00:10:17.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""To ease loading huge media collections,""" start="00:10:20.060" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""emms also can populate the cache asynchronously,""" start="00:10:22.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""so that your emacs isn't locked up in the interim.""" start="00:10:26.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Let's talk about streams and URLs.""" start="00:10:30.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Not all playlist entries need to be associated with files.""" start="00:10:33.780" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""It's possible to add streaming playlists""" start="00:10:37.620" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and URLs to any playlist.""" start="00:10:39.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms also comes with a built-in eclectic list""" start="00:10:42.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""of streaming audio stations to get you started.""" start="00:10:46.120" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Any playlist entry can be a URL,""" start="00:10:50.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and that URL will be passed on to the media player backend,""" start="00:10:52.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which can play it, if any.""" start="00:10:56.720" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""Meta-playlist mode:""" start="00:11:01.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms also has meta-playlist mode""" start="00:11:03.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to help manage multiple playlists.""" start="00:11:08.300" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""When you invoke meta-playlist mode,""" start="00:11:11.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""you will see a listing of all of the current Emms playlists,""" start="00:11:13.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and this mode binds a handful of useful keybindings""" start="00:11:16.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to help manage those playlists.""" start="00:11:22.000" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""The Browser:""" start="00:11:29.860" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Music doesn't always lend itself to being viewed""" start="00:11:31.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""as a series of discrete files.""" start="00:11:35.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""While there may be a good taxonomy of music""" start="00:11:38.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""that can be reflected using directories and filenames,""" start="00:11:41.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""there are other aspects which cannot.""" start="00:11:45.460" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This is especially true when you consider that""" start="00:11:49.100" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""unlike many computer file taxonomies,""" start="00:11:51.600" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""music files may contain""" start="00:11:55.300" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""a lot of self-descriptive information""" start="00:11:56.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""in the form of metadata,""" start="00:11:58.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""such as the year a work was published, the composer,""" start="00:12:00.620" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the performing artist, etc.""" start="00:12:04.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Therefore, it makes sense for Emms to enable""" start="00:12:07.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""a different view into a media collection""" start="00:12:11.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which is based on the cached metadata.""" start="00:12:13.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The browser interface binds a host of keys""" start="00:12:17.060" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to help navigate the tree structure""" start="00:12:19.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""of the metadata information.""" start="00:12:22.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Since browser display""" start="00:12:24.540" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""is not predicated upon directory structure,""" start="00:12:25.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""you can invoke functions such as `emms-browse-by-album`,""" start="00:12:28.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""or `emms-browse-by-artist`, etc.""" start="00:12:32.940" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to view the collection in different ways.""" start="00:12:35.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms can do a lot more,""" start="00:12:42.180" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""but covering it all would take too much time.""" start="00:12:43.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""I do recommend opening the fine Emms manual""" start="00:12:47.020" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and getting to know some additional features""" start="00:12:50.240" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""such as sorting tracks in playlists,""" start="00:12:52.320" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""sorting and filtering in the browser,""" start="00:12:55.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""editing track information,""" start="00:12:57.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""deriving a new playlist from an existing playlist,""" start="00:12:59.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the music player daemon, lyrics display, volume control,""" start="00:13:01.920" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""bookmarks, GNU FM, and Dbus/Mpris support.""" start="00:13:07.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""I hope this was a useful introduction to Emms.""" start="00:13:13.360" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""How Emms Works: The technical part:""" start="00:13:19.920" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This part is an overview of how Emms works.""" start="00:13:23.220" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""By the end of this, you should be familiar enough""" start="00:13:26.820" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""with Emms internals to hack on it. Hint hint.""" start="00:13:29.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A short history of Emms""" start="00:13:34.740" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms is 20 years old as of the time of writing.""" start="00:13:37.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Old enough to drink in many countries.""" start="00:13:42.940" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This means it was developed back in 2003""" start="00:13:45.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""for emacs 21.2 or thereabouts.""" start="00:13:48.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""As developers, we don't go around looking to""" start="00:13:53.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""replace code just because it's old.""" start="00:13:56.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""On the other hand, some parts were inadequate""" start="00:13:58.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""or just didn't age gracefully.""" start="00:14:01.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""And we have been partially or completely rewriting those.""" start="00:14:04.920" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""I became the maintainer of Emms about a decade ago,""" start="00:14:10.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""but I didn't start the project.""" start="00:14:13.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Jorgen Schäfer started the project.""" start="00:14:16.100" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""I reached out to Jorgen""" start="00:14:21.020" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and he kindly shared some of his recollections.""" start="00:14:22.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Jorgen states that Emms was born back""" start="00:14:25.620" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""when the music format wars raged.""" start="00:14:28.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""MP3 was the standard, but overshadowed with patent issues.""" start="00:14:31.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""In fact, Technicolor and Fraunhofer IIS""" start="00:14:38.700" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""only stopped licensing their patents for MP3""" start="00:14:42.480" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""as recently as April of 2017.""" start="00:14:45.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Jorgen said that, and I quote,""" start="00:14:49.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""&quot;I needed a tool that was player agnostic""" start="00:14:53.540" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and that could deal with a large collection of music files.""" start="00:14:56.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""And I did not want any of the GUI music players""" start="00:14:59.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""that existed back then.""" start="00:15:02.800" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Primarily, actually, because I did not want""" start="00:15:04.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to be switching windows to skip to the next song.""" start="00:15:07.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""If I remember correctly,""" start="00:15:11.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""I had just a shell script before that.""" start="00:15:12.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""But I figured I lived in Emacs, so why not write a tool""" start="00:15:16.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""that I can control my music from Emacs""" start="00:15:20.160" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""without ever having to leave Emacs?&quot; Unquote.""" start="00:15:23.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""We can see that Jorgen's motivations were of the best kind,""" start="00:15:27.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to stay in Emacs.""" start="00:15:32.120" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms, an architecture of sensible abstractions.""" start="00:15:35.320" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms can be divided into a number of parts.""" start="00:15:40.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The core, tracks, playlists, sources, players,""" start="00:15:44.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""info, cache, and ancillary.""" start="00:15:48.120" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Now David J. Wheeler once said""" start="00:15:51.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""that all problems in computer science""" start="00:15:53.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""can be solved by another level of indirection,""" start="00:15:56.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""except of course for the problem""" start="00:15:59.800" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""of too many layers of indirection.""" start="00:16:01.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms core has survived this long""" start="00:16:04.420" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""because it makes sensible and flexible coding abstractions.""" start="00:16:07.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Keep this in mind as we explore the implementation.""" start="00:16:11.620" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This following part of the talk will also be invaluable""" start="00:16:15.500" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""if you want to hack on Emacs.""" start="00:16:18.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Another hint.""" start="00:16:21.560" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""The Emms core.""" start="00:16:23.820" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The core defines tracks, playlists,""" start="00:16:25.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""a way to start and stop playback,""" start="00:16:29.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""as well as ways to proceed to the next track.""" start="00:16:31.760" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""Tracks:""" start="00:16:36.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms tracks consist of a list whose CAR is the symbol track,""" start="00:16:38.460" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and CADR is an alist starting with""" start="00:16:44.780" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the association of `type'.""" start="00:16:47.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Type can be something like file, streamlist, URL, etc.""" start="00:16:50.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A track of classical music from Bach's Art of Fugue""" start="00:16:56.740" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""may look something like this.""" start="00:17:00.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""While a track may contain many associations,""" start="00:17:04.380" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the number of associations remains a small constant""" start="00:17:07.600" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""from the perspective of computational steps required""" start="00:17:11.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to find any particular association.""" start="00:17:14.200" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""Playlist:""" start="00:17:18.460" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""An Emms playlist consists of an Emacs buffer""" start="00:17:20.620" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""with a buffer-local non-nil variable,""" start="00:17:23.480" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""`emms-playlist-buffer-p`.""" start="00:17:26.460" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The buffer can contain anything, any amount or type of text,""" start="00:17:29.820" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""or anything else.""" start="00:17:33.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms tracks are stored in text properties within the buffer,""" start="00:17:35.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""with the unimaginatively named text property `emms-track`.""" start="00:17:40.500" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""For Emms, to go to the next track consists of""" start="00:17:46.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""nothing more than looking for the next text property change""" start="00:17:49.240" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""containing `emms-track`, wherever that is.""" start="00:17:52.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""That means that there is a healthy decoupling between""" start="00:17:57.180" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the visual representation of a playlist""" start="00:18:00.540" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and its contents as far as Emms is concerned.""" start="00:18:03.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This decoupling allows Emms playlist buffers""" start="00:18:08.260" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to look like anything as long as that anything consists of""" start="00:18:11.600" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""one or more `emms-track` text properties.""" start="00:18:15.320" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""Sources:""" start="00:18:22.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A source is how you tell Emms:""" start="00:18:23.580" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""&quot;Go and get those things and turn them into tracks.&quot;""" start="00:18:25.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""More specifically, an Emms source is a function called in""" start="00:18:29.780" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""a playlist buffer in order to add tracks.""" start="00:18:34.480" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""And even more specifically, a source is really""" start="00:18:37.260" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""a family of related functions""" start="00:18:40.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""defined by the macro `define-emms-source`.""" start="00:18:42.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A straightforward example""" start="00:18:47.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""is the function `emms-add-directory`,""" start="00:18:49.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which adds an entire directory of files""" start="00:18:52.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to the current playlist.""" start="00:18:55.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""It accepts, or interactively queries for, a directory""" start="00:18:57.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and iterates over each file in that directory,""" start="00:19:02.320" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""adding them as tracks to the playlist buffer as it goes.""" start="00:19:06.120" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms comes with sources for files, directories, URLs,""" start="00:19:10.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""playlists of various formats,""" start="00:19:15.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""files from dired mode, and etc.""" start="00:19:17.320" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""Players:""" start="00:19:22.160" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""An Emms player is, at its simplest, a data structure""" start="00:19:24.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""with three functions.""" start="00:19:28.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""One to start playing, one to stop,""" start="00:19:30.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and one which returns true if the player knows""" start="00:19:34.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""how to play a given track.""" start="00:19:38.180" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""However, if your player also knows how to pause, resume,""" start="00:19:41.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""seek, etc, then additional functions can be added""" start="00:19:44.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to the player data structure.""" start="00:19:48.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This is abstract enough to be able to, for example,""" start="00:19:51.320" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""define a simple player for images with the help of""" start="00:19:55.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the `define-emms-simple-player` macro.""" start="00:19:58.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The above will define a player called `emms-player-display`,""" start="00:20:04.580" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which would call ImageMagick's `display` command""" start="00:20:09.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""on each file in our playlist""" start="00:20:12.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""with the image file extension we listed.""" start="00:20:15.640" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""Info:""" start="00:20:20.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""As previously described, Emms comes with info methods,""" start="00:20:23.060" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which are functions to add""" start="00:20:28.020" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""descriptive information to tracks.""" start="00:20:29.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms is set up so that""" start="00:20:32.340" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the hook `emms-track-initialize-functions` is called""" start="00:20:34.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""when a track is created, and that ends up calling""" start="00:20:37.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the info methods listed in the `emms-info-functions` list.""" start="00:20:41.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""These will modify the track data structure to add metadata.""" start="00:20:46.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""One of the coolest recent features of Emms""" start="00:20:51.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""is `emms-info-native`, written by Petteri Hintsanen;""" start="00:20:54.320" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""again, sorry for the pronunciation.""" start="00:20:58.700" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""`emms-info-native` is a purely Emacs Lisp implementation""" start="00:21:01.326" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which reads Ogg Vorbis, Ogg Opus, FLAC, and MP3 files""" start="00:21:06.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and parses out the metadata.""" start="00:21:11.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This is in comparison with other info readers""" start="00:21:14.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which Emms supports, which all involve calling out""" start="00:21:17.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to external processes and parsing the values returned.""" start="00:21:20.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""`emms-info-native` works by unpacking and examining""" start="00:21:25.620" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the binary data in the media file headers""" start="00:21:29.320" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and parsing the data layout specifications.""" start="00:21:32.040" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""The Cache:""" start="00:21:36.660" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The Emms cache is a mapping between a full path name""" start="00:21:38.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and its associated information.""" start="00:21:43.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Once information is extracted from a file""" start="00:21:45.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""using an info method, that information is then""" start="00:21:48.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""associated with that file in the cache.""" start="00:21:50.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""One thing to bear in mind is that the caching system""" start="00:21:53.980" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""was originally written back""" start="00:21:57.160" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""when slow spinning disks were common.""" start="00:21:58.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A 32GB SSD drive cost close to $700 in 2006,""" start="00:22:00.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which is the equivalent of about $1,000""" start="00:22:07.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""at the time of writing.""" start="00:22:10.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""But despite the speed of modern drives,""" start="00:22:12.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the caching system is still worth using""" start="00:22:15.260" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""for larger music collections.""" start="00:22:17.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The caching system is also a prerequisite""" start="00:22:19.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""for being able to use the Emms browser.""" start="00:22:22.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The cache implementation is relatively naive.""" start="00:22:26.600" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""For instance, moving a file will invalidate""" start="00:22:30.380" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""that cache entry for that file""" start="00:22:33.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and will require a refresh.""" start="00:22:35.800" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""However, relatively little work has been done""" start="00:22:37.580" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to the cache implementation over the years""" start="00:22:40.600" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""since it has proven to be good enough""" start="00:22:42.780" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""for the majority of situations.""" start="00:22:45.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Which is to say, nobody complained.""" start="00:22:47.060" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""Healthy back and forth. MPV, MPD, GNU.FM""" start="00:22:51.620" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Process communication with a simple media player""" start="00:22:56.240" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""can be as straightforward""" start="00:23:00.120" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""as starting an asynchronous process""" start="00:23:01.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and waiting for that process to complete""" start="00:23:03.800" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""in order to move to the next track.""" start="00:23:05.800" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This is how the example above""" start="00:23:08.620" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""with ImageMagick's display binary worked.""" start="00:23:10.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""However, Emms also handles asynchronous""" start="00:23:13.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""two-way communication with processes.""" start="00:23:17.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A simple example of this would be sending strings""" start="00:23:20.300" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to a running process such as the pause command to VLC.""" start="00:23:23.960" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""MPV:""" start="00:23:31.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""MPV is a popular media player forked""" start="00:23:33.380" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""in a roundabout way from mplayer.""" start="00:23:37.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""One of its most notable features is""" start="00:23:39.900" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""support for a robust client API.""" start="00:23:42.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Mike Kazantsev has been working since 2018""" start="00:23:46.600" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to develop the excellent `emms-player-mpv.el'.""" start="00:23:52.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""It can communicate with a long running MPV process""" start="00:23:58.350" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""via Unix sockets or IP sockets.""" start="00:24:02.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This allows for MPV to do things""" start="00:24:07.180" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""like update ICY metadata for streaming audio.""" start="00:24:11.170" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""So that, for example, when a song changes""" start="00:24:14.890" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""while you're listening to a streaming audio via Emms,""" start="00:24:17.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the song title displayed in the mode line""" start="00:24:22.050" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and track listing can update as well.""" start="00:24:24.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This means that deep inside the code""" start="00:24:28.330" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""there is an Emacs `make-network-process` call.""" start="00:24:30.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The fact that Mike has put this together""" start="00:24:35.630" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""in fewer than 1,000 lines of legible Emacs Lisp""" start="00:24:37.920" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""is a testament to some serious coding ability.""" start="00:24:42.640" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""MPD:""" start="00:24:47.470" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Similar to MPV but potentially""" start="00:24:49.610" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""on a completely different machine""" start="00:24:52.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""is Emms support for the Music Player Daemon.""" start="00:24:54.120" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Music Player Daemon or MPD is a media player""" start="00:24:58.460" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""with an explicit client-server design""" start="00:25:01.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and communicates with Emms via a network process.""" start="00:25:03.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Unfortunately, MPD support has never been all that great.""" start="00:25:09.950" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""But this isn't the emms developers fault!""" start="00:25:16.090" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Because unlike every other media player""" start="00:25:20.470" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""that Emms interfaces with MPD is designed around""" start="00:25:25.600" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""its own internal playlist database.""" start="00:25:29.730" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This is a surprising design decision""" start="00:25:31.930" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""on the MPD developers' part""" start="00:25:35.270" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""since it goes against the client-server mindset.""" start="00:25:37.650" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A consequence is that we end up having to try and coordinate""" start="00:25:41.750" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and harmonize the MPD playlist with the Emms playlist.""" start="00:25:45.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""I can foresee writing a completely new MPD mode for Emms""" start="00:25:51.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which is designed to be a true pure MPD client.""" start="00:25:56.690" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Unless of course someone volunteers to beat me to it.""" start="00:26:01.510" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Hint hint.""" start="00:26:05.340" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""GNU FM and Libre FM:""" start="00:26:07.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Libre FM is a music community which allows you""" start="00:26:10.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to share your listening habits with other users of the site.""" start="00:26:13.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A kind of online listening party.""" start="00:26:17.450" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""In the case of `emms-librefm-scrobber.el`""" start="00:26:21.270" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""we use Emacs' `url-retrieve` function""" start="00:26:25.650" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to asynchronously send to a URL""" start="00:26:28.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and then fire a callback function to process the response.""" start="00:26:32.450" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This represents numerous challenges""" start="00:26:40.050" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to implement within Emacs.""" start="00:26:42.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The primary issue being that Emacs itself""" start="00:26:45.090" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""is pretty weak at doing anything""" start="00:26:47.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""truly and really asynchronously.""" start="00:26:50.100" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""I can say with confident sarcasm""" start="00:26:54.220" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and with tongue firmly planted in cheek""" start="00:26:56.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""that it is almost as if the original designers""" start="00:26:59.530" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""of Emacs didn't foresee their text editor""" start="00:27:02.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""needing to play music""" start="00:27:05.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""while interacting with a remote network server.""" start="00:27:07.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""How myopic!""" start="00:27:09.820" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""How we work: Emms development:""" start="00:27:12.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This part is an overview of how Emms is developed.""" start="00:27:15.700" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""By the end of this part you should be able to understand""" start="00:27:19.620" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""how we hacked this project, and how you can too.""" start="00:27:23.900" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Where it's at.""" start="00:27:28.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""How to find our forge.""" start="00:27:29.950" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms has been hosted at the FSF's forge, Savannah,""" start="00:27:32.370" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""since around 2003.""" start="00:27:36.500" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms is distributed via GNU ELPA and integrated into Emacs.""" start="00:27:39.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Before ELPA it was distributed as a tarball""" start="00:27:46.230" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""via ftp.gnu.org but that stopped back in 2020.""" start="00:27:49.800" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""I was initially resistant to ELPA but around the time""" start="00:27:55.140" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""when the thousandth person asked me why Emms isn't on ELPA,""" start="00:27:58.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""I realized that it had to happen.""" start="00:28:03.850" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms can also be found in other places""" start="00:28:07.210" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""such as Melpa or GitHub but we, the developers of Emms,""" start="00:28:10.600" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""have nothing to do with that""" start="00:28:16.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and we don't monitor those channels.""" start="00:28:18.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""If you want the source straight from, well, the source,""" start="00:28:21.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""then go to the Savannah Git repository.""" start="00:28:26.300" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Look who's talking: Where development discussion happens.""" start="00:28:30.370" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""If you want to talk to us, discussions all happen""" start="00:28:34.990" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""on emms-help@gnu.org.""" start="00:28:38.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""We used to use emms-patches@gnu.org""" start="00:28:41.430" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""but didn't feel like the volume of incoming patches""" start="00:28:45.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""justified a separate mailing list.""" start="00:28:48.280" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""The Rime Of The Ancient Maintainer:""" start="00:28:52.590" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""There are a number of activities""" start="00:28:55.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""particular to being a maintainer.""" start="00:28:57.480" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""These are all part of a project's lifecycle.""" start="00:29:00.100" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Let's review some of them.""" start="00:29:03.390" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""The life and times of an Emms patch:""" start="00:29:06.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A maintainer needs to be able to accept, critique,""" start="00:29:10.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and integrate patches from contributors and developers.""" start="00:29:13.240" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This means, among other things, that the maintainer""" start="00:29:17.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""needs to keep on top of copyright issues.""" start="00:29:20.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Before being able to add Emms to GNU/ELPA,""" start="00:29:24.470" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""we had to make sure that the copyright situation""" start="00:29:29.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""was in order.""" start="00:29:31.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This long process required reaching out to people""" start="00:29:33.850" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and having them assign the copyright""" start="00:29:37.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""for their work to the FSF,""" start="00:29:39.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""or even removing their code entirely""" start="00:29:42.510" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""if they couldn't be reached.""" start="00:29:45.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The experience left me with the conviction""" start="00:29:47.970" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""that the easiest way to fix""" start="00:29:50.630" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the copyright situation of your package""" start="00:29:52.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""is to ensure that it never gets broken in the first place.""" start="00:29:54.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Often a person will write in to the emms-help mailing list,""" start="00:30:00.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""or perhaps raise an issue on IRC.""" start="00:30:04.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""If it's a bug report or feature request, we'll discuss it,""" start="00:30:08.030" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and when it's fixed, we'll ask the reporter""" start="00:30:11.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to test the result and provide feedback.""" start="00:30:14.160" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""If it's a patch, then we'll typically go one of three ways.""" start="00:30:17.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A trivial patch, such as fixing a typo""" start="00:30:22.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""or corrections on a single line of code,""" start="00:30:24.800" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""will simply be applied by one of the developers.""" start="00:30:27.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A non-trivial, but one-time patch,""" start="00:30:32.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""will have to be cleared from a copyright perspective.""" start="00:30:34.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This means assigning copyright for the changes to the FSF.""" start="00:30:37.990" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Once that's cleared, then the patch will be applied.""" start="00:30:42.420" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Finally, if it's a non-trivial patch,""" start="00:30:46.320" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which looks like it would be the start""" start="00:30:49.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""of a long-term development work (my favorite),""" start="00:30:52.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""then after copyright is cleared,""" start="00:30:56.010" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""that person will be offered to be added""" start="00:30:57.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to the members with Git repo access on Savannah.""" start="00:31:00.800" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""From there, we usually use a dedicated branch""" start="00:31:05.020" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to do all the playing around""" start="00:31:08.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""before merging it with the main Git repo.""" start="00:31:09.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""If you have ever sent a patch, feature request,""" start="00:31:13.630" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""or bug report into Emms (small or large), we thank you.""" start="00:31:16.880" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""Let It Go, The Release Process:""" start="00:31:24.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The maintainer is responsible for the release process.""" start="00:31:27.790" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""I found that a consistent schedule works well,""" start="00:31:31.610" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which is not to say that we have to release on schedule,""" start="00:31:35.130" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""but that aiming for a consistent release schedule""" start="00:31:39.380" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""provides structure and a goal.""" start="00:31:42.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The main Git branch in the repository is stable""" start="00:31:46.050" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and more often than not of release quality.""" start="00:31:50.160" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Releases are done about every three months.""" start="00:31:53.240" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""And with such a stable main branch,""" start="00:31:56.650" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the process of releasing often involves little more""" start="00:31:59.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""than writing a NEWS entry.""" start="00:32:02.320" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""As a consequence, new and wonderful features""" start="00:32:05.060" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which aren't quite ready for prime time""" start="00:32:08.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""when a release comes around,""" start="00:32:11.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""will remain safely in their branch on the Git repo""" start="00:32:13.500" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""until after the ELPA release.""" start="00:32:18.200" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""It Is Not In Our Stars, But In Ourselves; Future Directions:""" start="00:32:23.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""One aspect of Emms that needs to improve is ease of setup.""" start="00:32:29.630" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Now that might surprise you, since at the time of writing,""" start="00:32:34.900" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""it's already pretty easy.""" start="00:32:37.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""But my ideal is that the user would need to do""" start="00:32:40.070" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""nothing at all after installation.""" start="00:32:43.880" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""And with that, as a goal in mind,""" start="00:32:46.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""there is more work to be done.""" start="00:32:49.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""We are working on a player discovery feature.""" start="00:32:52.750" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The idea is simple.""" start="00:32:55.500" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The code looks for binaries of popular media players""" start="00:32:57.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""on the user's machine,""" start="00:33:00.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and for each one found, it asks the user""" start="00:33:01.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""if they want the associated Emms player backend""" start="00:33:04.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to be configured.""" start="00:33:07.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""In effect, this code is already working,""" start="00:33:09.810" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""but currently an undocumented, unofficial feature.""" start="00:33:12.590" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""You can try it for yourself with""" start="00:33:16.290" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""`emms-setup-discover-players`.""" start="00:33:17.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""So what's the holdup?""" start="00:33:21.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""`emms-setup-discover-players` currently configures""" start="00:33:22.970" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""the `emms-player-list` variable,""" start="00:33:26.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""but doesn't write it to disk.""" start="00:33:27.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""And that means that the configuration""" start="00:33:29.900" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""isn't preserved between Emacs sessions.""" start="00:33:31.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The question then becomes,""" start="00:33:35.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""what is the best way to preserve this setting?""" start="00:33:36.900" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""I personally don't like anything""" start="00:33:40.310" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to edit my .emacs except me,""" start="00:33:42.600" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and I wouldn't do that to anyone else.""" start="00:33:46.200" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Now we already write state to the .emacs.d/emms/ directory,""" start="00:33:49.280" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""but that would require care not to""" start="00:33:55.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""clobber a user's existing setup.""" start="00:33:58.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Having the user set up their system in one place,""" start="00:34:01.910" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""such as a .emacs or a .emmsrc,""" start="00:34:04.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""while saving state to a different place""" start="00:34:08.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""is asking for confusion.""" start="00:34:11.420" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""This is a good example which I bring up""" start="00:34:14.210" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""of where a maintainer needs to""" start="00:34:16.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""solicit opinions from developers,""" start="00:34:18.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""both the Emacs developers,""" start="00:34:21.309" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""asking them where packages should save state,""" start="00:34:23.900" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and the Emms developers, and also users.""" start="00:34:28.170" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Then, the maintainer needs to""" start="00:34:33.170" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""carefully choose a path forward.""" start="00:34:35.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""It is typical of the kind of issue you have to have in mind""" start="00:34:38.020" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""when you're maintaining a package.""" start="00:34:41.560" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""Development Policies: Interface Language.""" start="00:34:44.849" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A maintainer of an interactive program such as Emms""" start="00:34:49.160" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""needs to think about user interaction.""" start="00:34:52.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Emms doesn't use key bindings which are familiar""" start="00:34:55.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to people who are used to GUI media players,""" start="00:34:58.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and that can, and has, caused friction.""" start="00:35:02.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Some new users are confused when they press the spacebar""" start="00:35:06.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""on an entry in the Emms browser,""" start="00:35:09.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""only to find that nothing starts playing.""" start="00:35:12.530" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Indeed, all that does is to expand the browser tree""" start="00:35:15.460" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""at that point.""" start="00:35:18.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Then they might press RET on the same entry,""" start="00:35:20.470" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and be further frustrated at the continuing silence.""" start="00:35:23.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Since what return does is just to add that entry at point""" start="00:35:28.260" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""to the current playlist.""" start="00:35:33.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""The discussion then arises""" start="00:35:36.170" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""about how Emms should handle that situation.""" start="00:35:37.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""On one hand, we want to make it as easy as possible""" start="00:35:41.820" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""for new users to learn Emms,""" start="00:35:45.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and adopt a do-what-I-mean interface approach.""" start="00:35:48.820" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""On the other hand, this is an Emacs project.""" start="00:35:52.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""It isn't a stand-alone GUI media player,""" start="00:35:56.750" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and should integrate into Emacs,""" start="00:35:59.440" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and serve Emacs users first and foremost.""" start="00:36:01.400" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""Development policies: Freedom.""" start="00:36:05.980" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Another maintainer job is to think of Emms' posture""" start="00:36:10.290" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""in regards to software freedom.""" start="00:36:15.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Here are a few examples.""" start="00:36:17.380" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Back with MP3 was still a patent encumbered format,""" start="00:36:19.730" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""we pushed hard for Vorbis everywhere""" start="00:36:23.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""along with the PlayOgg campaign.""" start="00:36:26.081" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A then popular music streaming service,""" start="00:36:29.640" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which will remain unnamed,""" start="00:36:32.700" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""changed their stance towards third-party applications,""" start="00:36:34.930" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and required individual API keys which could not be shared.""" start="00:36:38.620" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""We stood firm, said &quot;no&quot;,""" start="00:36:43.130" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and removed support for that service.""" start="00:36:45.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A recent suggestion to add support for YouTube""" start="00:36:48.670" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""was also nixed,""" start="00:36:51.360" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""because the particular backend""" start="00:36:53.890" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""was found to download and run proprietary javascript""" start="00:36:55.680" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""on the user's machine.""" start="00:36:58.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Saying no to potentially useful or wanted features""" start="00:37:01.850" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""because it involves non-free software""" start="00:37:05.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""is often an unpopular decision and can alienate people.""" start="00:37:07.920" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""A maintainer needs to think carefully""" start="00:37:13.490" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""about each of these decisions,""" start="00:37:15.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""as they are rarely straightforward and one-sided.""" start="00:37:17.400" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""And as you see above, they also change over time""" start="00:37:21.920" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and need to be re-evaluated.""" start="00:37:25.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""One of the most useful things a maintainer can do""" start="00:37:30.300" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""is to coordinate the development effort""" start="00:37:33.000" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""and help new people join the project.""" start="00:37:35.520" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""In light of that, if you want to work on a project""" start="00:37:39.230" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which has a bit of everything,""" start="00:37:41.840" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""you could do worse than hacking on Emms.""" start="00:37:44.060" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""There is inter-process communication,""" start="00:37:47.810" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""displaying graphics, parsing binary files,""" start="00:37:49.720" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""caching, asynchronous processes, user interface design.""" start="00:37:52.480" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""We also are a project that insists on""" start="00:37:56.530" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""keeping a well-written and up-to-date manual.""" start="00:37:59.600" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""If you can write English or hack Emacs Lisp at all,""" start="00:38:02.960" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""chances are that there is something you can do for Emms.""" start="00:38:06.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Just saying.""" start="00:38:09.940" video="mainVideo-emms" id="subtitle"]]
+[[!template new="1" text="""Acknowledgements:""" start="00:38:12.370" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""I'd like to express my deep gratitude for all of the people""" start="00:38:14.190" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""who have hacked on Emms""" start="00:38:18.080" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""during my time as a maintainer and before it.""" start="00:38:19.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""It is often the case that I'm just the person""" start="00:38:23.170" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""holding the rudder and steering the ship,""" start="00:38:25.760" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""with all of these developers""" start="00:38:28.560" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""rowing furiously to provide the power""" start="00:38:30.040" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""which actually moves the ship forward.""" start="00:38:33.180" video="mainVideo-emms" id="subtitle"]]
+[[!template text="""Thank you to all.""" start="00:38:36.370" video="mainVideo-emms" id="subtitle"]]
+
+
+
+Captioner: yoni
+
Questions or comments? Please e-mail [emacsconf-org-private@gnu.org](mailto:emacsconf-org-private@gnu.org?subject=Comment%20for%20EmacsConf%202022%20emms%3A%20Emacs%20MultiMedia%20System%20%28EMMS%29)
diff --git a/2023/info/emms-before.md b/2023/info/emms-before.md
index e0bd5609..58e5d149 100644
--- a/2023/info/emms-before.md
+++ b/2023/info/emms-before.md
@@ -8,12 +8,40 @@ The following image shows where the talk is in the schedule for Sun 2023-12-03.
Format: 39-min talk; Q&A: BigBlueButton conference room <https://media.emacsconf.org/2023/current/bbb-emms.html>
Etherpad: <https://pad.emacsconf.org/2023-emms>
Discuss on IRC: [#emacsconf-gen](https://chat.emacsconf.org/?join=emacsconf,emacsconf-gen)
-Status: Ready to stream
+Status: Now playing on the conference livestream
<div>Times in different timezones:</div><div class="times" start="2023-12-03T18:00:00Z" end="2023-12-03T18:40:00Z"><div class="conf-time">Sunday, Dec 3 2023, ~1:00 PM - 1:40 PM EST (US/Eastern)</div><div class="others"><div>which is the same as:</div>Sunday, Dec 3 2023, ~12:00 PM - 12:40 PM CST (US/Central)<br />Sunday, Dec 3 2023, ~11:00 AM - 11:40 AM MST (US/Mountain)<br />Sunday, Dec 3 2023, ~10:00 AM - 10:40 AM PST (US/Pacific)<br />Sunday, Dec 3 2023, ~6:00 PM - 6:40 PM UTC <br />Sunday, Dec 3 2023, ~7:00 PM - 7:40 PM CET (Europe/Paris)<br />Sunday, Dec 3 2023, ~8:00 PM - 8:40 PM EET (Europe/Athens)<br />Sunday, Dec 3 2023, ~11:30 PM - 12:10 AM IST (Asia/Kolkata)<br />Monday, Dec 4 2023, ~2:00 AM - 2:40 AM +08 (Asia/Singapore)<br />Monday, Dec 4 2023, ~3:00 AM - 3:40 AM JST (Asia/Tokyo)</div></div><div><strong><a href="/2023/watch/gen/">Find out how to watch and participate</a></strong></div>
+<div class="vid"><video controls preload="none" id="emms-mainVideo"><source src="https://media.emacsconf.org/2023/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--main.webm" />captions="""<track label="English" kind="captions" srclang="en" src="/2023/captions/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--main.vtt" default />"""<track kind="chapters" label="Chapters" src="/2023/captions/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--main--chapters.vtt" /><p><em>Your browser does not support the video tag. Please download the video instead.</em></p></video>[[!template id="chapters" vidid="emms-mainVideo" data="""
+00:00.000 Introduction
+01:03.320 The structure of this talk
+01:21.320 Introduction to Emms: The practical part
+08:04.240 The modeline
+11:01.200 Meta-playlist mode
+11:29.860 The browser
+13:19.920 How Emms works: The technical part
+16:23.820 The Emms core
+16:36.440 Tracks
+17:18.460 Playlist
+18:22.080 Sources
+19:22.160 Players
+20:20.520 Info
+21:36.660 The cache
+22:51.620 Healthy back and forth: mpv, mpd, and GNU.FM
+23:31.560 MPV
+24:47.470 MPD
+26:07.440 GNU FM and Libre FM
+27:12.560 How we work: Emms development
+28:52.590 The Rime Of The Ancient Maintainer
+29:06.080 The life and times of an Emms patch
+31:24.080 Let It Go: The release process
+32:23.400 It Is Not In Our Stars, But In Ourselves: Future directions
+34:44.849 Development policies: Interface language
+36:05.980 Development policies: Freedom
+38:12.370 Acknowledgements
+"""]]<div></div>Duration: 38:38 minutes<div class="files resources"><ul><li><a href="https://pad.emacsconf.org/2023-emms">Open Etherpad</a></li><li><a href="https://media.emacsconf.org/2023/current/bbb-emms.html">Open public Q&A</a></li><li><a href="https://media.emacsconf.org/2023/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--final.webm">Download --final.webm (139MB)</a></li><li><a href="https://media.emacsconf.org/2023/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--intro.vtt">Download --intro.vtt</a></li><li><a href="https://media.emacsconf.org/2023/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--intro.webm">Download --intro.webm</a></li><li><a href="https://media.emacsconf.org/2023/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--main--chapters.vtt">Download --main--chapters.vtt</a></li><li><a href="https://media.emacsconf.org/2023/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--main.opus">Download --main.opus (21MB)</a></li><li><a href="https://media.emacsconf.org/2023/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--main.vtt">Download --main.vtt</a></li><li><a href="https://media.emacsconf.org/2023/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--main.webm">Download --main.webm (139MB)</a></li><li><a href="https://media.emacsconf.org/2023/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--normalized.opus">Download --normalized.opus (34MB)</a></li><li><a href="https://media.emacsconf.org/2023/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--original.webm">Download --original.webm (466MB)</a></li><li><a href="https://media.emacsconf.org/2023/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin--reencoded.webm">Download --reencoded.webm (127MB)</a></li><li><a href="https://media.emacsconf.org/2023/emacsconf-2023-emms--emacs-multimedia-system-emms--yoni-rabkin.outline">Download .outline</a></li><li><a href="https://toobnix.org/w/ppdF62LysvxpXgZVaeF9wk">View on Toobnix</a></li></ul></div></div>
# Description
<!-- End of emacsconf-publish-before-page --> \ No newline at end of file