Quick
index
main
eev
eepitch
maths
angg
blogme
dednat6
littlelangs
PURO
(C2,C3,C4,
 λ,ES,
 GA,MD,
 Caepro,
 textos,
 Chapa 1)

emacs
lua
(la)tex
maxima
git
agda
forth
squeak
icon
tcl
tikz
fvwm
debian
irc
contact

`find-yttranscript-links' (subtitles)

The main page about this video is here.
Its index is here.
Its subtitles in Lua are here.
The rest of this page contains a conversion of the subtitles in Lua
to a slightly more readable format.


00:01 Hi! My name is Eduardo Ochs,
00:03 I'm the author of an Emacs package called eev,
00:06 and this video is about a function that I added
00:09 to eev in March... it's called
00:11 `find-yttranscript-links'...
00:16 and... well, this page is about this video
00:18 and that function, with all the details...

00:22 and that function is inspired by a blog post
00:25 that Andrea Giugliano wrote in...
00:28 actually, two blog posts -
00:31 in the end of March...

00:33 the first blog post was called
00:35 "An Elisp snippet to download
00:37 YouTube video transcripts"...

00:40 and the second one was about rewriting
00:42 his function of the first blog post
00:45 in a slightly different style.

00:51 When I read those blog posts
00:53 I immediately thought that WOW,
00:56 I _need_ something like that in eev,
00:58 but I would like to rewrite it
01:01 in the style that I prefer to put the
01:04 things in eev in...

01:06 and that's the reason for the dog
01:10 with the square haircut here -
01:13 I'm going to call him the "square dog"...
01:17 when people say "dog" no one expects
01:24 a square dog, so this is not the dog
01:28 that people would expect by default...
01:31 and the interface that this function uses
01:35 is as unexpected as a square dog.

01:41 So let me show how this thing works.
01:46 I prepared two examples here.
01:49 The first example uses a video that I
01:53 have not downloaded with youtube-dl yet,
01:56 and the second example uses a video that
01:59 I have downloaded.

02:00 A few months ago I wanted to convince
02:05 a friend to read this manga here,
02:08 "Lone Wolf and Cub"...
02:11 and I found this video about Lone Wolf
02:13 and Cub, aind I wanted to to send him a
02:17 link to a specific part of the video...

02:20 so I watched first the whole video, and
02:23 then I wanted to find a specific part,
02:25 and I only remembered a few keywords of
02:28 it... so, what did I do?
02:32 First of all... uh, no, one second.

02:34 This thing here, this sequence of 11
02:37 characters, is what I call the "hash"
02:39 of the video, and YouTube videos
02:42 are identified by their hashes.

02:45 When I run `M-x find-youtubedl-links' -
02:50 this is my standard function for
02:52 downloading videos from YouTube and for
02:54 doing things related to downloaded
02:58 videos...

03:00 and when I run that function it detects
03:02 the hash around point and it
03:06 does some things with that hash...

03:08 in this case the hash is going to be
03:10 this one, "aZWq6CEzhuQ"...
03:13 and `find-youtubedl-links' is going to
03:16 generate a temporary buffer
03:19 in which several parts of it
03:21 were replaced by that hash.

03:24 so this thing here is the hash,
03:30 and these other... stubs
03:35 have not been replaced yet...
03:38 and one thing that I'm going to do is
03:39 that I'm going to replace the stem
03:42 by "lonewolf".

03:45 Let me duplicate this line and in this
03:49 copy I'm going to replace the "{stem}"
03:52 by "lonewolf".
03:54 if I execute this sexp here it will
03:58 regenerate this buffer with these values
04:01 for some variables of the template, and
04:04 the "{stem}" that appears here, here,
04:08 here, and in lots of other places is
04:09 going to be replaced by "lonewolf".
04:12 Let me do that now...

04:14 Here - the buffer was slightly changed...
04:17 here we see "lonewolf" in several
04:20 places... and let me delete the parts that
04:24 I'm not going to use. I'm not interested
04:26 in this part here...

