File List

Files of check-in [dc92eafe60] in the top-level directory

I make videos of myself narrating tongue twister scenes.

This endeavor is a very complex system, so the present software/catalog handles
many difficult situations.

1. Many people do not completely remember certain tongue twisters, so it is
   possible to enter partial information and easily fill in the remaining
   information later.
2. Many people do not know how to write in one of their mother languages,
   or they only know how to handwrite, not how to type. It is possible to write
   the tongue twister phonetically in an alternative script.
3. Tongue twisters tend to be very difficult to translate, and translators
   usually won't understand the tongue twister's original language. It is
   possible to display translations of one tongue twister in several languages,
   including the "literal" English translation, in order that a translator
   may get a better sence of the original meaning.
4. Most bilingual dictionaries are inadequete for this sort of translation,
   as they tend to be incomplete or vague. My "vortaro" software (distributed
   separately) is a high-performance bilingual dictionary software that can
   display translations between many different language pairs at once, which
   can help to clarify things when one particular bilingual dictionary is
5. Wikipedia is often very useful in the translation process, so a future
   tool that queries wikidata could be very helpful.
6. For purposes of research, video editing, and proofreading, I find it most
   convenient organize data by tongue twister. This format is not convenient
   for translation, so I convert the data to different formats for translation.
   Several formats are available to support the different softwares that people
   may use to write translations.
7. I export to several video, audio, subtitle, and web formats with conflicting
   concepts of what a language is; I thus use linked open data to convert my
   internal concept of a language to appropriate versions for the different
   output formats.
8. The dependencies for each particular output file are usually rather
   complex, and many output files take a long time to build. After I add new
   data, the software checks what has changed and rebuilds only the stale
   output files.

