extremen00b
Posts: 3
Joined: Mon Dec 28, 2020 7:11 pm

Raspberry Pi 4 - Converting Videos for Achieving Smaller Sizes

Mon Dec 28, 2020 7:30 pm

Hi Awesome Folks,

New user for Raspberry Pi 4 (and video encoding in general) here.

I have quite a number of video files on local storage that I would like to convert to a smaller size (hopefully without losing too much quality).
I plan to play these primarily through VLC Media Player on the Raspberry Pi itself (connected to living room TV).

In the set of videos
  • Most videos are 720p
  • A select number of videos are 1080p, and some are 480p or lower

Some searching leads me to believe H265 is a good codec to consider.

As a sample, i tried running

Code: Select all

ffmpeg -hwaccel rpi -i input_file1.mp4 -c:v libx265 -c:a copy output_file1.mkv
The command took an extremely long time to run (~10 min to encode like 5sec of video)

Would really appreciate any tips on
  1. Codecs or other suggestions? (Am a beginner here, so please call me out if my process above is really bad)
  2. Improving the encoding speed if possible (I do not understand hwaccel and dependencies well)

extremen00b
Posts: 3
Joined: Mon Dec 28, 2020 7:11 pm

Re: Raspberry Pi 4 - Converting Videos for Achieving Smaller Sizes

Wed Jan 13, 2021 10:07 am

Hi Awesome Folks,

Wish you a very Happy New Year !

Gently bumping up this post.


Would love your inputs on codecs / methods to achieve better sizes.

LTolledo
Posts: 4498
Joined: Sat Mar 17, 2018 7:29 am
Location: Anime Heartland

Re: Raspberry Pi 4 - Converting Videos for Achieving Smaller Sizes

Wed Jan 13, 2021 9:03 pm

have you tried OpenShot Video Editor?
am using it on my this RPi4B-4G and on a RPi4B-8G to edit (splice, join and convert) some videos that I need to....
some screen shots below:
OpenShot Video Editor export video format1.jpg
OpenShot Video Editor export video format1.jpg (47.87 KiB) Viewed 136 times
OpenShot Video Editor export video format2.jpg
OpenShot Video Editor export video format2.jpg (60.97 KiB) Viewed 136 times

H265 is a good codec, but I cannot recommend it if the playback device is on a RPi...
"Don't come to me with 'issues' for I don't know how to deal with those
Come to me with 'problems' and I'll help you find solutions"

Some people be like:
"Help me! Am drowning! But dont you dare touch me nor come near me!"

MacUser2525
Posts: 157
Joined: Thu Dec 31, 2020 5:34 am
Location: NS, Canada

Re: Raspberry Pi 4 - Converting Videos for Achieving Smaller Sizes

Wed Jan 13, 2021 10:54 pm

extremen00b wrote:
Mon Dec 28, 2020 7:30 pm
Hi Awesome Folks,

New user for Raspberry Pi 4 (and video encoding in general) here.

I have quite a number of video files on local storage that I would like to convert to a smaller size (hopefully without losing too much quality).
I plan to play these primarily through VLC Media Player on the Raspberry Pi itself (connected to living room TV).

In the set of videos
  • Most videos are 720p
  • A select number of videos are 1080p, and some are 480p or lower

Some searching leads me to believe H265 is a good codec to consider.


As a sample, i tried running

Code: Select all

ffmpeg -hwaccel rpi -i input_file1.mp4 -c:v libx265 -c:a copy output_file1.mkv
The command took an extremely long time to run (~10 min to encode like 5sec of video)

Would really appreciate any tips on
  1. Codecs or other suggestions? (Am a beginner here, so please call me out if my process above is really bad)
  2. Improving the encoding speed if possible (I do not understand hwaccel and dependencies well)

You can give this a try I cobbled together for myself When Handbrake was giving me trouble. I have commented it well I think you can see how to use the various parameters of ffmpeg yourself and perhaps adapt to your needs.

Code: Select all

MacUser2525:~$ cat Bin/x265_convert.sh 
#!/bin/bash

