Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
(Re)generate: (find-audiovideo-intro)
Source code:  (find-eev "eev-intro.el" "find-audiovideo-intro")
More intros:  (find-eev-quick-intro)
This buffer is _temporary_ and _editable_.
Is is meant as both a tutorial and a sandbox.

Time offsets
Links to audio and video files are similar to links to pdf-like
documents, but instead of page numbers we use "time offsets" to
refer to positions. Time offsets are strings like 1:23, 12:34, or
1:23:45. The sexp hyperlinks below should all work if you have the
files that they refer to:

  (find-audio "/tmp/mysong.mp3")
  (find-audio "/tmp/mysong.mp3" "1:23")
  (find-audio "/tmp/mysong.mp3" "1:23" "comment are ignored")
  (find-video "/tmp/myvideo.mp4")
  (find-video "/tmp/myvideo.mp4" "1:23")
  (find-video "/tmp/myvideo.mp4" "1:23" "comment are ignored")

Note that they work by invoking an external player - mplayer, by
default - and its error messages appear here:

  (find-ebuffer "*Messages*")

Shorter hyperlinks to audio and video files
If you type `M-V' (`eewrap-audiovideo') on a line containing a
shorthand word and a file name of an audio or video file, for
example, here,

  sunwillset  ~/Zoe_Keating/Sun_Will_Set.ogg

you will get something like this:

  ;; (find-fline "~/Zoe_Keating/")
  (code-audio "sunwillset" "~/Zoe_Keating/Sun_Will_Set.ogg")
  (code-video "sunwillset" "~/Zoe_Keating/Sun_Will_Set.ogg")
  ;; (find-sunwillset)
  ;; (find-sunwillset "0:00")

you should delete the line with the wrong sexp by hand - in this
case the wrong one is the one with `code-video', as we are
working with a sound file - and execute the other one; this will
define a function called `find-sunwillset', that plays the audio
file with `find-audio'. Run this this sexp to inspect its code:

  (find-code-audio "sunwillset" "/tmp/Zoe_Keating__Sun_Will_Set.ogg")

you will notice that running `find-sunwillset' sets a variable,

  (setq ee-audiovideo-last 'find-sunwillset)

As we shall see soon, some operations play again the default
audio or video file, starting from some given time offset. The
default is always what is stored in `ee-audiovideo-last', and
each call to a short hyperlink of the form `find-xxxaudio' or
`find-xxxvideo' sets that variable.

Passing options to mplayer
By default mplayer is called with just a few command-line options,
besides the ones that tell it at what position to start playing -
typically just these for videos,

  -fs -osdlevel 2

to make it run in full-screen mode with an on-screen display
showing the current position, and no options for audio.

If you want to change this you should redefine these functions:



"avadj-mode" is a shorthand for "audio/video adjust mode".
When `eev-avadj-mode' is active we get keys for adjusting time
offsets quickly and for playing again the default audio or video
file at a given time offset, all of this without moving the
point. The keys are:

  M--    decrease the time offset by one second
  M-+    increase the time offset by one second
  M-=    same as M-+, for convenience
  M-p    play the default audio/video file at a time offset

You can toggle eev-avadj-mode on and off with `M-x
eev-avadj-mode', or with this sexp:


When it is on you will see an "avadj" at the mode line. Let's
examine `M--' and `M-+' first. With eev-avadj-mode on, try typing
several `M--'s and `M-+'s (or `M-='s) on the line below:

  This time offset - 9:59 - will change

Now, as an exercise, try to use `M--'s and `M-+'s/`M-='s, plus
`M-h M-2' (`ee-duplicate-this-line') and other more standard
editing commands, to convert this line

  (find-exampleaudio "0:00")


  (find-exampleaudio "0:00")
  (find-exampleaudio "0:12" "blah")
  (find-exampleaudio "0:30" "bleh")

That should give you an idea of how to index audio or video files
- by creating elisp hyperlinks, with comments, to specific
positions in them. Of course in a real-world situation we would
execute these sexps occasionally to check if they are really
pointing to the right places, and then make further adjustments;
we are not doing that yet.

The time-from-bol
All the keys in eev-avadj-mode operate on the "time-from-bol"
of the current line: the first occurrence, in the current line,
of a string that looks like a time offset. Note that the search
starts from the beginning of the line ("-from-bol"), and if
there are several possibilities, the first one is chosen.

Remember that `M-e' has a variant that just highlights what would
be executed, instead of evaluating a sexp:

  (find-eval-intro "`M-0 M-e'")