04:28 by the way, this sexp here goes to a tutorial
04:31 that explains how to use youtube-dl...
04:34 sorry, how to use youtube-dl from eev.
04:39 If we follow this we go
04:41 to this tutorial here, to this section,
04:43 that starts by explaining what is the hash
04:46 of the video, and so on... but let me go back.

04:49 I also do not want this section here,
04:52 I said that I do not want to download this
04:55 video, so I also do not want these things
04:58 here... remember that this is a
05:00 temporary buffer, so I can do any mess
05:02 that I want with it...
05:07 this section is about playing the local
05:08 copy - I do not have a local copy...
05:13 I'm interested in these parts here.

05:19 If I execute this then Emacs
05:22 is going to call Google Chrome
05:27 with a certain URL to play the video
05:30 starting from a certain position. For
05:32 example, if I replace this by 2:34, if
05:36 executed this it will play the video
05:39 with this hash starting from this
05:41 position...

05:42 and if I execute this sexp here
05:48 it will define a function with this "code"
05:51 in its name, so it's "lonewolf"...
05:55 the code is here... and this function
05:58 here, `file-lonewolfvideo', it will play
06:02 that video from a certain point...

06:05 and it was defined as a function
06:09 that plays that video by opening a
06:12 browser on a certain URL that plays
06:15 the video from a certain position.

06:19 So, for example, if I put 2:34 here
06:22 it will play the video starting from
06:25 2:34... but I do not want to play the
06:28 video now.

06:34 I want to run this. If I run this sexp
06:37 here it will open another temporary buffer
06:39 with another name, so it will not delete
06:42 this temporary buffer... note that this
06:44 temporary buffer is called
06:46 "*find-youtubedl-links*"...
06:48 let me execute this... it opens another
06:52 temporary buffer, called
06:55 "*find-yttranscript-links*"
07:03 let me run this with a smaller font...

07:09 remember that when I use eepitch the
07:13 main key is f8, and f8 acts in one way
07:17 on lines that start with a red star,
07:19 like these four lines here, and in
07:23 another way on lines that do not start
07:26 with red stars...

07:28 and I usually use lines with red stars
07:31 to set up a target buffer, but I can also
07:34 use them to do other kinds of setups.

07:37 These three lines here will
07:40 prepare a target buffer that is running
07:43 python, but in this case I will usually
07:47 execute these four lines here,
07:49 starting from this one...

07:51 and the action of this first one -
07:54 remember that when we execute
07:57 lines that start with red stars with f8
08:01 the rest of the line after the red star
08:05 is executed as Lisp...

08:07 So... if I start by typing an f8 here
08:11 the action of this first line is to put
08:15 this buffer here, that is in fundamental
08:17 mode, in Python mode...
08:21 so now the colors are more expressive.

08:24 And now I'm going to run this these
08:27 three lines again, they will kill this
08:29 target buffer and will regenerate it
08:31 again...

08:33 and now I'm going to use f8 again to
08:36 send these lines to the target buffer.
08:38 Remember that when I type an f8 on a
08:40 line that do not start with a red star
08:42 the f8 sends the line to the target
08:46 buffer...

08:48 usually the target buffer is running
08:50 an interactive program, and the program
08:56 thinks that the user had typed the
08:59 contents of that line.

09:01 So I'm going to send these commands here
09:04 to this Python interpreter here,
09:06 starting by this one.
09:09 This one here, that calls this
09:13 function with a very long name here,
09:15 takes a few seconds to run, so I'm going
09:18 to type f8 here and wait until it's
09:22 done... it was quick.

09:25 And now I'm going to run these things
09:27 here, and this print here.

09:36 And this print here prints the
09:38 transcript of the video in a certain
09:40 format. Sometimes I want other formats so
09:44 it's easy to switch to another format...
09:47 in this case when I ran these three lines here
09:52 I defined two variables, trits0 and trits1,
09:58 for a transcript... and the second definition
10:06 for trits1 over... oh god, how do I say
10:11 that in English? Has overridden
10:14 the previous one... so I executed this,
10:18 and then this, and the current definition
10:23 of trits1 is the one that corresponds to
10:28 this expression here,
10:30 that gives me this format...

10:33 if I execute this line here I'm going
10:37 to get another format... another
10:39 definition for trits1 and another
10:41 format. Let me do that now, and let me
10:44 print the current value of trits1...

10:48 it is in this much shorter format.
10:53 I do not want to explain how to use this
10:56 this shorter format now... the other
10:58 format is easier to understand.

11:01 So let me use the previous format again...
11:05 and now I have a sequence of sexps, and
11:09 each one of these sexps is a link that...
11:12 I mean, when I execute it it is going to
11:17 act as a hyperlink that does something,
11:19 and this something is to
11:22 invoke Google Chrome to play
11:25 this video here
11:27 starting from a certain position.

11:30 And when I wanted to send a part
11:34 of this video to my friend
11:39 I wanted to show him the part that
11:41 mentioned Akira Kurosawa...
11:44 so let me search for Kurosawa here...
11:47 found it! Let me see...
11:51 I want to start a few seconds before
11:53 that, let me see where... ah, here:
11:59 "...but Lone Wolf and cub is above all
12:02 cinematic, blah blah blah blah... it
12:04 uses the vocabulary of movies..."

12:07 I want to start from this position, so
12:10 let me check if this is what
12:12 I'm looking for... let me execute this.
12:16 It will open another tab in the browser...
12:20 it takes a few seconds...
12:22 no, sorry, many seconds...
12:27 and it plays an ad...
12:34 that's the part that I'm interested in.
12:36 I'm not interested in the ads.
12:39 Let me close the YouTube window.

12:43 Anyway, so this is the part that I want,
12:50 and I can copy that to my buffer with
12:55 the annotations about this video...
13:03 and let me delete this and go back to
13:11 this thing here, where I saved some
13:14 hyperlinks... so I was saving these
13:17 hyperlinks here, and of course
13:20 I'm not going to use all of them,
13:24 but the ones that can be useful, that
13:28 deserve to be saved if I want to replay
13:30 this action at some point, are
13:37 these ones. So, these ones create
13:40 a kind of setup in which this function
13:43 is defined, and now that this function
13:45 is defined I can use this sexp here to
13:50 play the video from a certain position.

13:53 But let me go back. I said a long time
13:58 ago that I was going to show two
14:00 examples. In the first one I was going to
14:02 use a video that I do not have a local
14:05 copy of, that is the first one... and the
14:07 second one is an example in which I use
14:10 a video that I have downloaded the local
14:13 copy: this one.
14:16 Remember that I can either type
14:19 `find-youtubedl-links' here...
14:27 but I can also type
14:29 `find-yttranscript-links' here...
14:31 it also detects the hash around point.
14:40 Let me see... no, I want the other
14:42 one, here... and I want to define
14:53 short names for the hyperlinks to this
14:55 video. I'm going to use this stem here,
14:58 "haskelltocore".
15:01 Let me use a smaller font...

15:07 this title here was derived from...
15:11 I mean, Emacs looked at my directory
15:15 with local copies of videos that I
15:16 have downloaded using
15:19 `find-youtubedl-links', and it found
15:22 that I have a video with this hash here,
15:23 with this title here, and with this
15:27 extension. So this is the title,
15:31 this is the hash, this is the
15:35 extension, and so on. And I have just
15:39 adjusted this by hand, and I'm going
15:43 to run this sexp here to regenerate
15:45 this buffer, so these "{stem}"s
15:48 here are going to be replaced by
15:49 "haskelltocore".