# Echo options to select
echo "Select Bitrate Sound Desied  1) SD 2ch  2) SD 5.1ch  3) HD 2ch  4) HD 5.1ch 5) Two Pass HD stereo 6) Two Pass HD 5.1ch 7) Two pass concert 8) Quit "

# Read the input
read n

# Case stetement to process files according to input selected.
case $n in

	1) 

		# SD 600k video stereo audio
		# Get directory script is running in
		DIR="$(dirname "$PWD")/$(basename "$PWD")"

		# Change to directory and make new one if not there for processed files so always working on copy.

		cd "$DIR"
		if [ ! -d "$DIR/SDstereo" ]; then
			mkdir "$DIR/SDstereo"
#			touch "$DIR/SDstereo/SDstereo.log"
		fi
		
		for i in $(find "$PWD" -type f | grep '.mkv\|.avi\|.mp4\|.m4v' ); do

			# Name of file and extension to use in output file for further prosessing
			# http://mindspill.net/computing/linux-notes/working-with-filenames-in-bash/
			# https://stackoverflow.com/questions/965053/extract-filename-and-extension-in-bash
			NAME=$(basename "$i")
			EXTENSION="${NAME##*.}"
			NAMENOEXT="${NAME%.*}"
						
			# Use ffmpeg to convert to 600k video stereo sound
			ffmpeg -i "$i" -c:v libx265 -preset ultrafast -b:v 600k -ac 2 -ar 48000 -c:a aac -strict -2 -b:a 128k -sn  "SDstereo/$NAME.mkv"
	
			# Use mkvmerge to get rid of many English ffmpeg leaves in the Metadata
			mkvmerge --no-subtitles "SDstereo/$NAME.mkv" -o "SDstereo/$NAMENOEXT.mkv"
	
			# remove no longer needed newly created by ffmpeg file 
			rm "SDstereo/$NAME.mkv"
			
			# Delete title (movie name) if any
			mkvpropedit "SDstereo/$NAMENOEXT.mkv" -d title
			
			
		done
		
	;;
	
	2) 

		# SD 600k video 5.1 audio
		# Get directory script is running in
		DIR="$(dirname "$PWD")/$(basename "$PWD")"

		# Change to directory and make new one if not there for processed files so always working on copy.

		cd "$DIR"
		if [ ! -d "$DIR/SDsurround" ]; then
			mkdir "$DIR/SDsurround"
#			touch "$DIR/SDsurround/SDsurround.log"
		fi
		
		for i in $(find "$PWD" -type f | grep '.mkv\|.avi\|.mp4\|.m4v' ); do

			# Name of file and extension to use in output file for further prosessing
			# http://mindspill.net/computing/linux-notes/working-with-filenames-in-bash/
			# https://stackoverflow.com/questions/965053/extract-filename-and-extension-in-bash
			NAME=$(basename "$i")
			EXTENSION="${NAME##*.}"
			NAMENOEXT="${NAME%.*}"
						
			# Use ffmpeg to convert to 1000k video 5.1 sound
			ffmpeg -i "$i" -c:v libx265 -preset ultrafast -b:v 600k -ac 6 -ar 48000 -c:a aac -strict -2 -b:a 384k -sn  "SDsurround/$NAME.mkv"
	
			# Use mkvmerge to get rid of many English ffmpeg leaves in the Metadata
			mkvmerge --no-subtitles "SDsurround/$NAME.mkv" -o "SDsurround/$NAMENOEXT.mkv"
	
			# remove no longer needed newly created by ffmpeg file 
			rm "SDsurround/$NAME.mkv"
			
			# Delete title (movie name) if any
			mkvpropedit "SDsurround/$NAMENOEXT.mkv" -d title
			
			
		done
		
	;;
	
	3) 
	
		# HD 1000k video stereo audio
		# Get directory script is running in
		DIR="$(dirname "$PWD")/$(basename "$PWD")"

		# Change to directory and make new one if not there for processed files so always working on copy.

		cd "$DIR"
		if [ ! -d "$DIR/HDstereo" ]; then
			mkdir "$DIR/HDstereo"