`M-p' also has something like this: `M-0 M-p' highlights the
time-from-bol and displays in the echo area the sexp that it
would execute to invoke a player - instead of running that sexp.
Try to evaluate these sexps:

  (code-audio "sunwillset" "~/Zoe_Keating/Sun_Will_Set.ogg")
  ;; ^ don't worry if this fails - we are only calling it
  ;;   to set `ee-audiovideo-last'

and now try `M-0 M-p' on these lines:

  ;; 4:19 blah
  ;; 2:19 

For more realistic examples, see:


Videos at Youtube are identified by unique 11-char codes that are
assigned to them when they are uploaded. We will call those 11-char
codes "hashes", even though the term is not totally adequade in this
case, and we will explain the main ideas considering the case of an
imaginary video whose title is just TITLE, and whose hash is
"abcdefghijk". The URL to access that video at Youtube would be this:

                                  its hash

If we execute this on a shell,

  cd /tmp/
  youtube-dl -t 'http://www.youtube.com/watch?v=abcdefghijk'

then youtube-dl would download a local copy of the video; due to the
option "-t" ("--title"), the name of the local copy would have both
the title of the video and its hash, and, if the video is in MP4
format, that would be


during the download, and would be renamed to


as soon as the download is finished.

Downloading a local copy
Place the point at hash in the URL below,


and run `M-x find-youtubedl-links'; `find-youtubedl-links' will use
the hash at point as a default for one of its arguments, will run
something equivalent to this sexp,

  (find-youtubedl-links nil nil "abcdefghijk")

and will create a buffer like this:

  |# (find-youtubedl-links "/tmp/" "{title}" "abcdefghijk" "{ext-}" "{stem}") |
  |# (find-youtubedl-links "/tmp/" nil "abcdefghijk" nil "{stem}")            |
  |                                                                           |
  |# (find-youtubedl-links "~/videos/" nil "abcdefghijk" nil "{stem}")        |
  |# (find-youtubedl-links "~/videos/tech/" nil "abcdefghijk" nil "{stem}")   |
  |# (find-youtubedl-links "/tmp/videos/" nil "abcdefghijk" nil "{stem}")     |
  |# (find-youtubedl-links "/tmp/" nil "abcdefghijk" nil "{stem}")            |
  |# (find-efunction 'find-youtubedl-links)                                   |
  |                                                                           |
  |* (eepitch-shell2)                                                         |
  |* (eepitch-kill)                                                           |
  |* (eepitch-shell2)                                                         |
  |# http://www.youtube.com/watch?v=abcdefghijk                               |
  |# http://www.youtube.com/watch?v=abcdefghijk#t=0m00s                       |
  |# http://www.youtube.com/watch?v=abcdefghijk#t=0h00m00s                    |
  |cd /tmp/                                                                   |
  |youtube-dl -t 'http://www.youtube.com/watch?v=abcdefghijk'                 |
  |                                                                           |
  |# youtube-dl -t -F    'http://www.youtube.com/watch?v=abcdefghijk'         |
  |# youtube-dl -t -f 18 'http://www.youtube.com/watch?v=abcdefghijk'         |
  |                                                                           |
  |# (find-es "video" "youtube-dl")                                           |
  |# (find-fline "/tmp/" "abcdefghijk")                                       |
  |# (find-fline "/tmp/" "{title}-abcdefghijk")                               |
  |# (find-fline "/tmp/" "{title}-abcdefghijk{ext-}")                         |
  |# (find-video "/tmp/{title}-abcdefghijk{ext-}")                            |
  |# (find-video "/tmp/{title}-abcdefghijk{ext-}.part")                       |
  |# (code-video "{stem}video" "/tmp/{title}-abcdefghijk{ext-}")              |
  |# (code-video "{stem}video" "/tmp/{title}-abcdefghijk{ext-}.part")         |
  |# (find-{stem}video)                                                       |
  |# (find-{stem}video "0:00")                                                |
  |                                                                           |
  |# Error messages (for the player):                                         |
  |# (find-ebuffer "*Messages*")                                              |
  |                                                                           |
  |                                                                           |
  |--:**-  *Elisp hyperlinks*   All L1     (Fundamental)----------------------|

which has LOTS of things... the part

  * (eepitch-shell2)
  * (eepitch-kill)
  * (eepitch-shell2)
  cd /tmp/
  youtube-dl -t 'http://www.youtube.com/watch?v=abcdefghijk'

is obvious: it is an eepitch script that downloads a local copy
of the video from Youtube.

