Skip to content

Commit 0b4d02f

Browse files
committed
Optimized and rewritten some code, added a bunch
bunch of fallbacks in case stuff fails
1 parent d943f34 commit 0b4d02f

File tree

1 file changed

+166
-17
lines changed

1 file changed

+166
-17
lines changed

main.sh

Lines changed: 166 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,201 @@
11
#!/bin/bash
22

3-
echo Welcome to my simple ffmpeg GPU accelerator thingy
3+
# Colour formatting stuff
4+
RED='\033[0;31m'
5+
GREEN='\033[0;32m'
6+
BLUE='\033[0;34m'
7+
NC='\033[0m' # No Color
8+
9+
# Script description
10+
echo Welcome to my ffmpeg GPU accelerator thingy
11+
12+
# This part checks if lshw is installed or not
13+
if command -- lshw >/dev/null 2>&1; then
14+
echo -e "${GREEN}lshw is installed\n${NC}"
15+
else
16+
echo -e "${RED}lshw not found, please install lshw before running this script.\n${NC}"
17+
exit 1
18+
fi
19+
20+
echo "--------------------"
21+
22+
# Lists out GPU in a system, ignores errors about the command running in non-sudo mode, then filters out the vendors
23+
listGPU=$( (lshw -C video) 2>/dev/null | awk '$1=="vendor:"{$1=""; print}')
24+
25+
declare -i GPUType
26+
GPUType=0
27+
28+
# Function for detecting intel GPU to avoid duplicated codes
29+
detect_intel () {
30+
# echo -e "${BLUE}Intel${NC} GPU detected"
31+
Intel=true
32+
GPUType+=1
33+
}
34+
35+
# Logic for checking which GPU exists in system
36+
if (grep NVIDIA <<< $listGPU) 1>/dev/null ; then
37+
# echo -e "${GREEN}NVIDIA${NC} GPU detected"
38+
Nvidia=true
39+
GPUType+=5
40+
elif (grep Intel <<< $listGPU) 1>/dev/null ; then
41+
detect_intel
42+
fi
43+
44+
if (grep AMD <<< $listGPU) 1>/dev/null ; then
45+
# echo -e "${RED}AMD${NC} GPU detected"
46+
AMD=true
47+
GPUType+=3
48+
elif (grep Intel <<< $listGPU) 1>/dev/null ; then
49+
detect_intel
50+
else
51+
echo Unknown GPU
52+
fi
53+
54+
case $GPUType in
55+
1)
56+
echo -e "Only ${BLUE}Intel${NC} GPU detected, possibly integrated graphics or Intel Arc"
57+
;;
58+
3)
59+
echo -e "Only ${RED}AMD${NC} GPU detected, probably an AMD-only system."
60+
;;
61+
4)
62+
echo -e "${BLUE}Intel${NC} and ${RED}AMD${NC} detected, probably a system with an Intel processor with iGPU and AMD graphics."
63+
;;
64+
5)
65+
echo -e "Only ${GREEN}Nvidia${NC} GPU detected. Possibly a system with a single dedicated Nvidia graphics."
66+
;;
67+
6)
68+
echo -e "${BLUE}Intel${NC} and ${GREEN}Nvidia${NC} detected, possibly a hybrid system like a laptop."
69+
;;
70+
8)
71+
echo -e "${RED}AMD${NC} and ${GREEN}Nvidia${NC} detected, probably a system with AMD APU and Nvidia GPU."
72+
;;
73+
*)
74+
echo "Unknown system type"
75+
;;
76+
esac
77+
78+
echo -e "--------------------\n"
479

580
read -p 'Please type input name here: ' inputfile
681
read -p 'Please type output name here (without extensions): ' outputfile
782

8-
PS3=$'Which video codec do you want to use?\n'
83+
# Video codec choice
84+
PS3=$'Which video codec do you want to use? (Make sure your hardware supports it!)\n'
985
select vidcodecchoice in h264 hevc
1086
do
1187
case $vidcodecchoice in
1288
h264)
1389
printf "$vidcodecchoice selected\n"
14-
vidcodec=${vidcodecchoice}_vaapi
1590
break
1691
;;
1792
hevc)
1893
printf "$vidcodecchoice selected\n"
19-
vidcodec=${vidcodecchoice}_vaapi
2094
break
2195
;;
2296
*)
23-
echo "Invalid option"
97+
echo $RED "Invalid option" $NC
2498
;;
2599
esac
26100
done
27101

102+
# Video quality choice
28103
read -p 'Please enter your desired video quality (CQP): ' vidqual
29-
eval $(ffprobe -v quiet -select_streams a:0 -of flat=s=_ -show_entries stream=codec_name "$inputfile")
30104

105+
# This part checks whether or not $inputfile has mp3 or aac audio codec already. If it does, then it'll just copy the audio stream over to avoid re-encoding.
106+
eval $(ffprobe -v quiet -select_streams a:0 -of flat=s=_ -show_entries stream=codec_name "$inputfile")
31107
if [[ $streams_stream_0_codec_name == "mp3" || $streams_stream_0_codec_name == "aac" ]]; then
32108
audcodec="copy"
33109
else
34110
read -p 'Please enter your desired audio quality (bitrate): ' audqual
35111
audcodec="aac -b:a $audqual"
36112
fi
37113