15:53 Again, I'm going to delete the things
15:55 that I do not want to use...
15:58 I have already downloaded the video, so I
16:01 do not need this, and I'm going to
16:05 delete this part that plas the video
16:07 on YouTube because I just want the
16:09 local copy.

16:12 And now let me copy this to my notes.
16:24 I want to execute this sexp here,
16:27 and this sexp here is going to define
16:30 the function `find-haskelltocorevideo',
16:37 this function here...

16:39 and it's going to define
16:41 that function in a way that is very
16:43 different from the way that I defined
16:45 this function here. When I ran
16:48 `code-youtubevideo' with these arguments
16:51 here it defined `find-lonewolfvideo'
16:54 as a function that plays a video on
16:56 YouTube by telling a browser to open
17:00 a certain URL,
17:03 and now what I'm going to do is that I'm
17:07 going to define the function... I mean,
17:10 this very long sexp here defines this
17:12 function here as a function that plays
17:15 a local copy of a video - a local video.
17:20 The function that plays local copies does
17:22 not know if the local copy
17:24 was downloaded from YouTube
17:27 or if it is something else.

17:32 So, this sexp here plays the local
17:36 copy of the video -
17:41 it's a very good talk about Haskell -
17:44 and suppose that I want to find
17:46 something that I remember
17:48 that I saw in the video
17:50 when I watched it, and I remember a few
17:53 keywords about it.

17:55 So, I can use this to access the
17:57 transcript...
18:02 note that
18:05 this sexp here was invoked with
18:09 the hash of the video,
18:11 and with this short name here, that can
18:14 be used to generate the name of this
18:17 function here...

18:20 If I run this I get this
18:24 temporary buffer, and I want to execute
18:27 this block here - let me do that now...
18:35 this line here takes several seconds
18:38 to run, so I'm going to press f8 once and
18:42 then wait for the next prompt here...
18:48 got it. And now I'm going to generate
18:54 these variables here, and I'm going to
18:56 print the contents of the variable
18:57 trits1... it is this thing here...

19:04 let me choose a keyword...
19:08 let me search for "monad", for example -
19:13 just a random keyword... I don't remember
19:16 what is the part that I was
19:18 looking for, sorry...

19:24 let's see what happens when I run
19:26 this thing here...
19:31 it plays a local copy.

19:39 So, yeah, that's it. So: I can use that
19:43 to find things in videos...
19:47 if I want to download the
19:51 transcript of a video I need something
19:53 that is a bit tricky...
19:56 if I just run this sexp here,
20:01 this sexp with `find-youtubedl-links',
20:10 this block here, that has the commands
20:12 for downloading the video...
20:16 in this block youtube-dl is called with
20:18 several different command line options...
20:23 I sometimes choose one that downloads the
20:26 video with low resolution, and
20:28 sometimes I run this one to download the
20:33 the best possible version...