Guessing the title and extension
Let's simulate what would happen after the eepitch script above -
Execute this:

  (find-sh0 "rm -v  /tmp/TITLE-abcdefghijk*")
  (find-sh0 "echo > /tmp/TITLE-abcdefghijk.mp4.part")

Now use `M-2 M-e' to compare the buffers generated by two calls
to `find-youtubedl-links' below:

  (find-youtubedl-links nil nil "abcdefghijk")
  (find-youtubedl-links "/tmp/" nil "abcdefghijk")

In the second one we get a buffer where all occurrences
of "{title}" have been substituted by "TITLE", and all
occurrences of "{ext-}" by ".mp4". What happenned was that

  (ee-youtubedl-guess* "/tmp/" "abcdefghijk")
     --> ("/tmp/TITLE-abcdefghijk.mp4.part")

did find files what that hash string in their names in the
directory "/tmp/", and the function `ee-youtubedl-split' has
picked up the first of these file names and has split it into

  (ee-youtubedl-split "/tmp/TITLE-abcdefghijk.mp4.part")
     --> ("/tmp/" "TITLE" "abcdefghijk" ".mp4" ".mp4.part")

The last of these components is what we will call the "ext" -
the "full extension" - and the previous one is the "ext-" -
the "extension minus its optional `.part'". The first three
components are the "dir", the "title", and the "hash".

The first lines regenerate the buffer
The arguments to `find-youtubedl-links' are:

  (find-youtubedl-links DIR TITLE HASH EXT- STEM)

and we just saw how `ee-youtubedl-guess*' and
`ee-youtubedl-split' can be used to guess TITLE, EXT and EXT-
from DIR and HASH.

All the arguments to `find-youtubedl-links' have defaults,
that are used when the received arguments are nil:

  * when HASH is nil, use the youtube hash around point,
    or "{hash}" if none;
  * when DIR is nil, use the value of `ee-youtubedl-dir',
    or "{dir}" if none;
  * when TITLE or EXT- are nil use the guessing method described
    above, and when they fail use "{title}" or "{ext-}";
  * when STEM is nil, use "{stem}".

The first two lines in a `find-youtubedl-links' regenerate the
buffer, and are usually equivalent to one another. In the buffer
generated by:

  (find-youtubedl-links "/tmp/" nil "abcdefghijk")

they are:

  (find-youtubedl-links "/tmp/" "TITLE" "abcdefghijk" ".mp4" "{stem}")
  (find-youtubedl-links "/tmp/" nil "abcdefghijk" nil "{stem}")

The first one has only non-nil arguments - all the rules for
guesses and defaults have been applied - where in the second one
TITLE and EXT- are made nil.

Selecting a directory
The second block of lines in the `find-youtubedl-links' buffer
are used to let we switch the directory quickly. If we just
execute `M-x find-youtubedl-links' with the point on our example
hash, or, equivalently, if we do this,

  (find-youtubedl-links nil nil "abcdefghijk")

you will see that the first two lines will be:

  (find-youtubedl-links "~/videos/" "{title}" "abcdefghijk" "{ext-}" "{stem}")
  (find-youtubedl-links "~/videos/" nil "abcdefghijk" nil "{stem}")

which means that the guessing process didn't find a downloaded
copy, as TITLE is "{title}" and EXT- is "{ext-}". That's because
we are using "~/videos/" as the DIR, and our file


is elsewhere, and the guessing functions only search in one

The second block contains these sexps,

  (find-youtubedl-links "~/videos/" nil "abcdefghijk" nil "{stem}")
  (find-youtubedl-links "~/videos/tech/" nil "abcdefghijk" nil "{stem}")
  (find-youtubedl-links "/tmp/videos/" nil "abcdefghijk" nil "{stem}")
  (find-youtubedl-links "/tmp/" nil "abcdefghijk" nil "{stem}")

and if we execute the last one we set DIR to "/tmp/".

To change the dir strings "~/videos/", "~/videos/tech/", "/tmp/videos/",
"/tmp/", that appear in the second block of `find-youtubedl-links'
buffers, change the variables `ee-youtubedl-dir', `ee-youtubedl-dir2',
`ee-youtubedl-dir3', `ee-youtubedl-dir4.'

How to download

Test the download

Create short links

  (find-youtubedl-links "/tmp/" "TITLE" "abcdefghijk" ".mp4" "{stem}")
  (find-youtubedl-links nil nil "abcdefghijk")

  (find-eev "eev-audiovideo.el")
  (find-eev "eev-audiovideo.el" "eev-avadj-mode")