114+
# Change resolution choice
38115
printf "Do you want to change resolutions?\n"
39116
read changeres
40117

41-
if [ $changeres == yes ]; then
42-
printf "\n"
43-
read -p "enter the width here: " vidwidth
44-
read -p 'enter the height here: ' vidheight
45-
vidfilter="format=nv12,hwupload,deinterlace_vaapi=rate=field:auto=1,scale_vaapi=w=$vidwidth:h=$vidheight"
46-
elif [ $changeres == no ]; then
47-
vidfilter="format=nv12,hwupload,deinterlace_vaapi=rate=field:auto=1"
48-
else
49-
printf "Unknown parameter"
50-
fi
118+
resChange () {
119+
if [[ $changeres == yes || $changeres == y ]]; then
120+
printf "\n"
121+
read -p "enter the width here: " vidwidth
122+
read -p "enter the height here: " vidheight
123+
vidfilterVAAPI="-vf format=nv12,hwupload,deinterlace_vaapi=rate=field:auto=1,scale_vaapi=w=$vidwidth:h=$vidheight"
124+
vidfilterQSV="-vf format=qsv,hwupload,deinterlace_qsv,scale_qsv=w=$vidwidth:h=$vidheight"
125+
vidfilterCUDA="-vf format=cuda,hwupload,yadif_cuda=deint=interlaced,scale_cuda=w=$vidwidth:h=$vidheight"
126+
elif [[ $changeres == no || $changeres == n ]]; then
127+
vidfilterVAAPI="-vf format=nv12,hwupload,deinterlace_vaapi=rate=field:auto=1"
128+
vidfilterQSV="-vf format=qsv,hwupload,deinterlace_qsv"
129+
vidfilterCUDA="-vf format=cuda,hwupload,yadif_cuda=deint=interlaced"
130+
else
131+
printf "Unknown parameter"
132+
fi
133+
}
134+
135+
# Choose encoder type based on detected GPUs
136+
encType () {
137+
case $GPUType in
138+
1) # Intel GPU
139+
hwEncode="$vidfilterQSV -c:v ${vidcodecchoice}_qsv -global_quality $vidqual"
140+
hwDecode="-hwaccel qsv -hwaccel_output_format qsv -vcodec ${vidcodecchoice}_qsv"
141+
;;
142+
3 | 4) # AMD GPU
143+
hwEncode="$vidfilterVAAPI ${vidcodecchoice}_vaapi -rc_mode CQP -qp $vidqual"
144+
hwDecode="-vaapi_device /dev/dri/renderD128"
145+
;;
146+
5 | 6 | 8) # Nvidia GPU
147+
hwEncode="$vidfilterCUDA -c:v ${vidcodecchoice}_nvenc -cq $vidqual"
148+
hwDecode="-hwaccel cuda -hwaccel_output_format cuda"
149+
;;
150+
*)
151+
echo "Something went wrong!"
152+
exit 1
153+
;;
154+
esac
155+
}
156+
157+
# Final command for running ffmpeg
158+
run_ffmpeg () {
159+
resChange
160+
encType
161+
ffmpeg -hide_banner $hwDecode -i "$inputfile" $hwEncode -fps_mode passthrough -c:a $audcodec "$outputfile.mp4"
162+
}
163+
164+
on_error() {
165+
echo -e "${RED}Exit code: $?${NC}"
166+
if [[ $GPUType == 6 || ! $? == 0 ]] ; then
167+
read -p "Oh no! Nvidia transcoding failed! Do you want to try again with Intel QSV? " tryIntel
168+
case $tryIntel in
169+
[Yy][Ee][Ss] | [Yy] | [Tt][Rr][Uu][Ee] | [Tt])
170+
GPUType=1
171+
echo ""
172+
run_ffmpeg || on_error "Error occured!"
173+
;;
174+
[Nn][Oo] | [Nn] | [Ff][Aa][Ll][Ss][Ee] | [Ff])
175+
echo "Goodbye!"
176+
exit 0
177+
;;
178+
*)
179+
echo "Invalid input: $tryIntel"
180+
;;
181+
esac
182+
elif [[ $GPUType == 8 || ! $? == 0 ]] ; then
183+
read -p "Oh no! Nvidia transcoding failed! Do you want to try again with Intel QSV? " tryAMD
184+
case $tryAMD in
185+
[Yy][Ee][Ss] | [Yy] | [Tt][Rr][Uu][Ee] | [Tt])
186+
GPUType=3
187+
echo ""
188+
run_ffmpeg || on_error "Error occured!"
189+
;;
190+
[Nn][Oo] | [Nn] | [Ff][Aa][Ll][Ss][Ee] | [Ff])
191+
echo "Goodbye!"
192+
exit 0
193+
;;
194+
*)
195+
echo "Invalid input: $tryAMD"
196+
;;
197+
esac
198+
fi
199+
}
51200

52-
ffmpeg -vaapi_device /dev/dri/renderD128 -i "$inputfile" -vf $vidfilter -c:v $vidcodec -fps_mode passthrough -rc_mode CQP -qp $vidqual -c:a $audcodec "$outputfile.mp4"
201+
run_ffmpeg || on_error "Error occured!"

0 commit comments

Comments
 (0)