20:35 and note that I here I have an option
20:39 that says that I want youtube-dl to
20:43 download the subtitles of the video, and
20:46 for YouTube subtitles and transcripts
20:49 are different things... subtitles are
20:52 edited by hand, and transcripts are
20:55 generated automatically from the
20:59 program that does speech recognition...
21:04 and to download the transcript I need
21:08 other options... they are not here...

21:12 I need another trick, so I need to
21:14 change them by hand...
21:16 so when I downloaded the copy of this
21:19 video I did not download the
21:21 transcript. The local copy does not have
21:24 subtitles...

21:27 I'm not going to show how to download
21:30 this transcript now, and to
21:33 convert it to a format that makes it
21:36 work as subtitles for the video,
21:41 but it is possible to do that.
21:43 It's not the focus of the video
21:45 and I did not prepare that now...
21:51 anyway, let me go back. This is what I
21:54 wanted to show... no, there's one
21:57 thing missing, but the main idea
21:59 is that I have enhanced my
22:04 `find-youtubedl-links'
22:07 with a way to download the transcript
22:09 of a video.

22:11 This way can be accessed by this last
22:15 block here in the temporary buffer...
22:18 and so this is new - this is something
22:21 that I added to `find-youtubedl-links'
22:25 in March... and also,
22:28 there are several
22:30 new tricks here. One trick, that is not
22:34 very obvious and not everyone has
22:36 figured out that red star lines can do
22:38 that, is that we can use a red star line
22:41 to do other things of setups, like
22:44 changing the mode of a buffer - even
22:48 a temporary buffer...
22:49 so this one puts it in Python mode.
22:53 The rest is more familiar...
22:56 and note that this first line here says
23:01 to Python to import a library that
23:05 downloads transcripts from YouTube...
23:07 either transcripts or subtitles, it
23:10 works for both cases...
23:13 when people are running this for the
23:15 first time they probably do not have
23:17 that library... so what can they do?

