@@ -14,7 +14,7 @@ The strengths of the script include:
1414either using the current monitor resolution or setting a custom resolution.
15152. Frame rate configuration: The script allows the user to set the screen capture frame rate, with a default value of 15 fps.
16163. Video codec configuration: The script allows the user to choose between different video codecs, including libx264, libx265,
17- libvpx-vp9, mpeg4, mpeg2video, and libaom-av1 .
17+ libvpx-vp9, mpeg4, mpeg2video, and libsvtav1 .
18184. Audio sampling rate configuration: The script allows the user to set the audio sampling rate for the screen capture,
1919with a default value of 22050 Hz.
20205. Muxing support: The script supports muxing functionality, which allows the user to define the maximum muxing queue size.
@@ -30,40 +30,62 @@ DOCUMENTATION
3030# Define a signal handler to capture SIGINT (Ctrl+C)
3131trap ' kill $(jobs -p)' SIGINT # SIGTERM #SIGHUP #SIGINT #SIGQUIT #SIGABRT #SIGKILL #SIGALRM #SIGTERM
3232
33+ # Function to detect Wayland session
34+ function is_wayland {
35+ [[ " ${XDG_SESSION_TYPE,,} " == " wayland" ]] || [[ -n " $WAYLAND_DISPLAY " ]]
36+ }
37+
3338# Função de ajuda
3439function show_help {
3540 cat << EOF
3641Usage: ${0##*/ } [args] -o video.ext
3742Options:
38- -mon, -monitor <resolution> Set monitor resolution (default: current)
39- -vf, -video_scale <scale> Set video scale (e.g., 1920x1080)
40- -fr, -framerate <fps> Set video framerate (default: 15)
41- -ar, -audio_rate <rate> Set audio sampling rate (default: 22050)
42- -muxing, -muxing_enabled <on/off> Enable or disable video muxing (default: off)
43- -max_muxing <value> Set maximum muxing queue size (default: 9999)
44- -vc, -video_codec <codec> Set video codec (default: libx264)
45- -list, -codec_list List available video codecs
46- -o <output_file> Set output file path and name
43+ -mon, -monitor <resolution> Set monitor resolution (default: current)
44+ -vf, -video_scale <scale> Set video scale (e.g., 1920x1080)
45+ -fr, -framerate <fps> Set video framerate (default: 15)
46+ -ar, -audio_rate <rate> Set audio sampling rate (default: 22050)
47+ -muxing, -muxing_enabled <on/off> Enable or disable video muxing (default: off)
48+ -max_muxing <value> Set maximum muxing queue size (default: 9999)
49+ -vc, -video_codec <codec> Set video codec (default: libx264)
50+ -list, -codec_list List available video codecs
51+ -o <output_file> Set output file path and name (optional)
4752EOF
4853}
4954
50-
5155function resolution_current_monitor {
5256 xrandr --current | grep ' *' | uniq | awk ' {print $1}'
5357}
5458
5559function codecs_list {
5660
5761 cat << 'EOF '
58- libx264 (H.264 codec, MP4 or MKV format)
59- libx265 (H.265 codec, MP4 or MKV format)
62+ libx264 (H.264 codec, MP4 or MKV format) - Default
63+ libx265 (H.265/HEVC codec, MP4 or MKV format)
64+ libsvtav1 (AV1 codec, MP4 or MKV format) - Fast AV1 encoding
6065libvpx-vp9 (VP9 codec, WebM format)
6166mpeg4 (MPEG-4 codec, MP4 format)
6267mpeg2video (MPEG-2 codec, MPG format)
63- libaom-av1 (AV1 codec, MKV format)
68+ hevc_nvenc (NVIDIA HEVC hardware encoding)
69+ av1_nvenc (NVIDIA AV1 hardware encoding)
6470EOF
6571}
6672
73+ # Function to get default audio source for Wayland
74+ function get_wayland_audio_source {
75+ LANG=en pactl list sources | awk ' /Name:/ {print $2}' | head -n1 | tail -n1
76+ }
77+
78+ # Function to check if a command exists
79+ function command_exists {
80+ command -v " $1 " > /dev/null 2>&1
81+ }
82+
83+ # Function to check if FFmpeg has specific codec support
84+ function ffmpeg_has_codec {
85+ ffmpeg -hide_banner -encoders 2> /dev/null | grep -i " $1 " > /dev/null 2>&1
86+ }
87+
88+ # Default variables
6789mon=${mon:- $(resolution_current_monitor)}
6890framerate=${framerate:- 15}
6991muxing=${muxing:- 9999}
@@ -72,48 +94,45 @@ arate=${arate:-44100}
7294codec=${codec:- " libx264" }
7395default_folder=" ${HOME} /Videos/Capture"
7496
75- [[ ! -d " $default_folder " ]] && mkdir -p " $default_folder "
76- output_file=${output_file:- " ${default_folder} /Screen_$( date +' %Y-%m-%d_%H:%M:%S' ) .mp4" }
77-
7897# Parse dos argumentos
7998while [[ $# -gt 0 ]]; do
8099 key=" $1 "
81100
82101 case $key in
83- -mon| -monitor)
102+ " -mon" | " -monitor" )
84103 mon=" $2 "
85104 shift 2
86105 ;;
87- -vf| -video_scale)
106+ " -vf" | " -video_scale" )
88107 vf_scale=" ${2// x/: } "
89108 shift 2
90109 ;;
91- -fr| -framerate)
110+ " -fr" | " -framerate" )
92111 framerate=" $2 "
93112 shift 2
94113 ;;
95- -ar| -audio_rate)
114+ " -ar" | " -audio_rate" )
96115 arate=" $2 "
97116 shift 2
98117 ;;
99- -muxing| -muxing_enabled)
118+ " -muxing" | " -muxing_enabled" )
100119 if_muxing=" $2 "
101120 shift 2
102121 ;;
103- -max_muxing)
122+ " -max_muxing" )
104123 muxing=" $2 "
105124 shift 2
106125 ;;
107- -vc| -video_codec)
126+ " -vc" | " -video_codec" )
108127 codec=" $2 "
109128 shift 2
110129 ;;
111- -list| -codec_list)
130+ " -list" | " -codec_list" )
112131 codecs_list
113132 shift
114133 exit 0
115134 ;;
116- -o )
135+ " -o " | " --output " )
117136 output_file=" $2 "
118137 shift 2
119138 ;;
@@ -124,6 +143,108 @@ while [[ $# -gt 0 ]]; do
124143 esac
125144done
126145
146+ # Create default folder if it doesn't exist
147+ [[ ! -d " $default_folder " ]] && mkdir -p " $default_folder "
148+
149+ # Set output file if not specified by user
150+ output_file=${output_file:- " ${default_folder} /Screen_$( date +' %Y-%m-%d_%H:%M:%S' ) .mp4" }
151+
152+ # Check if Wayland is being used
153+ if is_wayland; then
154+ # Check if wf-recorder is already running
155+ wf_rec=$( pidof wf-recorder)
156+
157+ if [[ -z " ${wf_rec} " ]]; then
158+ echo " Detected Wayland session. Using wf-recorder..."
159+
160+ # Check if wf-recorder is installed
161+ if ! command_exists wf-recorder; then
162+ echo " Error: wf-recorder is not installed."
163+ echo " Please install wf-recorder to use this script on Wayland."
164+ exit 1
165+ fi
166+
167+ # Determine audio source
168+ audio_source=$( get_wayland_audio_source)
169+
170+ # Determine codec based on file extension for wf-recorder
171+ filename=$( basename " $output_file " )
172+ extension=" ${filename##* .} "
173+
174+ # Default codec for wf-recorder
175+ wf_codec=" libx265"
176+
177+ # Map codecs for wf-recorder compatibility
178+ case " $codec " in
179+ libx265|hevc_nvenc)
180+ wf_codec=" libx265"
181+ ;;
182+ libsvtav1|av1_nvenc)
183+ wf_codec=" av1"
184+ ;;
185+ libvpx-vp9)
186+ wf_codec=" vp9"
187+ ;;
188+ esac
189+
190+ # Handle scale option if provided
191+ scale_option=" "
192+ if [[ -n " $vf_scale " ]]; then
193+ # Convert scale format from ffmpeg to wf-recorder format
194+ wf_scale=" ${vf_scale//:/ x} "
195+ scale_option=" -g ${wf_scale} "
196+ fi
197+
198+ # Build wf-recorder command
199+ echo " Recording to: $output_file "
200+ echo " Using codec: $wf_codec "
201+ echo " Audio source: $audio_source "
202+
203+ # Execute wf-recorder with appropriate options
204+ wf-recorder -c " $wf_codec " --audio=" $audio_source " $scale_option -f " $output_file "
205+
206+ exit 0
207+ else
208+ echo " wf-recorder is already running (PID: ${wf_rec} )"
209+ exit 1
210+ fi
211+ fi
212+
213+ # Original X11/FFmpeg code
214+ echo " Using X11 session with FFmpeg..."
215+
216+ # Check if ffmpeg is installed
217+ if ! command_exists ffmpeg; then
218+ echo " Error: ffmpeg is not installed."
219+ echo " Please install ffmpeg to use this script on X11."
220+ exit 1
221+ fi
222+
223+ # Check for specific codec support
224+ case " $codec " in
225+ " hevc_nvenc" |" av1_nvenc" )
226+ if ! ffmpeg_has_codec " $codec " ; then
227+ echo " Error: Codec '$codec ' is not available in your FFmpeg installation."
228+ echo " Make sure you have NVIDIA drivers and FFmpeg with NVENC support."
229+ exit 1
230+ fi
231+ ;;
232+ " libsvtav1" )
233+ if ! ffmpeg_has_codec " libsvtav1" ; then
234+ echo " Error: Codec 'libsvtav1' is not available in your FFmpeg installation."
235+ echo " You may need to compile FFmpeg with --enable-libsvtav1 or install a version with SVT-AV1 support."
236+ exit 1
237+ fi
238+ ;;
239+ " libx265" )
240+ if ! ffmpeg_has_codec " libx265" ; then
241+ echo " Error: Codec 'libx265' is not available in your FFmpeg installation."
242+ echo " You may need to install libx265 development packages and recompile FFmpeg."
243+ exit 1
244+ fi
245+ ;;
246+ esac
247+
127248# https://stackoverflow.com/questions/39887869/ffmpeg-whatsapp-video-format-not-supported
128249if [[ " $if_muxing " == " on" ]]; then
129250
@@ -141,6 +262,38 @@ elif [[ "$codec" == "libx264" ]]; then
141262 ffmpeg -video_size " $mon " -framerate " $framerate " -f x11grab -re -i " ${DISPLAY} " -f pulse -ac 2 -i default -ar " $arate " -c:v libx264 -profile:v baseline -level 3.0 -pix_fmt yuv420p " $output_file "
142263 fi
143264
265+ elif [[ " $codec " == " libx265" ]]; then
266+ # Optimized parameters for libx265 (HEVC)
267+ if [[ " $vf_scale " ]]; then
268+ ffmpeg -video_size " $mon " -framerate " $framerate " -f x11grab -re -i " ${DISPLAY} " -f pulse -ac 2 -i default -ar " $arate " -c:v libx265 -preset ultrafast -crf 28 -x265-params log-level=error -pix_fmt yuv420p -vf scale=" $vf_scale " " $output_file "
269+ else
270+ ffmpeg -video_size " $mon " -framerate " $framerate " -f x11grab -re -i " ${DISPLAY} " -f pulse -ac 2 -i default -ar " $arate " -c:v libx265 -preset ultrafast -crf 28 -x265-params log-level=error -pix_fmt yuv420p " $output_file "
271+ fi
272+
273+ elif [[ " $codec " == " libsvtav1" ]]; then
274+ # Optimized parameters for libsvtav1 (fast AV1 encoding)
275+ if [[ " $vf_scale " ]]; then
276+ ffmpeg -video_size " $mon " -framerate " $framerate " -f x11grab -re -i " ${DISPLAY} " -f pulse -ac 2 -i default -ar " $arate " -c:v libsvtav1 -preset 8 -crf 35 -pix_fmt yuv420p -svtav1-params log-level=error -vf scale=" $vf_scale " " $output_file "
277+ else
278+ ffmpeg -video_size " $mon " -framerate " $framerate " -f x11grab -re -i " ${DISPLAY} " -f pulse -ac 2 -i default -ar " $arate " -c:v libsvtav1 -preset 8 -crf 35 -pix_fmt yuv420p -svtav1-params log-level=error " $output_file "
279+ fi
280+
281+ elif [[ " $codec " == " hevc_nvenc" ]]; then
282+ # Optimized parameters for NVIDIA HEVC hardware encoding
283+ if [[ " $vf_scale " ]]; then
284+ ffmpeg -video_size " $mon " -framerate " $framerate " -f x11grab -re -i " ${DISPLAY} " -f pulse -ac 2 -i default -ar " $arate " -c:v hevc_nvenc -preset p7 -tune hq -rc vbr -cq 28 -qmin 0 -qmax 51 -b:v 0 -pix_fmt yuv420p -vf scale=" $vf_scale " " $output_file "
285+ else
286+ ffmpeg -video_size " $mon " -framerate " $framerate " -f x11grab -re -i " ${DISPLAY} " -f pulse -ac 2 -i default -ar " $arate " -c:v hevc_nvenc -preset p7 -tune hq -rc vbr -cq 28 -qmin 0 -qmax 51 -b:v 0 -pix_fmt yuv420p " $output_file "
287+ fi
288+
289+ elif [[ " $codec " == " av1_nvenc" ]]; then
290+ # Optimized parameters for NVIDIA AV1 hardware encoding
291+ if [[ " $vf_scale " ]]; then
292+ ffmpeg -video_size " $mon " -framerate " $framerate " -f x11grab -re -i " ${DISPLAY} " -f pulse -ac 2 -i default -ar " $arate " -c:v av1_nvenc -preset p7 -tune hq -rc vbr -cq 32 -qmin 0 -qmax 63 -b:v 0 -pix_fmt yuv420p -vf scale=" $vf_scale " " $output_file "
293+ else
294+ ffmpeg -video_size " $mon " -framerate " $framerate " -f x11grab -re -i " ${DISPLAY} " -f pulse -ac 2 -i default -ar " $arate " -c:v av1_nvenc -preset p7 -tune hq -rc vbr -cq 32 -qmin 0 -qmax 63 -b:v 0 -pix_fmt yuv420p " $output_file "
295+ fi
296+
144297else
145298
146299 if [[ " $vf_scale " ]]; then
0 commit comments