video


ffmpeg: Create a video countdown

The code below was used to generate the video countdown timers that are available in the following playlist using ffmpeg:

#This example will create a 3 second video, with 100 frames per second and it will print the elapsed and remaining times using a two second accuracy.
fps=100;
seconds=3;
mantissaDigits=2;
upperFont=600;
lowerFont=100;
ffmpeg -loop 1 -i ~/Pictures/Black-Background.png -c:v libx264 -r $fps -t $seconds -pix_fmt yuv420p -vf "fps=$fps,drawtext=fontfile='/usr/share/fonts/urw-base35/C059-Bold.otf':fontcolor=yellow:fontsize=$upperFont:x=(w-text_w)/2:y=(h-text_h)/2:text='%{eif\:($seconds-t)\:d}.%{eif\:(mod($seconds-t, 1)*pow(10,$mantissaDigits))\:d\:$mantissaDigits}',drawtext=fontfile='/usr/share/fonts/urw-base35/C059-Bold.otf':fontcolor=yellow:fontsize=$lowerFont:x=(w-text_w)/2:y=((h-text_h)/2)+$upperFont:text='Elapsed\: %{eif\:(t)\:d}.%{eif\:(mod(t, 1)*pow(10,$mantissaDigits))\:d\:$mantissaDigits}'" "$seconds seconds countdown timer.mp4";

Notes:

  • We used a single black frame for the background that defined the size of the video frame as well.
  • Using the fps variable we defined the number of Frames per Second for the video.
  • The seconds variable defined the number of seconds the duration of the video should be.
  • The mantissaDigits variable defines how many decimal digits should be shown after the dot.
  • upperFont and lowerFont define the size of the fonts in the upper row and the lower one respectively.
  • We used the drawtext directive twice to write to the frames.

Notes on the first drawtext:

  • fontfile='/usr/share/fonts/urw-base35/C059-Bold.otf' defines the font to be used for the text.
  • fontcolor=yellow defines the color of the font of the text.
  • fontsize=$upperFont defines the size of the font of the text.
  • x=(w-text_w)/2 defines the X-coordinate of the location for the text on the frame, here we center the text horizontally on the frame.
  • y=(h-text_h)/2 defines the Y-coordinate of the location for the text on the frame, here we center the text vertically on the frame.
  • text='%{eif\:($seconds-t)\:d}.%{eif\:(mod($seconds-t, 1)*pow(10,$mantissaDigits))\:d\:$mantissaDigits}' We print the remaining seconds for the video to finish with specific decimal digit accuracy.

Notes on the second drawtext:

  • drawtext=fontfile='/usr/share/fonts/urw-base35/C059-Bold.otf' defines the font to be used for the text.
  • fontcolor=yellow defines the color of the font of the text.
  • fontsize=$lowerFont defines the size of the font of the text.
  • x=(w-text_w)/2 defines the X-coordinate of the location for the text on the frame, here we center the text horizontally on the frame.
  • y=((h-text_h)/2)+$upperFont defines the Y-coordinate of the location for the text on the frame, here shift the text from the vertical center  of the frame.
  • text='Elapsed\: %{eif\:(t)\:d}.%{eif\:(mod(t, 1)*pow(10,$mantissaDigits))\:d\:$mantissaDigits}' We print the elapsed seconds since the video started with specific decimal digit accuracy.

Fedora 27: Setup stackskills-dl

A couple of days ago we were asked to setup stackskills-dl on a Fedora 27 (x64).
Apparently stackskills-dl is a Ruby script that allows a registered user to download the StackSkills tutorials for which the user has access to.

Following the instructions at https://github.com/yoonwaiyan/stackskills-dl are not enough to get the application running as the json gem and the Ruby development files appear to be missing from the filesystem.

Solution: Below are the steps we followed to setup stackskills-dl and make it operational:

sudo dnf install gem ruby-devel youtube-dl wget;
gem install json;
gem install bundler;
git clone https://github.com/yoonwaiyan/stackskills-dl.git;
cd stackskills-dl/;
bundle install;

After the above steps were completed, we were able to use stackskills-dl from the clone/installation folder normally:

[[email protected] stackskills-dl]$ ruby stackskills_dl.rb -u "[email protected]" -p "e#rf54HTw3se!fe678f." -s https://stackskills.com/courses/enrolled/007;
Loaded login credentials from environment variables.
Login Successfully.
Finding https://stackskills.com/courses/enrolled/007 from your list of courses
Number of courses found: 1
...

[[email protected] stackskills-dl]$ ruby stackskills_dl.rb --help
Usage: ruby stackskills_dl.rb [options]
-u, --email NAME Email
-p, --password PASSWORD Password
-c, --course COURSE_URL Course URL in ID.
-s, --course-slug COURSE_SLUG Course URL in slug.

With out the Ruby json gem you would get the following error:

[[email protected] stackskills-dl]$ ruby stackskills_dl.rb --help;
/usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- json (LoadError)
from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require'
from /home/george/.gem/ruby/2.4.0/gems/mime-types-2.99.1/lib/mime/types/loader.rb:226:in `load_from_json'
from /home/george/.gem/ruby/2.4.0/gems/mime-types-2.99.1/lib/mime/types/loader.rb:63:in `block in load_json'
from /home/george/.gem/ruby/2.4.0/gems/mime-types-2.99.1/lib/mime/types/loader.rb:62:in `each'
from /home/george/.gem/ruby/2.4.0/gems/mime-types-2.99.1/lib/mime/types/loader.rb:62:in `load_json'
from /home/george/.gem/ruby/2.4.0/gems/mime-types-2.99.1/lib/mime/types/loader.rb:88:in `load'
from /home/george/.gem/ruby/2.4.0/gems/mime-types-2.99.1/lib/mime/types/loader.rb:113:in `load'
from /home/george/.gem/ruby/2.4.0/gems/mime-types-2.99.1/lib/mime/types.rb:296:in `load_default_mime_types'
from /home/george/.gem/ruby/2.4.0/gems/mime-types-2.99.1/lib/mime/types.rb:323:in `<class:Types>'
from /home/george/.gem/ruby/2.4.0/gems/mime-types-2.99.1/lib/mime/types.rb:63:in `<top (required)>'
from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require'
from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require'
from /home/george/.gem/ruby/2.4.0/gems/mechanize-2.7.4/lib/mechanize/pluggable_parsers.rb:5:in `<top (required)>'
from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require'
from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require'
from /home/george/.gem/ruby/2.4.0/gems/mechanize-2.7.4/lib/mechanize.rb:1361:in `<top (required)>'
from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:133:in `require'
from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:133:in `rescue in require'
from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:40:in `require'
from /home/george/Videos/stackskills-dl/lib/course_finder.rb:1:in `<top (required)>'
from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require'
from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require'
from stackskills_dl.rb:4:in `<main>'


Extract audio from online video

Using the youtube-dl command line application you can download videos and directly extract the audio of the video in various formats.

youtube-dl supports a large variety of online video hosts, including:

  • youtube.com
  • 9gag.com
  • crunchyroll.com
  • dailymotion.com
  • southparkstudios.com

Note: Please be sure that you are allowed to download a video before you do that, many of these hosts do not expect that you will be downloading their videos as they do not allow that.

The following command, will download a video, convert it to an mp3 and delete the original video:

youtube-dl --extract-audio --audio-format mp3 https://www.youtube.com/watch?v=cwI-n3sI8ec

If you want to keep the original video, you just add the parameter -k or --keep-video.

The --audio-format parameter accepts other types of audio format outputs, specifically it supports

youtube-dl is a very powerful tool, advice the documentation for some of the great features it supports.

 


ffmpeg: Extract audio from .MKV to .MP3 6

The following command will find all mkv files that are in the current directory and in all sub-folders and extract the audio to mp3 format.

find . -type f -name "*.mkv" -exec bash -c 'FILE="$1"; ffmpeg -i "${FILE}" -vn -c:a libmp3lame -y "${FILE%.mkv}.mp3";' _ '{}' \;

The filename of the audio file will be the same as the mkv video with the correct extension. The mkv extension will be removed and replaced by the mp3 extension e.g hi.mkv will create a new file named hi.mp3


ffmpeg: Extract audio from .MP4 to .MP3

The following command will find all mp4 files that are in the current directory and in all sub-folders and extract the audio to mp3 format.

find . -type f -iname "*.mp4" -exec bash -c 'FILE="$1"; ffmpeg -i "${FILE}" -vn -y "${FILE%.mp4}.mp3";' _ '{}' \;

The filename of the audio file will be the same as the mp4 video with the correct extension. The mp4 extension will be removed and replaced by the mp3 extension e.g hi.mp4 will become hi.mp3


ffmpeg: Extract audio from .WEBM to .OGG 3

If you need to extract the audio from an .WEBM movie file to an .OGG audio file you can  execute the following:

FILE="the-file-you-want-to-process.webm";
ffmpeg -i "${FILE}" -vn -y "${FILE%.webm}.ogg"

The first command will assign the file name to a variable, we do this to avoid typing errors in the second command where we might want to use the same name for the audio file.

The second command, will use ffmpeg to extract the audio. The -i flag, indicates the file name of the input. We used the flag -vn that will instruct ffmpeg to disable video recording. The -acodec flag will set the output audio codec to vorbis. The -y flag will overwrite output file without asking, so be careful when you use it.

In case we want to automatically process (batch process) all .WEBM video files in a folder we can use the following:

for FILE in *.webm;
do
    echo -e "Processing video '\e[32m$FILE\e[0m'";
    ffmpeg -i "${FILE}" -vn -y "${FILE%.webm}.ogg"
done

The above script will find all .WEBM files in the folder and process them one after the other.

 

UPDATE:

The following command will find all webm files that are in the current directory and in all sub-folders and extract the audio to ogg format.

find . -type f -iname "*.webm" -exec bash -c 'FILE="$1"; ffmpeg -i "${FILE}" -vn -y "${FILE%.webm}.ogg";' _ '{}' \;

The filename of the audio file will be the same as the webm video with the correct extension. The webm extension will be removed and replaced by the ogg extension e.g hi.webm will become hi.ogg

 