#			touch "$DIR/HDstereo/HDstereo.log"
		fi
		
		for i in $(find "$PWD" -type f | grep '.mkv\|.avi\|.mp4\|.m4v' ); do

			# Name of file and extension to use in output file for further prosessing
			# http://mindspill.net/computing/linux-notes/working-with-filenames-in-bash/
			# https://stackoverflow.com/questions/965053/extract-filename-and-extension-in-bash
			NAME=$(basename "$i")
			EXTENSION="${NAME##*.}"
			NAMENOEXT="${NAME%.*}"
						
			# Use ffmpeg to convert to 1000k video stereo sound
			ffmpeg -i "$i" -c:v libx265 -preset ultrafast -b:v 1000k -ac 2 -ar 48000 -c:a aac -strict -2 -b:a 128k -sn  "HDstereo/$NAME.mkv"
	
			# Use mkvmerge to get rid of many English ffmpeg leaves in the Metadata
			mkvmerge --no-subtitles "HDstereo/$NAME.mkv" -o "HDstereo/$NAMENOEXT.mkv"
	
			# remove no longer needed newly created by ffmpeg file 
			rm "HDstereo/$NAME.mkv"
			
			# Delete title (movie name) if any
			mkvpropedit "HDstereo/$NAMENOEXT.mkv" -d title
			
			
		done
		
	;;
	
	4) 
	
		# HD 1000k video 5.1 audio
		# Get directory script is running in
		DIR="$(dirname "$PWD")/$(basename "$PWD")"

		# Change to directory and make new one if not there for processed files so always working on copy.

		cd "$DIR"
		if [ ! -d "$DIR/HDsurround" ]; then
			mkdir "$DIR/HDsurround"
#			touch "$DIR/HDsurround/HDsurround.log"
		fi
		
		for i in $(find "$PWD" -type f | grep '.mkv\|.avi\|.mp4\|.m4v' ); do

			# Name of file and extension to use in output file for further prosessing
			# http://mindspill.net/computing/linux-notes/working-with-filenames-in-bash/
			# https://stackoverflow.com/questions/965053/extract-filename-and-extension-in-bash
			NAME=$(basename "$i")
			EXTENSION="${NAME##*.}"
			NAMENOEXT="${NAME%.*}"
						
			# Use ffmpeg to convert to 1000k video 5.1 sound
			ffmpeg -i "$i" -c:v libx265 -preset ultrafast -b:v 1000k -ac 6 -ar 48000 -c:a aac -strict -2 -b:a 384k -sn  "HDsurround/$NAME.mkv"
	
			# Use mkvmerge to get rid of many English ffmpeg leaves in the Metadata
			mkvmerge --no-subtitles "HDsurround/$NAME.mkv" -o "HDsurround/$NAMENOEXT.mkv"
	
			# remove no longer needed newly created by ffmpeg file 
			rm "HDsurround/$NAME.mkv"
			
			# Delete title (movie name) if any
			mkvpropedit "HDsurround/$NAMENOEXT.mkv" -d title
			
			
		done
		
	;;
	
	5)
	
			# HD 1000k video stereo sound two pass
		# Get directory script is running in
		DIR="$(dirname "$PWD")/$(basename "$PWD")"

		# Change to directory and make new one if not there for processed files so always working on copy.

		cd "$DIR"
		if [ ! -d "$DIR/HDsurround" ]; then
			mkdir "$DIR/HDsurround"
