Beginners guide to Bash, Linux commands and Transcoding. Learn Linux and Bash while transcoding your entire video collection to HEVC (x265) recursively.
What you’ll need:
- A directory full of Videos
- A Linux Machine – I am using Manjaro
- Ffmpeg with your hardware transcode compiled. I am using VA-Api with an AMD graphics card which can also be used with intel graphics. This isn’t a guide on how to compile ffmpeg with hardware transcoding enabled but you can either set up a software transcode, have the same set up as mine, or stay tuned for a future guide!
- Screen to run the script in the background
Getting what you need:
You can install what you need in Manjaro with:
pamac install ffmpeg-amd-full screen
Or Ubunutu
apt-get install ffmpeg screen
Preparing Script File
Start a new empty file with the touch command
touch ~/convert-video
change permissions of this file so that it can be executed by the owner (you) and your primary group. I’ll go a little more in-depth about permissions. You do this with the change mode command
chmod 774 ~/convert-video
The first 7 means read/write/execute permissions for the owner.
The second 7 means read/write/execute permission for the file’s group. This will be your primary group when you touched the file. You can see your primary group by using
id $USER
Mine shows gid=984(users) which means my primary group is users.
The 4 means everyone else only has read capability on this file.
To verify permissions are set correctly:
ls -l ~/convert-video
Now open with a console text editor:
nano ~/convert-video
Start Scripting!
- First line we hash bang this to be a bash script
#!/bin/bash - Next we want to check to make sure the user designates the folder that all of our videos are located. We do this with an if-statement.
if [ -z $1 ];then echo Give target directory; exit 0;fiThis statement checks if the user put in anything as an argument when executing the script. If the user enters~/convert-video /videofoldereverything is good and we continue. If they just enter~/convert-videoThe script echos a warning message then exits with a code 0. Code 0 is a non-error exit. - Next line we use the find command. We will search for all video extensions that do not have a HEVC added on by this script. Later in the script, we will add this to the file when transcoded so we can stop the script and resume it without transcoding the same videos. There are better ways of doing this (like using ffprobe to check the video format). I’m doing it this way to make the script simple to understand and fast.
find "$1" -depth \( -iname "*.mkv" -o -iname "*.mp4" -o -iname "*.mpg" -o -iname "*.mov" -o -iname "*.avi" -o -iname "*.iso" -o -iname "*.mpeg" \) -a -not -iname "*HEVC.mkv" | while read file ; doThe find command searches the folder the user inputted, checks all sub-folders with -depth and looks for all entered video extensions. -iname is case insensitive, -o means ‘or’, -a -not means ‘and not’ and we pipe ‘|’ that the rest of the code executes while going through our results. - We now create three variables based on a result from the find
directory=$(dirname "$file")
oldfilename=$(basename "$file")
newfilename=$(basename "${file%.*}")
directory is the path of the file. Because we are converting all sub-folders, this could be different from file to file. oldfilename is the full name of the movie with its old extension, i.e. movie.avi newfilename is the file name with the extension removed. This would actually change movie.avi to movie, as we don’t want .avi to be part of the new filename
- Next line we do the conversion with ffmpeg ` nice -n 15 ffmpeg -threads 4 -i "$directory/$oldfilename" -vaapi_device /dev/dri/renderD128 -vcodec hevc_vaapi -vf format='nv12-f matroska "$directory/$newfilename - HEVC.mkv"