Downloading video from youtube

This might sound complicated, but youtube videos come in many shapes, many of them have either video only, or audio only !

the best way to get a full resolution video is to download then combine video and audio !

But before we go there, youtube throttles the speed you download videos at ! so youtube-dl needs patching, an alternative would be yt-dlp (See here)

The easier way to install would be

apt install yt-dlp

Now, if you insist on pip, you can do the following

apt install python3-pip

python3 -m pip install --force-reinstall https://github.com/yt-dlp/yt-dlp/archive/master.tar.gz

Now, let us try downloading a video/audio

youtube-dl -F https://www.youtube.com/watch?v=mUvrLxaSolc

The line above will show you a bunch of options and their IDs, what you need to do now is to download the ones you need with a command such as

youtube-dl -f 270 https://www.youtube.com/watch?v=mUvrLxaSolc

Now, to combine them (Audio and video) without re-encoding…

ffmpeg -i ao.webm -i vo.webm -c:v copy -c:a copy output.webm

But remember when you download,

Only VP8 or VP9 or AV1 video and Vorbis or Opus audio and WebVTT subtitles are supported for WebM.

If you have installed via pip3

/usr/local/bin/yt-dlp ...

ffmpeg cheat sheet

Combine video and audio (yt-dlp)

First of all, after using yt-dlp to download 2 webm files for a video, you can combine them without reencoding using the following command (See here), Just make sure both files are VP8 or VP9

ffmpeg -i ao.webm -i vo.webm -c:v copy -c:a copy output.webm

Extract segment from video

To extract the section from the file resulting from the first command above

1- From second x, and duration in seconds

ffmpeg -ss 285 -i g_in.mkv -t 5475 -map 0 -c copy g_out.mkv

2- From second x to second y

ffmpeg -copyts -ss 4633 -i g_in.mkv -to 5470 -map 0 -c copy g_p2.mkv

Convert file

Converting a file you have downloaded using 1 or any other file into MP4 (H264), since some windows computers will not play a webm file !

ffmpeg -i source264.mp4 -c:v libx265 -crf 28 -preset fast -c:a aac -b:a 128k  -filter:v fps=25 out265.mp4

If you want to cut a part of the video, without re-encoding it

ffmpeg -i input.mp4 -vcodec copy -acodec copy -ss 00:01:00.000 -t 00:00:02.000 output.mp4

nVidia (GPU) : Convert H264/H265

Nvidia graphics card to convert H265 (MKV) to H264 MP4, Using nvidia hardware encoder to encode video into H264 or H265 !

To checks whether hardware encoders are available or not, run the command

ffmpeg -encoders | findstr /ic:"NVIDIA"

If the following two lines are in the command, you can use the nVidia encoder, the first codec is H264, and the second is for H265 (HEVC)

V....D h264_nvenc           NVIDIA NVENC H.264 encoder (codec h264)
V....D hevc_nvenc           NVIDIA NVENC hevc encoder (codec hevc)

ffmpeg.exe -vsync 0 -hwaccel cuda -i <input_file> -map 0  -c:a copy -c:v h264_nvenc -pix_fmt yuv420p -preset hq <output_file>

-vsync : Synchronize video audio and metadata using the video timestamp
-hwaccel cuda : Use nVidia’s cuda for hardware accelleration

Example, Convert mkv to mp4 (Tested OK)

Now, with the above out of the way, the following command should encode your 1080P mkv H265 video to H264 ! all within GPU, so this re-encodes an nVidia compatible format to another nVidia compatible format, on my 1650 card, it was encoding at 12x. this provides better compatibility, if smaller file size and quality are what you seek, then you should do it the other way around

ffmpeg -i "1080p.mkv" -c:v h264_nvenc -pix_fmt yuv420p -minrate 500k -maxrate 1000k -c:a mp3 -b:a 128k "1080p.mp4"

The other way around

ffmpeg -i "1080p.mp4" -c:v hevc_nvenc -pix_fmt yuv420p -minrate 200k -maxrate 1000k -c:a aac -b:a 128k "1080p.mkv"

NOTE: The above does everything within the GPU, if for example you wanted the decoding on CPU, that will make things much slower because the decoded video (Huge) will still need to be copied to the GPU,

nVidia : DVD to H265

Encoding H265 with my entry level GPU (1650) is around five to fifteen times faster than with CPU (6 core, 12 thread i7-4930K), CPU was running at around 50% load through the encoding

Now one very common task people want to execute is converting their old, bulky DVD collection to H265 (Or H264 if they value compatibility over size and clarity), DVD files are usually on a DVD in the Video_TS folder, and the AudioTS folder, So this will create a few cases

