Video lectures: unix way

Video lectures: unix way
Quarantine is a wonderful time to learn something. However, as you understand, in order for someone to learn something, someone must teach. If you have a presentation that you want to make in front of a million audience, gaining worldwide fame, then this article is for you. There will be step-by-step instructions on how to make a video out of a presentation.

The path of recording "sound notes" in PowerPoint and exporting the presentation to video, we brush aside as trivial and does not give a tenth of the possibilities that are needed for a truly cool video.

First, let's decide what frames we need:

  1. Own slides with voice-over
  2. slide change
  3. Interrupting quotes from popular films
  4. Several shots with the physiognomy of the lecturer and a beloved cat (optional)

Creating a directory structure

.
β”œβ”€β”€ clipart
β”œβ”€β”€ clips
β”œβ”€β”€ rec
β”œβ”€β”€ slide
└── sound

The purpose of the directories in the order listed: films from which we will pull quotes (clipart), fragments of our future video (clips), videos from the camera (rec), slides in the form of pictures (slide), sound (sound).

Making a picture presentation

For a real red-eyed Linuxoid, making a presentation in the form of pictures does not present any problems. Let me just remind you that a pdf document can be parsed into images by the command

pdftocairo -png -r 128 ../lecture.pdf

If there is no such command, put yourself a package poppler-utils (instructions for Ubuntu; if you have Arch, then you already know perfectly well what to do without me).

Here and below, I believe that the video is being prepared in HD Ready format, i.e. 1280 Γ— 720. A presentation with a horizontal size of 10 inches produces exactly that size when unloaded (see the -r 128 option).

Preparing the text

If you want to make really cool material, then your speech must first be written. I also thought that I could speak the text without preparation, especially since I have a good experience in lecturing. But it's one thing to perform live, and another to record a video. Do not be lazy - the time spent on typing will pay off many times over.

Video lectures: unix way

Here is my entry format. The number in the title is equal to the number of the slide, breaks are highlighted in red. Any editor is suitable for preparation, but it is still better to take a full-fledged word processor - for example, only Office.

Voice over slides

What can I say - turn on the microphone and write πŸ™‚

Experience shows that the recording quality from even the cheapest external microphone is incomparably better than from the laptop's built-in microphone. If you want quality equipment, then I recommend this article.

For the record I used audio recorder is a very simple recording application. You can take it, for example, here:

sudo add-apt-repository ppa:audio-recorder/ppa
sudo apt-get update
sudo apt-get install audio-recorder

The main thing at this step is the correct naming of the files. The name must consist of the slide number and the fragment number. Fragments are numbered with odd numbers - 1, 3, 5, etc. So, for the slide, the text of which is shown in the picture, two files will be created: 002-1.mp3 ΠΈ 002-3.mp3.

If you recorded all the clips at once in a quiet room, then you can do nothing with them. If you recorded in several steps, it is better to equalize the volume level:

mp3gain -r *.mp3

Utilities mp3gain for some reason it is not in the standard repositories, but you can get it here:

sudo add-apt-repository ppa:flexiondotorg/audio
sudo apt-get update
sudo apt-get install mp3gain

After all this, you need to write another file with silence. It is necessary to add an audio track to silent videos: if one video has an audio track and the other does not, then it is difficult to glue these videos together. Silence can be recorded from a microphone, but it is better to create a file in an editor Audacity. The length of the file must be at least a second (or more), and it should be named silence.mp3

Preparing roll-ups

Here everything is limited only by your imagination. You can use the editor to edit the video Avidemux. Once it was in the standard repositories, but then for some reason it was cut out. It won't stop us:

sudo add-apt-repository ppa:ubuntuhandbook1/avidemux
sudo apt-get update
sudo apt-get install avidemux2.7-qt5

There are a lot of instructions for working with this editor on the net, but in principle, everything is intuitively clear there. It is important to comply with several conditions.

First, the resolution of the movie must match the target resolution of the movie. To do this, you need to use two filters in the "video to exit": swsResize to change the resolution and "add margins" to make a wide format out of a Soviet "narrow-format" film. All other filters are optional. For example, if someone does not understand what Mr. Sharikov’s statement is about in the fragment under discussion, using the β€œadd logo” filter, you can overlay the PostgreSQL logo on top of the β€œHeart of a Dog”.

Secondly, in all fragments you need to use the same frame rate. I use 25 frames per second, because that's what my camera and old Soviet films give. If the movie you're cropping from is shot at a different speed, use the "resample video" filter.

Thirdly, all fragments must be compressed with the same codec and packed into the same containers. Therefore, in Avidemux for the format, select video - "MPEG4 AVC (x264)", audio - "AAC (FAAC)”, the output format is β€œMP4 MuxerΒ».

Fourth, it is important to correctly name the cut videos. The file name must consist of a slide number and a fragment number. Fragments are numbered with even numbers, starting from 2. So, for the frame under discussion, the clip with interruption should be called 002-2.mp4

After the videos are ready, you need to transfer them to the directory with fragments. Settings avidemux different from settings ffmpeg by default with cryptic parameters tbr, tbn, tbc. They do not affect playback, but they do not allow the videos to be glued together. So let's recode:

for f in ???-?.mp4;
do
  ffmpeg -hide_banner -y -i "${f}" -c copy -r 25 -video_track_timescale 12800 ../clips/$f
done

We shoot screensavers

Here, too, everything is simple: shoot against the background of some smart scheme, add the resulting videos to the catalog rec, and from there transfer to the directory with fragments. The naming rules are the same as for break quotes, the recoding command is:

ffmpeg -y -i source_file -r 25 -vcodec libx264 -pix_fmt yuv420p -profile:v high -coder 1 -s 1280x720 -ar 44100 -ac 2 ../clips/xxx-x.mp4

If you plan to start the video with your speech, name this fragment 000-1.mp4

Making frames from static pictures

It's time to mount videos from static pictures and sound. This is done with the following script:

#!/bin/bash

for sound in sound/*.mp3
do
  soundfile=${sound##*/}
  chunk=${soundfile%%.mp3}
  clip=${chunk}.mp4
  pic=slide/${chunk%%-?}.png

  duration=$(soxi -D ${sound} 2>/dev/null)
  echo ${sound} ${pic} ${clip} " - " ${duration}

  ffmpeg -hide_banner -y -loop 1 -i ${pic} -i ${sound} -r 25 -vcodec libx264 -tune stillimage -pix_fmt yuv420p -profile:v high -coder 1 -t ${duration} clips/${clip}
done

Please note that the duration of the sound file is first determined by the utility soxi, and then the video of the desired length is mounted. All the recommendations I found are simpler: instead of a flag -t ${duration} flag is used -shortest. In fact ffmpeg determines the length of an mp3 very approximately, and during editing, the length of the audio track can differ greatly (by one or two seconds) from the length of the video track. It does not matter if the entire video consists of a single frame, but when gluing such a clip with a break at the border, extremely unpleasant stuttering effects occur.

Another way to determine the length of an mp3 file is to use mp3 info. She also makes mistakes, and sometimes ffmpeg gives more than mp3 info, sometimes vice versa, sometimes both lie - I did not notice patterns. And here soxi works correctly.

To install this useful utility for yourself, do this:

sudo apt-get install sox libsox-fmt-mp3

Making transitions between slides

A transition is a short video in which one slide turns into another. To make such videos, we take slides in pairs and with the help of imagemagick turn one into the other:

#!/bin/bash

BUFFER=$(mktemp -d)

for pic in slide/*.png
do
  if [[ ${prevpic} != "" ]]
  then
    clip=${pic##*/}
    clip=${clip/.png/-0.mp4}
    #
    # Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ
    #
    ./fade.pl ${prevpic} ${BUFFER} 1280 720 5 direct 0
    ./fade.pl ${pic} ${BUFFER} 1280 720 5 reverse 12
    #
    # Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΠ»ΠΈ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ
    #
    ffmpeg -y -hide_banner -i "${BUFFER}/%03d.png" -i sound/silence.mp3 -r 25 -y -acodec aac -vcodec libx264 -pix_fmt yuv420p -profile:v high -coder 1 -shortest clips/${clip}
    rm -f ${BUFFER}/*
  fi
  prevpic=${pic}
done

rmdir ${BUFFER}

For some reason, I wanted the slide to crumble into dots, and then the next slide was assembled from the dots, and for this I wrote a script called fade.pl Having imagemagick, a real linuxoid will create any special effect, but if someone likes my idea with scattering, then here is the script:

#!/usr/bin/perl

use strict;
use warnings;
use locale;
use utf8;
use open qw(:std :utf8);
use Encode qw(decode);
use I18N::Langinfo qw(langinfo CODESET);

my $codeset = langinfo(CODESET);
@ARGV = map { decode $codeset, $_ } @ARGV;

my ($source, $target, $width, $height, $pixsize, $rev, $file_no) = @ARGV;

my @rects;
$rects[$_] = "0123456789AB" for 0..$width*$height/$pixsize/$pixsize/12 - 1;

for my $i (0..11) {
  substr($_,int(rand(12-$i)),1) = "" for (@rects);
  my $s = $source;
  $s =~ s#^.*/##;
  open(PICTURE,"| convert - -transparent white PNG:- | convert "$source" - -composite "$target/".substr("00".($file_no+$i),-3).".png"");
  printf PICTURE ("P3n%d %dn255n",$width,$height);
  for my $row (1..$height/$pixsize/3) {
    for my $j (0..2) {
      my $l = "";
      for my $col (1..$width/$pixsize/4) {
        for my $k (0..3) {
          $l .= (index($rects[($row-1)*$width/$pixsize/4+$col-1],sprintf("%1X",$j*4+$k))==-1 xor $rev eq "reverse") ? "0 0 0n" : "255 255 255n" for (1..$pixsize);
        }
      }
      print PICTURE ($l) for (1..$pixsize);
    }
  }
  close(PICTURE);
}

We mount the finished video

Now we have all the fragments. Go to catalog clips and assemble the finished movie with two commands:

ls -1 ???-?.mp4 | gawk -e '{print "file " $0}' >list.txt
ffmpeg -y -hide_banner -f concat -i list.txt -c copy MOVIE.mp4

Happy viewing to your grateful students!

Source: habr.com

Add a comment