The output of the present software is intended as input to
dadaportal (
The following files are created.

    Play a video of the concatenated short videos. Link to the long video
    pages and to the help page.
    The concatenated video
    Subtitle tracks for the concatenated video
    Play a long video of a particular tongue twister.
    Subtitle tracks for the long videos
    Request assistance in learning, shooting, and translating tongue
    twisters. List languages for which I have not learned tongue
    twisters, request that people email me to help prepare scenes,
    and link to translation spreadsheets.
    Translation spreadsheets

The "output" directory should be a symbolic link to the src/!/langrompiloj/
directory for so that can be inputs to dadaportal and
rendered at!/langrompiloj/.

Making a new tongue twister
In the context of the management software, a "scene" is a recording of
me saying a particular, possibly with a video of the phrase of interest.
A "tongue twister" is a group of scenes where the phrases are the same
or the phrases are in different languages but share the same meaning.

Create a directory under "tongue-twisters/", copy
"lib/" to "Makefile" in that directory, and
replace the various fields with the necessary information.

Inside of that, create scenes in subdirectories of the "concat",
"standalone", "placeholder", "mumble", "slow", and "fast" directories.
(I call these the six "kinds". The meaning of these kinds is discussed
elsewhere in the documentation.) Copy "lib/" to
"Makefile" in the scene directory

Inside the tongue twister directory,

1. Run "make skeleton" to create subdirectories.
2. Copy recordings to the "recordings" directory.
3. Run "make placeholder" to take an audio recording.
4. Add the text of the tongue twister in the text directory. Minimally
   add one for each language set in "ORIGINAL_LANGUAGES" in the various
   "Makefile" files.
5. Run "make help" for directions on building the website and video.

Remember this when taking the video.

* Before shooting the video, practice by recording myself, listening to
  the recording, and comparing to references.
* Smile.
* Wait a few seconds before starting the scene.
* Stand still for a few seconds after the scene.
* Clothes options

  * Suit (Switch tie and shirt.)
  * Bright clothes (Like yellow and green)

I use a bespoke language list, falling back to ISO 639-3.
But I started the bespoke language list with this command.

  cut -f4,1,7 iso-639-3_Code_Tables_20170217/ |
    grep -v '[^a-z]\{3\}' | cut -f1,3

Find the duration of a video file like this.

    ffprobe -v error -show_entries format=duration \
            -of default=noprint_wrappers=1:nokey=1 "$(filename)"

Add a utility to help me put the duration in the file where it says "$".
This way, I don't need to calculate the duration in the build process.


* sh
* BSD make
* ffmpeg (for cutting video)
* python3
  * Jinja2 module (for writing web files)
  * horetu module (for command-line interfaces),
    though this dependency could be removed easily


* mpv (for cutting and playing video)
* mkvmerge (for mkv output with contained subtitles)

Subtitle construction
Subtitle construction is among the more complex aspects of this project, as
I translate the tongue twisters into different languages in order to construct
subtitles in different languages.

I produce a subtitle track for each combination of language
(English, Esperanto, &c.) and subtitle export format (only WebVTT for now), and
video file (main video or long video). In addition, for the main video I produce
subtitle tracks with the tongue twisters in their original languages, one track
per export format.

Subtitles are internally stored as lists of timings and lists of texts,
one timing list per short or long video, and one list of texts per scene.
Dependencies thus look like this.

* Each long video subtitle track depends on the timing list for the scene's
  long video and on the text list for the language within the scene.
* The main video subtitle tracks depend on the timing lists for all scenes'
  short videos, on the text lists for all the scenes' short videos the
  track's language, and on the lengths of the concatenated videos.
* The original language subtitle track for the main video additionally depends
  on the identifier of the language of each particular scene, in order that
  the appropriate short video subtitle information may be selected.

Internal subtitle format
With each scene I select a short video, to be played in a series with the
others, and a long video, to be played on its own. With each of these two videos
I create a subtitle timings file that looks like this.


The first line (3.043) is where the first part of the subtitle should appear,
the last line (5.179) is where it should disappear, and the lines in-between are
where other parts of the tongue twister should appear, in "karaoke" style
as described in the WebVTT specifications. The special time "$" is available
to indicate the end of the video; this file would show subtitles from
1.2 seconds to the end, adding a second part at 2.1 seconds.


and this one would show the full subtitle for the full video.


Both subtitle timings files (for the long video and the short video) must have
the same number of lines.

Subtitle texts are specified in a different file, one such file per language,
and the software combines them with the timings files. All subtitle text files
(one per language) must have the same number of lines, and this must be one
fewer line than the number of lines in the timings files.

Consider this subtitle timing file that I also included above.


It could be combined with the following subtitle text file.


This would result in
"生麦、" being displayed from 3.043 to 3.794 seconds,
"生麦、生米、" being displayed from 3.794 to 4.295 seconds, and
"生麦、生米、生卵" being displayed from 4.295 to 5.179 seconds.

The most annoying part of this project is carrying the tripod, as a
decent tripod will be big and heavy. My current thinking is to get a
light tripod that gets very small and to get something like the things


The other components are pretty simple.

* A video camera with a decent microphone
* A personal computer
* A neutral thing for white balance

But, separately, I am considering starting to carry a suitcase;
if I do that, I might as well bring a normal tripod too.

The Logitech 4K camera seems to work with Linux.

You can help me document tongue twisters by teaching me tongue twisters,
participating in videos, and translating tongue twisters.

Teaching tongue twisters can involve telling me about the popular tongue
twisters in different languages or critiquing my pronunciation.
I am interested only in the well known tongue twisters. If you tell me
which tongue twisters are popular in a particular language, I will look
on the internet for recordings of people saying them, and I will
practice with these. It is best if you write it in the native script.
(If I can't find such recordings, it would also be very nice for you to
record yourself saying the tongue twister.) It would be also helpful if
you translate them to English, but I usually can figure out how to
translate the simpler tongue twisters.

Many of the tongue twister scenes require human actors or strange objects,
and I prefer to record them around varied and interesting scenery. Please
email me if you are willing to participate in a tongue twister scene or
to help prepare one. I am happy to travel, so do not be concerned about
geospatial difficulties.

I want have all the tongue twisters translated to many different languages.
Most have already been translated to English, so I have prepared
spreadsheets for translating from English to other languages. These
spreadsheets include the existing translations and have blank cells for
the missing translations.

Cut format
Each output media file corresponds a ``$scene/cuts/$name`` directory.
It contains these files.

    the source file, probably a symbolic link
    ``[start [end [volume]]]``
    subtitle timings format
    Something like ``cs``.
poster.jpg or poster.txt
    Either an image (jpg) or a time within the source (txt) to use as the poster

The type and slug are based on the directory name.

    Specify the type and slug.
    These are allowed if there would be no conflicts.
    In the case of "concat", use "concat" as the slug.
    In the other cases, use the scene slug as the slug.
    The full directory name is used as the slug.
    The number is used to compose the subtitles.

In the resulting webpage, the cuts are ordered first by type, in the following
order, and then lexicographically by slug.

Standalone or placeholder cuts are displayed first.
If any standalone is available, display only standalone(s).
If no standalone is available and placeholders are available, display only placeholder(s).

Mumble and slow cuts are displayed only if they are complete, that is, there are
as many mumble and slow cuts as there are chunks (syllables) in the tongue
twister. Fast cuts are displayed only if mumble and slow cuts are available and
the fast cuts are also complete. If any educational cuts are displayed,
directions for training are included as well.

Concat cuts are displayed only in the concatenated video.

Language tags
I mostly follow IETF language tags, but I include non-standard languages, and
I use only a subset of the tags. My tags have one of these formats. ::


No tags bear any formal relation to each other in my program. The only
relationship I am presently considering is between tags occurs when two
tags both define alphabets and differ only alphabet. I would use this to
suppress display of one of the languages when translations are presented.