Case 1: Audio_ts folder is empty, Video TS folder has files that you know the order they should be displayed in, the objective is to put them all in one video file (Assuming MKV but the container is your choice), in this case, I usually start by converting all the videos to H265, then combine them, here, most of my videos are interlaced (that will be dealt with with yadif), and sometimes, they are files of different resolutions, so I will unify their size

ffmpeg -i "v1.VOB" -c:v hevc_nvenc -c:a aac -b:a 256k -vf yadif,scale=1920:1080 -x265-params "crf=22:min-keyint=25:keyint=50" -preset slow "d1.mkv"

Now, create a list of the files

(for %i in (*.mkv) do @echo file '%i') > mylist.txt

And concatenate the videos

ffmpeg -f concat -i mylist.txt -c copy output.mkv
Now, to batch process a folder on the command line... in this example i am lowering the resolution of files to FHD from 4K
for /f "tokens=1 delims=." %a in ('dir /B *.mp4') do ffmpeg -i "%a.mp4" "%a.1080.mp4"

And here is one meant to extract the audio from all the MP4 files

Windows

for /f "tokens=1 delims=." %a in ('dir /B *.mp4') do ffmpeg -i "%a.mp4" -vn -acodec copy "%a.aac"

Linux

for i in *.mp4; do ffmpeg -i "$i" -vn -acodec copy "${i%.*}.aac"; done

Split audio file

ffmpeg -i 2024-07-27_20_38_2.m4a -f segment -segment_time 1740 output_%03d.m4a

Converting MKV to MP4

Here is a case where my MKV file contains the audio in AAC, and the video in H264, As you slide the slider in VLC media player, it tells you what the section is about, i should be able to copy the streams exactly as they are, but I was concerned that the “Slider Hints” would disappear, hence I split it into audio and video without re-encoding, checked that the hints are still there in the video, then combined them into an MP4, also without encoding, the reason I wanted the container to be MP4 is that sometimes I access my network files in a browser, and browsers seem more comfortable playing MP4 files than MKV

* ffmpeg -i My_Dinner_With_Andre_1981.mkv -vn -acodec copy ao.aac
* ffmpeg -i My_Dinner_With_Andre_1981.mkv -an -c:v copy vo.mp4
* ffmpeg -i ao.aac -i vo.mp4 -c:v copy -c:a copy My_Dinner_With_Andre_1981.mp4

Making a video smaller

A couple of hours ago, i received a video that is 50 frames per second, and compressed in H264, the video was 58MB, and she wanted it less than 15 to send it via email, the video was 1:45 long, so i re-encoded it in H-265 but she had a problem playing it (No codec), so i decided to re-encode it with VP9 (webm).

to arrive at a number less than 10, i needed to be encoding at around 1 MegaBIT per second, now, to do this, I made a 2pass encoding with ffmpeg as follows

ffmpeg -i source.mp4 -c:v libvpx-vp9 -b:v 1M -filter:v fps=25 -pass 1 -an -f null /dev/null && \
ffmpeg -i source.mp4 -c:v libvpx-vp9 -b:v 1M -filter:v fps=25 -pass 2 -c:a libopus out.webm

The first pass collects statistics about the source video in a text log file, the second pass encodes the new video, from the options above, i have taken the frame rate to 25fps (from 50), and instead of defining the crf, i simply told ffmpeg what the biterate I need is, which is 1Mbit per second (Every 8 seconds, 1 MBYTE)

The previous one, H-265 was done with the command

ffmpeg -i source264.mp4 -c:v libx265 -crf 28 -preset fast -c:a aac -b:a 128k  -filter:v fps=25 out265.mp4

the H265 was smaller due to the crf factor used, as well as the lower frame rate

Audio Video Libraries at home DLNA etc

This is basically a comparison of free sofwtare that you can install on your NAS or headless linux machine, I am using Debian Bullseye, but that is besides the point

To run webm files (VP9) through miniDLNA, all you need to do is rename the file !

My atom PC (D525) is not capable of transcoding on the fly, so i keep it, and i wrote a script to execute the following command for webm video files (and any other unsupported file) by browsing to the file in the web browser, then clicking on it, a simple script but explaining how to install it is going to take some times with permissions and server config, so i will probably be posting it online and explaining in a different post when i have the time

ffmpeg -y -i output.webm -c:v libx265 -b:v 2600k -x265-params pass=1 -an -f null /dev/null && \
ffmpeg -i input -c:v libx265 -b:v 2600k -x265-params pass=2 -c:a aac -b:a 128k TEMP_OUTPUT.mp4