#			touch "$DIR/HDsurround/HDsurround.log"
		fi
		
		for i in $(find "$PWD" -type f | grep '.mkv\|.avi\|.mp4\|.m4v' ); do

			# Name of file and extension to use in output file for further prosessing
			# http://mindspill.net/computing/linux-notes/working-with-filenames-in-bash/
			# https://stackoverflow.com/questions/965053/extract-filename-and-extension-in-bash
			NAME=$(basename "$i")
			EXTENSION="${NAME##*.}"
			NAMENOEXT="${NAME%.*}"
						
			# Use ffmpeg to convert to 1000k video stereo sound two pass
			ffmpeg -y -i $i -c:v libx265 -preset ultrafast -b:v 1000k -x265-params pass=1 -an -f mp4 /dev/null && ffmpeg -i $i -c:v libx265 -preset ultrafast -b:v 1000k -x265-params pass=2 -ac 2 -ar 48000 -c:a aac -strict -2 -b:a 128k -sn "HDsurround/$NAME.mp4"
	
			# Use mkvmerge to get rid of many English ffmpeg leaves in the Metadata
			mkvmerge --no-subtitles "HDsurround/$NAME.mp4" -o "HDsurround/$NAMENOEXT.mkv"
	
			# remove no longer needed newly created by ffmpeg file and leftover temp files
			rm "HDsurround/$NAME.mp4"
			rm x265*
			
			# Delete title (movie name) if any
			mkvpropedit "HDsurround/$NAMENOEXT.mkv" -d title
			
			
		done
	
	;;
	
	6)
	
		# HD 1000k video 5.1 audio two pass
		# Get directory script is running in
		DIR="$(dirname "$PWD")/$(basename "$PWD")"

		# Change to directory and make new one if not there for processed files so always working on copy.

		cd "$DIR"
		if [ ! -d "$DIR/HDsurround" ]; then
			mkdir "$DIR/HDsurround"
#			touch "$DIR/HDsurround/HDsurround.log"
		fi
		
		for i in $(find "$PWD" -type f | grep '.mkv\|.avi\|.mp4\|.m4v' ); do

			# Name of file and extension to use in output file for further prosessing
			# http://mindspill.net/computing/linux-notes/working-with-filenames-in-bash/
			# https://stackoverflow.com/questions/965053/extract-filename-and-extension-in-bash
			NAME=$(basename "$i")
			EXTENSION="${NAME##*.}"
			NAMENOEXT="${NAME%.*}"
						
			# Use ffmpeg to convert to 1000k video 5.1 sound two pass
			ffmpeg -y -i $i -c:v libx265 -preset ultrafast -b:v 1000k -x265-params pass=1 -an -f mp4 /dev/null && ffmpeg -i $i -c:v libx265 -preset ultrafast -b:v 1000k -x265-params pass=2 -ac 6 -ar 48000 -c:a aac -strict -2 -b:a 384k -sn "HDsurround/$NAME.mp4"
	
			# Use mkvmerge to get rid of many English ffmpeg leaves in the Metadata
			mkvmerge --no-subtitles "HDsurround/$NAME.mp4" -o "HDsurround/$NAMENOEXT.mkv"
	
			# remove no longer needed newly created by ffmpeg file and leftover temp files
			rm "HDsurround/$NAME.mp4"
			rm x265*
			
			# Delete title (movie name) if any
			mkvpropedit "HDsurround/$NAMENOEXT.mkv" -d title
			
			
		done
		
	;;
	
	7)
	
		# HD 2500k video 5.1 audio two pass
		# Get directory script is running in
		DIR="$(dirname "$PWD")/$(basename "$PWD")"

		# Change to directory and make new one if not there for processed files so always working on copy.

		cd "$DIR"
		if [ ! -d "$DIR/HDsurround" ]; then
			mkdir "$DIR/HDsurround"