ffmpeg: Extract audio from .WEBM to .AAC 2

If you need to extract the audio from an .WEBM movie file to an .AAC audio file you can  execute the following:

FILE="the-file-you-want-to-process.webm";
ffmpeg -i "${FILE}" -vn -ab 128k -ar 44100 -strict -2 -y "${FILE%.webm}.aac";

The first command will assign the file name to a variable, we do this to avoid typing errors in the second command where we might want to use the same name for the audio file.

The second command, will use ffmpeg to extract the audio. The -i flag, indicates the file name of the input. We used the flag -vn that will instruct ffmpeg to disable video recording. The -ab flag will set the bit rate to 128k. The -ar flag will set the audio sample rate to 441000 Hz.  The flags -strict -2 are required as the native FFmpeg AAC encoder that is included with ffmpeg is considered an experimental encoder. The -y flag will overwrite output file without asking, so be careful when you use it.

In case we want to automatically process (batch process) all .WEBM video files in a folder we can use the following:

for FILE in *.webm; do
    echo -e "Processing video '\e[32m$FILE\e[0m'";
    ffmpeg -i "${FILE}" -vn -ab 128k -ar 44100 -strict -2 -y "${FILE%.webm}.aac";
done;

The above script will find all .WEBM files in the folder and process them one after the other.

 

UPDATE:

The following command will find all webm files that are in the current directory and in all sub-folders and extract the audio to aac format.

find . -type f -iname "*.webm" -exec bash -c 'FILE="$1"; ffmpeg -i "${FILE}" -vn -ab 128k -ar 44100 -strict -2 -y "${FILE%.webm}.aac";' _ '{}' \;

The filename of the audio file will be the same as the webm video with the correct extension. The webm extension will be removed and replaced by the aac extension e.g hi.webm will become hi.aac

 


ffmpeg: Extract audio from .WEBM to .MP3 6

If you need to extract the audio from an .WEBM movie file to an .MP3 audio file you can  execute the following:

FILE="the-file-you-want-to-process.webm";
ffmpeg -i "${FILE}" -vn -ab 128k -ar 44100 -y "${FILE%.webm}.mp3";

The first command will assign the file name to a variable, we do this to avoid typing errors in the second command where we might want to use the same name for the audio file.

The second command, will use ffmpeg to extract the audio. The -i flag, indicates the file name of the input. We used the flag -vn that will instruct ffmpeg to disable video recording. The -ab flag will set the bit rate to 128k. The -ar flag will set the audio sample rate to 441000 Hz.  The -y flag will overwrite output file without asking, so be careful when you use it.

In case we want to automatically process (batch process) all .WEBM video files in a folder we can use the following:

for FILE in *.webm; do
    echo -e "Processing video '\e[32m$FILE\e[0m'";
    ffmpeg -i "${FILE}" -vn -ab 128k -ar 44100 -y "${FILE%.webm}.mp3";
done;

The above script will find all .WEBM files in the folder and process them one after the other.

 

UPDATE:

The following command will find all webm files that are in the current directory and in all sub-folders and extract the audio to mp3 format.

find . -type f -iname "*.webm" -exec bash -c 'FILE="$1"; ffmpeg -i "${FILE}" -vn -ab 128k -ar 44100 -y "${FILE%.webm}.mp3";' _ '{}' \;

The filename of the audio file will be the same as the webm video with the correct extension. The webm extension will be removed and replaced by the mp3 extension e.g hi.webm will become hi.mp3

 


ffmpeg: Extract audio from .MP4 to .OGG 1

If you need to extract the audio from an .MP4 movie file to an .OGG audio file you can  execute the following:

FILE="the-file-you-want-to-process.mp4";
ffmpeg -i "${FILE}" -vn -acodec libvorbis -y "${FILE%.mp4}.ogg"

The first command will assign the file name to a variable, we do this to avoid typing errors in the second command where we might want to use the same name for the audio file.

The second command, will use ffmpeg to extract the audio. The -i flag, indicates the file name of the input. We used the flag -vn that will instruct ffmpeg to disable video recording. The -acodec flag will set the output audio codec to vorbis. The -y flag will overwrite output file without asking, so be careful when you use it.

In case we want to automatically process (batch process) all .MP4 video files in a folder we can use the following:

for FILE in *.mp4;
do
    echo -e "Processing video '\e[32m$FILE\e[0m'";
    ffmpeg -i "${FILE}" -vn -acodec libvorbis -y "${FILE%.mp4}.ogg";
done

The above script will find all .MP4 files in the folder and process them one after the other.

 

UPDATE:

The following command will find all mp4 files that are in the current directory and in all sub-folders and extract the audio to ogg format.

find . -type f -iname "*.mp4" -exec bash -c 'FILE="$1"; ffmpeg -i "${FILE}" -vn -acodec libvorbis -y "${FILE%.mp4}.ogg";' _ '{}' \;

The filename of the audio file will be the same as the mp4 video with the correct extension. The mp4 extension will be removed and replaced by the ogg extension e.g hi.mp4 will become hi.ogg