the most popular of the bunch is MiniDLNA, it does not transcode, and on openWRT it does not even serve video, so it is a good option when you have a PC storing the files, and you don’t need transcoding on the fly ! for some devices that are capable of running VP9 like modern 4K TVs,all you need to do is rename the file !

Universal Media Server : Universal Media Server is a DLNA-compliant UPnP Media Server. It was originally based on PS3 Media Server by shagrath.

OSMC

Streama: Self hosted streaming media server.

Gerbera: Free UPnP media server based on MediaTomb

Watermarking Video with ffmpeg

In this post, I will be explaining how to watermark videos with a PNG image watermark that is transparent where it needs to be, I will cover both Linux and Windows (Not much is different on the ffmpeg side, the difference is when you want to traverse a directory (The script).

The watermark you see here is what I want to overlay over the video, If you right click and view the image, you should be able to see that around the text, it is transparent.

The PNG with transparency to be overlaid over the video

now, let us assume that the file in the directory is called x.mp4, and this watermark image is called watermark.png, then the following commands should overlay this image over the video

ffmpeg -i x.mp4 -i watermark.png -filter_complex "overlay=10:10" x1.mp4

The code above will create a new file (x1.mp4) which has the overlaid watermark, as you might be able to see if you execute the above the watermark is positioned at the top left corner of the video, which is not necessarily what you want, now because we know the dimensions of the watermark image, we can ask ffmpeg to center it horizontally (and if you like vertically to have it in the center of the image, but this is not what i want.

So let’s assume the video is full HD, meaning it has the dimensions 1920 x 1080 (Width x Height), and the image, as you can see has the dimensions (500 x 100), what i want here is to have the watermark centered horizontally and nudged down 100 pixels vertically, the code to do that would be

ffmpeg -i z.mp4 -i watermark.png -filter_complex "overlay=x=(1920-500)/2:y=100" z3.mp4

And in case this is not clear, here is a code to place it in the bottom right side of the screen

ffmpeg -i z.mp4 -i watermark.png -filter_complex "overlay=x=(1920-500):y=(1080-100)" z6.mp4

Now with the process of watermarking out of the way, How do we batch process videos under windows and under linux ?

Under Linux it is simple, I put all the input files in a directory named “in” and all the output is to be put in an directory called “out”, the shell script (batch file) is at the root where those 2 directories exist, the shell script is this

!/bin/bash
OIFS="$IFS"
IFS=$'\n'
for filename in "in/"*.mp4; do
ffmpeg -i "$filename" -i /apth_to_watermark/watermark.png -filter_complex "overlay=x=(1920-500):y=(1080-100)" "out/$(basename "$filename" .mp4).mp4"
done
IFS="$OIFS"

I have never been good at windows, so i looked around for a script to traverse a directory, I found some stuff, and here is my final result, if you can clean it up and make it more robust, please do leave me a comment and i will improve with your recommendations.

Converting DVD to MP4 (H264) on windows (With the free ffmpeg tool)

Converting DVD files to MP4

Video files on a DVD are usually in the video_ts directory and have the extension VOB.

On Windows, the easiest way to do this is by copying the files in the video directory on the DVD to a folder in your hard drive, then running the commands below, then deleting the source VOB files,

NOTE to ignore: surely, you can do it by adding absolute paths, but that would force me to explain much more here. with find the directory and copy the path then append it here then copy the names and append them to the path and all that good stuff, so why not just make it simple with copy then delete the source.

Assuming you have ffmpeg installed and in your path, you would execute the command like so, concatenating all the video files in the DVD

cd c:\directory_where_you_put_the_vob_files
ffmpeg -i "concat:VTS_01_1.VOB|VTS_01_2.VOB|VTS_01_3.VOB|VTS_01_4.VOB|VTS_01_5.VOB" outfile.mp4
Another note to ignore, On a linux box (The above works on both linux and windows), you can concatinate the VOB files then pipe them into ffmpeg like so
cat VTS_01_1.VOB VTS_01_2.VOB VTS_01_3.VOB VTS_01_4.VOB VTS_01_5.VOB | ffmpeg -i - outfile.mp4

Extracting Audio from youtube files without loss of quality

To not get you confused with terminology, let’s create our own with the simple words we know.

For those who have been here before and want the lowdown to remind them of the commands, just scroll to the bottom of this post.

this bit of theory i am starting with is not needed for you to extract your audio, but simply to introduce you to what we are doing

The video file has 2 sub files, one for video and one for audio, and they are synchronized together so that the people’s lips movement in the video appear to be speaking what the audio file is playing.

If we do not want to lose any of the audio’s quality by decoding then re-encoding again, we will want to extract the “Inner audio file” without modifying it, and to put it into a separate file (container).

Separating the audio from the video is easy with a free tool called ffmpeg, and here are the exact instructions

1- Make sure ffmpeg is installed on your computer and is added to the system path, if not see the article (installing ffmpeg)
2- Download the youtube or any other video file to c:downloadvideo, assuming we have 2 tutorial files one is tutorial.flv and the other is tutorial.mp4, both were downloaded from youtube.com (if you don’t know how to download a youtube video, see this article).
3- open the command line (Command prompt can be opened from your start menu, look in accessories).
4- Enter the following command into your command prompt to change active directory to where you have your files, in our example we enter the following into the command prompt

cd c:downloadvideo

5-Then, for my first file, i will execute the command

ffmpeg -i tutorial.flv

You should now see, on your command prompt window, what sub files (streams) are inside your container file (the file you downloaded from youtube or anywhere else).

--------------------------------------------------------------
  Duration: 00:02:06.59, start: 0.000000, bitrate: 64 kb/s
    Stream #0.0: Video: flv, yuv420p, 320x240, 29.97 tbr, 1k tbn, 1k tbc
    Stream #0.1: Audio: mp3, 22050 Hz, mono, s16, 64 kb/s
--------------------------------------------------------------

if you don’t see the word mp3 like this example, don’t panic, just move on to step 7.

In our first example file, the audio stream turned out to be an MP3 stream as you can see below, if that was not the case and we had a different format (As i will explain next), we would have had different choices in extracting, but for this example, we have MP3, meaning we do not need to re-encode anything, just copy the stream from the container we downloaded into a new container that will be created

6- Extract the MP3 file without re-encoding and while keeping full quality like in the video

ffmpeg.exe -i tutorial.flv -acodec copy tutorial.mp3

But for some reason, copeying the OGG ogg vorbis from a webm file without reencoding did not work untill i added the -vn switch

ffmpeg -i Bir_G_zellik_Yap_Murat_Dalk_l.webm -vn -acodec copy test1.ogg

So, now i have the file tutorial.mp3 that simply has the same clarity as my video file. the -acodec copy parameter told ffmpeg to just copy into new file, and not to re-encode

7- If it does not say mp3 anywhere in your results, you have a different audio format. that we will deal with now.

so let us deal with our second file tutorial.mp4 that turned out not to have MP3 in it, but rather AAC.

So executing the command

ffmpeg.exe -i tutorial.mp4

Returned the result

--------------------------------------------------------------
Duration: 00:05:02.44, start: 0.000000, bitrate: 281 kb/s
  Stream #0.0(und): Audio: aac, 44100 Hz, mono, s16
  Stream #0.1(und): Video: h264, yuv420p, 320x240 [PAR 1:1 DAR 4:3], 25 tbr, 25 tbn, 50 tbc
--------------------------------------------------------------

In this case, we do NOT have the option that will allow us to get an MP3 without re-encoding, we can re-encode it into MP3 as i will show you in a bit, or we can extract and use an AAC audio file.

An AAC file is not at all bad, sometimes it is better than an MP3. Why ? The AAC file is a newer format and it will still play on many devices, on most computers, relatively new IPODs, Most modern mobile phones and many other MP3 players.

AAC file streams are mostly put into m4a containers, but can also be .m4b, .m4p, .m4v, .m4r, .3gp, .mp4, .aac. (OF YOUR CHOICE, the most common is m4a, but some older mobiles use 3GP)

So, let us first try to extract the AAC stream without re-encoding (next step we will re-encode to MP3 for those who want an MP3)

ffmpeg.exe -i tutorial.mp4 -acodec copy tutorial.m4a

Now, the device you want to use does not support AAC files, so what we can do is ask ffmpeg to convert it to MP3 for us

ffmpeg -i tutorial.mp4 tutorial.mp

—————————————————–

The Lowdown

1- Find out what streams exist

ffmpeg -i tutorial.mp4

2- Copy MP3 stream without re-encoding

ffmpeg.exe -i tutorial.mp4 -acodec copy tutorial.mp3

3- Copy AAC stream without re-encoding

ffmpeg.exe -i tutorial.mp4 -acodec copy tutorial.m4a

4- Re-encode audio to MP3 file fromat

ffmpeg -i tutorial.mp4 tutorial.mp3

 

To encode any file into a DVD compatible file (Best when used with DVD players that have a USB input or with USB TV)

ffmpeg -i 9.mp4 -threads 2 -filter:v "scale='if(gt(a,720/480),720,-1)':'if(gt(a,720/480),-1,480)',pad=w=720:h=480:x=(ow-iw)/2:y=(oh-ih)/2" -target pal-dvd 9.mpg

Sometimes, you might want to replace pal-dvd with ntsc-dvd