#			touch "$DIR/HDsurround/HDsurround.log"
		fi
		
		for i in $(find "$PWD" -type f | grep '.mkv\|.avi\|.mp4\|.m4v' ); do

			# Name of file and extension to use in output file for further prosessing
			# http://mindspill.net/computing/linux-notes/working-with-filenames-in-bash/
			# https://stackoverflow.com/questions/965053/extract-filename-and-extension-in-bash
			NAME=$(basename "$i")
			EXTENSION="${NAME##*.}"
			NAMENOEXT="${NAME%.*}"
						
			# Use ffmpeg to convert to 2500k video 5.1 sound two pass
			ffmpeg -y -i $i -c:v libx265 -preset ultrafast -b:v 2500k -x265-params pass=1 -an -f mp4 /dev/null && ffmpeg -i $i -c:v libx265 -preset ultrafast -b:v 2500k -x265-params pass=2 -ac 6 -ar 48000 -c:a aac -strict -2 -b:a 384k -sn "HDsurround/$NAME.mp4"
	
			# Use mkvmerge to get rid of many English ffmpeg leaves in the Metadata
			mkvmerge --no-subtitles "HDsurround/$NAME.mp4" -o "HDsurround/$NAMENOEXT.mkv"
	
			# remove no longer needed newly created by ffmpeg file and leftover temp files
			rm "HDsurround/$NAME.mp4"
			rm x265*
			
			# Delete title (movie name) if any
			mkvpropedit "HDsurround/$NAMENOEXT.mkv" -d title
			
			
		done
	
	;;
	
	8)
	
		exit 0
	
# End case statement done processing files
esac
You need mkvtoolnix installed and to know what you want from your files in the directory you run it from. I am not sure if it handles files with spaces or special characters I never use them. For example you have all high definition 5.1 sound, that is the option applied to all files in the directory. You end up with the converted file in a sub directory as I do not like messing with originals and having no option to go back if things do not turn out properly. I do think this is probably going to take longer than you want on a pi. I am a good ten minutes into an encode of a 1080p 5.1 surround sound file. My pi is running at 70C with a load of over 5.

Code: Select all

    Stream #0:1(eng): Audio: aac (LC) ([255][0][0][0] / 0x00FF), 48000 Hz, 5.1, fltp, 384 kb/s (default)
    Metadata:
      title           : 
      BPS-eng         : 640007
      DURATION-eng    : 00:47:40.480000000
      NUMBER_OF_FRAMES-eng: 89391
      NUMBER_OF_BYTES-eng: 228840960
      _STATISTICS_WRITING_APP-eng: mkvpropedit v28.2.0 ('The Awakening') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2021-01-13 02:52:42
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
      encoder         : Lavc58.35.100 aac
frame= 1246 fps=2.0 q=-0.0 size=    8305kB time=00:00:52.05 bitrate=1307.0kbits/s speed=0.084x     
There is where I gave it up at about that ten minutes into the encode about a minute of the video was done. Here it is on my main machine a i5 9600K 6 core machine with 32gb of ram it did thirty-three in ten minutes.

Code: Select all

    BPS-eng         : 640007
      DURATION-eng    : 00:47:40.480000000
      NUMBER_OF_FRAMES-eng: 89391
      NUMBER_OF_BYTES-eng: 228840960
      _STATISTICS_WRITING_APP-eng: mkvpropedit v28.2.0 ('The Awakening') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2021-01-13 02:52:42
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
      encoder         : Lavc58.54.100 aac
frame=47605 fps= 82 q=-0.0 size=  337860kB time=00:33:05.70 bitrate=1393.8kbits/s speed=3.44x    

Edit: Oh the output is h265 video aac audio in an .mkv container for the files produced.

extremen00b
Posts: 3
Joined: Mon Dec 28, 2020 7:11 pm

Re: Raspberry Pi 4 - Converting Videos for Achieving Smaller Sizes

Wed Jan 20, 2021 11:19 am

Thank you @MacUser2525 and @LTolledo for your inputs


@LTolledo - would it be possible to elaborate on why you would not recommend HEVC for playback?
I find existing HEVC files (1080p) work pretty well on my RPi4


@MacUser2525 - I tried the following based on your code

Code: Select all

ffmpeg -i <input_file> -c:v libx265 -preset ultrafast -b:v 1000k -ac 2 -ar 48000 -c:a aac -strict -2 -b:a 128k -sn  <output_file>
While this runs relatively fast (I am able to get speeds of 1x / 1-min-runtime-for-1-min-of-video on my 4GB Rpi 4), the CPU temperature goes up significantly.
I may take a leaf out of your book to use a different device for encoding long videos


Thanks again to the both of you for your help !

Return to “Graphics, sound and multimedia”