(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_.
It is meant as both a tutorial and a sandbox.

This intro is being rewritten.

1. 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, and if you have mpv and xterm installed: (find-audio "/tmp/mysong.mp3") (find-audio "/tmp/mysong.mp3" "1:23") (find-audio "/tmp/mysong.mp3" "1:23" "comments are ignored") (find-video "/tmp/myvideo.mp4") (find-video "/tmp/myvideo.mp4" "1:23") (find-video "/tmp/myvideo.mp4" "1:23" "comments are ignored") Note that they work by invoking an external player - mpv, by default - and its error messages appear here: (find-ebuffer "*Messages*")

2. `eev-avadj-mode'

"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 these sexps: (eev-avadj-mode 0) (eev-avadj-mode) 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") into: (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 idea of a "default audio/video file" will be explained later.

3. 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") (find-sunwillset) ;; ^ 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: (find-videos-intro)

4. Short hyperlinks to audio and video files

This sexp (code-video "eevtk2video" "~/eev-videos/three-keys-2.mp4") defines a function `find-eevtk2video'. Note that the function definition in (find-code-video "eevtk2video" "~/eev-videos/three-keys-2.mp4") has this line: (setq ee-audiovideo-last 'find-eevtk2video) Every call to a function with a name like `find-*audio' or `find-*video' sets the variable `ee-audiovideo-last'.

4.1. `find-code-audiovideo-links'

The easist way to produce `code-audio' or `code-video' hyperlinks uses `M-h M-a', that calls `find-code-audiovideo-links' and is very similar to: (find-pdf-like-intro "9. Generating three pairs") (find-pdf-like-intro "9. Generating three pairs" "M-h M-p") A test: * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) mkdir ~/eev-videos/ cd ~/eev-videos/ wget -nc http://angg.twu.net/eev-videos/three-keys-2.mp4 # (find-code-audiovideo-links "~/eev-videos/three-keys-2.mp4" "eevtk2") # (find-fline "~/eev-videos/") # (find-fline "~/eev-videos/" "three-keys-2.mp4") # ^ Type `M-h M-a' on the line with the .mp4 [Todo: explain M-p in eev-avadj-mode]

4.2. `eewrap-audiovideo'

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, with: (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.

4.3. A demo

Here's some code to test `find-video' and `code-video'. Make sure that you have mpv installed, and run this escript block: * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) # http://www.youtube.com/watch?v=K6LmZ0A1s9U # http://angg.twu.net/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4 mkdir ~/eev-videos/ cd ~/eev-videos/ wget -nc http://angg.twu.net/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4 It will download a copy of a video from youtube; I prepared the .mp4 by running "youtube-dl -f 18" on the youtube URL and renaming the result. Then try: (find-video "~/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4") (code-video "punchandjudyvideo" "~/eev-videos/Punch_and_Judy_Mark_Poulton-K6LmZ0A1s9U.mp4") (find-punchandjudyvideo) (find-punchandjudyvideo "0:00") (find-punchandjudyvideo "0:10" "calls the baby") (find-punchandjudyvideo "0:40" "where's the baby") (find-punchandjudyvideo "1:04" "right position") (find-punchandjudyvideo "1:17" "he will sing the baby to sleep") (find-punchandjudyvideo "1:33" "1-2-3") (find-punchandjudyvideo "1:48" "baby downstairs") (find-punchandjudyvideo "3:12" "slaps") (find-punchandjudyvideo "3:50" "1-2-3") (find-punchandjudyvideo "4:34" "you keep an eye on mr Punch") (find-punchandjudyvideo "4:46" "hat") (find-punchandjudyvideo "5:03" "hat") (find-punchandjudyvideo "5:25" "did you see him?") (find-punchandjudyvideo "5:55" "clown") (find-punchandjudyvideo "6:14" "slaps") (find-punchandjudyvideo "6:52" "sausages") (find-punchandjudyvideo "7:24" "crocodile") (find-punchandjudyvideo "8:07" "crocodile + sausages") (find-punchandjudyvideo "8:32" "another scene") (find-punchandjudyvideo "8:39" "fight") (find-punchandjudyvideo "9:03" "clown") (find-punchandjudyvideo "9:45" "mr punch")

5. 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: (ee-mplayer-video-options) (ee-mplayer-audio-options) *******

6. Youtube-dl

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: http://www.youtube.com/watch?v=abcdefghijk \---------/ 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 /tmp/TITLE-abcdefghijk.mp4.part during the download, and would be renamed to /tmp/TITLE-abcdefghijk.mp4 as soon as the download is finished.

7. Downloading a local copy

Place the point at hash in the URL below, http://www.youtube.com/watch?v=abcdefghijk 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.

8. 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 components: (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".

9. 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.

10. 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 /tmp/TITLE-abcdefghijk.mp4.part is elsewhere, and the guessing functions only search in one directory... 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.'