23:21 This sexp here calls pip3, that is the
23:26 package manager for Python 3, with this
23:29 argument here, that is the name of our
23:31 package...
23:33 and this thing here opens a temporary
23:35 buffer that lets me
23:38 install that package.
23:40 In this case I already have that package
23:43 installed, so I do not need to run
23:45 these things...
23:50 and let me show something that I have
(find-2022yttranscriptvideo "23:53" "added to this...
23:55 let's say, this module of eev, just a
23:59 few days ago. I've added these two
24:02 functions here. This one here
24:06 can be used to
24:10 show information about a package
24:12 that is already installed... let me
24:14 copy these two lines to my notes,
24:17 one second...
24:21 my notes are here...
24:27 so this sexp here
24:32 is also like a square dog, it's an
24:36 unusual kind of interface...

24:41 and it has this small Python program
24:44 here, that mentions the name of a package
24:46 in a certain point...
24:49 and in this small program here I import
24:53 a library called "importlib", that
24:59 handles "import" and the files that
25:02 import uses, and
25:04 its sublibrary metadata,
25:09 and pretty-print, and so on...
25:12 let me do that now...
25:16 here is a new Python
25:19 interpreter and I'm going to to run
25:22 these things...
25:23 if I do not have this package then this
25:27 import will fail, but I have this
25:29 package.

25:30 And now I'm going to run these things
25:33 here to get information about this local
25:35 package. Its init file is here...
25:42 now I'm going to run importlib with
25:44 a certain submethod to get information
25:47 about this package...

25:49 and I'm going to print some information
25:53 that is in this that data structure
25:58 here... and ta-da!
26:00 This is quite primitive, but basically
26:02 it shows how to obtain
26:05 information about Python a package
26:08 that is already installed
26:11 in a very low-level way...

26:15 so I think that people who are learning
26:17 Python are going to find this interesting.
26:20 And there's something similar, but that
26:25 checks the remote repository of Python
26:28 packages...
26:30 if execute this I get another
26:33 temporary buffer here...
26:41 and here I have
26:43 some information about the
26:45 functions that I'm going to to use now...

26:51 basically I'm going to
26:54 to ask this site here about information
26:57 about this package...
27:00 and well, it's...
27:04 sorry I'm not going to give
27:06 the details now... let me just show what
27:08 this does.
27:11 Let me run this again...
27:13 this takes a second because it has to
27:18 to talk to the internet,
27:20 and now I'm going to
27:22 explore this data structure a bit.
27:26 For example, this subfield of a subfield
27:29 here
27:31 has information about the home page of
27:35 the upstream version of this package...
27:38 I can visit this URL here...
27:45 I have just asked Emacs to open

27:52 a new tab in the browser with
27:54 this URL here... so
27:58 this is all the information about this
28:00 package, and
28:03 I think that not all these files are
28:06 downloaded when I install this package...
28:08 some of these files may be
28:10 documentation, examples...
28:12 I do not know this very well yet...
28:20 Yeah, so: that's it.
28:22 Let me finish the video now. So:
28:26 yeah, bye! =)