#!/bin/sh ## ## Nautilus ## SCRIPT: 05_1mp4File_CROP-PERCENTS_ffmpeg-filter-crop_copyAudio_toMP4.sh ## ## PURPOSE: Crop a user-specified area from a '.mp4' movie file using an ## 'ffmpeg' video-filter specification in pixels --- like ## -filter:v "crop=out_w:out_h:x:y" ## --- and make the output movie file an MP4 container ## and copy the audio format. ## ## The user is prompted for margin-percents --- top, right, ## bottom, left. The pixels for out_w, out_h, x, and y ## are calculated by getting the width and height ## in pixels of the input video (using the ## 'mediainfo' command) and applying the percents. ## ## METHOD: Uses 'zenity --entry' to prompt for the percent parameters. ## ## Uses 'ffmpeg' with '-filter:v' and '-c:a copy' parms. ## ## Shows the new, cropped movie file in a movie player. ## ## NOTE on TESTING: ## This script was developed and testing using ffmpeg version ## 3.4.6, released circa 2019. ## ## HOW TO USE: In Gnome-Nautilus or MATE-Caja, select an mp4 movie file. ## Then right-click and choose this script to run (name above). ## ############################################################################### ## Started: 2023dec11 Based on FE Nautilus Script ## 04B_1movieFile_CROP-W-H-X-Y_ffmpeg-filter-crop_toMP4-H264-AAC.sh ## and ## tested using ## ffmpeg version 3.4.6-0ubuntu0.18.04.1 ## Used 'mediainfo' to get the width&height of the input video. ## Changed: 2024jan17 Add a zenity-entry prompt to allow the user to check the ## 4 crop parms calculated from the 4 user-specified percentages. ## Changed: 2024mar18 Improved the use of 'mediainfo' to get width&height. ## Also, in comments, provided 'ffprobe' & 'ffmpeg' examples ## of getting the width&height of the input video. ############################################################################### ## FOR TESTING: (display the executed statements) # set -x ######################################################### ## Check if the ffmpeg executable exists. ######################################################### EXE_FFMPEG="/usr/bin/ffmpeg" if test ! -f "$EXE_FFMPEG" then zenity --info --title "Executable NOT FOUND." \ --no-wrap \ --text "\ The ffmpeg executable $EXE_FFMPEG was not found. Exiting. If the executable is in another location, you can edit this script to change the filename. OR, install the 'ffmpeg' package." exit fi ######################################################### ## Check if the mediainfo executable exists. ######################################################### EXE_MEDIAINFO="/usr/bin/mediainfo" if test ! -f "$EXE_MEDIAINFO" then zenity --info --title "Executable NOT FOUND." \ --no-wrap \ --text "\ The mediainfo executable $EXE_MEDIAINFO was not found. Exiting. If the executable is in another location, you can edit this script to change the filename. OR, install the 'mediainfo' package." exit fi ############################################## ## Get the filename of the selected file. ############################################## FILENAME="$1" # FILENAMES="$@" # FILENAMES="$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" ################################################################## ## Check that the selected file is a '.mp4' file. ## (Assumes just one dot [.] in the filename, at the extension.) ## ################################################################## FILEEXT=`echo "$FILENAME" | cut -d\. -f2` if test "$FILEEXT" != "mp4" then zenity --info --title "Input video suffix is not '.mp4'" \ --no-wrap \ --text "\ The input video $FILENAME suffix is not '.mp4'. Exiting." exit fi ############################################################################# ## Prompt for the 'crop area' of the movie file in percents ## --- top, right, bottom, left. ############################################################################# CROP_PCTS="0 0 30 0" CROP_PCTS=$(zenity --entry \ --title "CROP-MARGINS in %s: top,right,bottom,left" \ --text "\ Enter CROP-MARGIN of the video frame in PERCENTS --- top, right, bottom, left (clock-wise) --- separated by single-spaces. Example: 10 30 20 0 would cut 10% from the top 30% from the right 20% from the bottom 0% from the left Enter null (delete input percents) to exit. " \ --entry-text "$CROP_PCTS") if test "$CROP_PCTS" = "" then exit fi PCT_TOP=`echo "$CROP_PCTS" | cut -d' ' -f1` PCT_RGT=`echo "$CROP_PCTS" | cut -d' ' -f2` PCT_BOT=`echo "$CROP_PCTS" | cut -d' ' -f3` PCT_LFT=`echo "$CROP_PCTS" | cut -d' ' -f4` ######################################################### ## Get input video framesize (width and height in pixels) ## in vars IN_WID and IN_HGT --- using 'mediainfo'. ## References: ## https://stackoverflow.com/questions/7376477/getting-video-information-from-mediainfo ## https://superuser.com/questions/595177/how-to-retrieve-video-file-information-from-command-line-under-linux ## https://stackoverflow.com/questions/684015/how-can-i-get-the-resolution-width-and-height-for-a-video-file-from-a-linux-co?noredirect=1 ## https://stackoverflow.com/questions/19091771/how-to-find-duration-of-a-video-file-using-mediainfo-in-seconds-or-other-formats ######################################################### IN_WID=`mediainfo --Inform="Video;%Width%" "$FILENAME"` IN_HGT=`mediainfo --Inform="Video;%Height%" "$FILENAME"` ######################################################### ## Alternatively: ## Get input video framesize (width and height in pixels) ## in vars IN_WID and IN_HGT --- using 'ffprobe'. ## Reference: ## https://stackoverflow.com/questions/7362130/getting-video-dimension-resolution-width-x-height-from-ffmpeg ## https://www.skillsugar.com/how-to-get-video-dimensions-with-ffmpeg ## https://askubuntu.com/questions/577090/one-liner-ffmpeg-or-other-to-get-only-resolution ## https://video.stackexchange.com/questions/16356/how-to-use-ffprobe-to-obtain-certain-information-about-mp4-h-264-files ######################################################### # IN_WID=`ffprobe -v error -show_entries stream=width -of default=noprint_wrappers=1 "$FILENAME" | cut -d'=' -f2` # IN_HGT=`ffprobe -v error -show_entries stream=height -of default=noprint_wrappers=1 "$FILENAME" | cut -d'=' -f2` ######################################################### ## Alternatively: ## Get input video framesize (width and height in pixels) ## in vars IN_WID and IN_HGT --- using 'ffmpeg'. ## Reference: ## https://superuser.com/questions/841235/how-do-i-use-ffmpeg-to-get-the-video-resolution ######################################################### # IN_WID=`ffmpeg -i "$FILENAME" 2>&1 | grep Video: | grep -Po '\d{3,5}x\d{3,5}' | cut -d'x' -f1` # IN_HGT=`ffmpeg -i "$FILENAME" 2>&1 | grep Video: | grep -Po '\d{3,5}x\d{3,5}' | cut -d'x' -f2` ############################################# ## Compute the ffmpeg '-filter:v' crop parms: ## OUT_WID, OUT_HGT, UPLFT_X, UPLFT_Y ############################################# ## Example crop command format: ## ffmpeg -i in.mp4 -filter:v "crop=out_w:out_h:x:y" -c:a copy out.mp4 ## ## Reference: ## https://video.stackexchange.com/questions/4563/how-can-i-crop-a-video-with-ffmpeg #################################################################################### PX_TOP=$(( (PCT_TOP*IN_HGT)/100 )) PX_RGT=$(( (PCT_RGT*IN_WID)/100 )) PX_BOT=$(( (PCT_BOT*IN_HGT)/100 )) PX_LFT=$(( (PCT_LFT*IN_WID)/100 )) OUT_WID=$(( IN_WID - (PX_RGT + PX_LFT) )) OUT_HGT=$(( IN_HGT - (PX_TOP + PX_BOT) )) UPLFT_X=$(( PX_LFT )) UPLFT_Y=$(( PX_TOP )) ########################################### ## Show the 4 calculated crop parameters and ## allow the user to change them or exit. ########################################### CROPPARMS="$OUT_WID $OUT_HGT $UPLFT_X $UPLFT_Y" CROPPARMS=$(zenity --entry \ --title "Check the crop parameters." \ --text "\ According to 'mediainfo' command, the image width and height are $IN_WID and $IN_HGT pixels. The 4 crop parameters calculated from percentages are OUT_WID = $OUT_WID OUT_HGT = $OUT_HGT UPLFT_X = $UPLFT_X UPLFT_Y = $UPLFT_Y Change them OR leave them unchanged --- OR delete them to exit (cancel)." \ --entry-text "$CROPPARMS") if test "$CROPPARMS" = "" then exit fi OUT_WID=`echo "$CROPPARMS" | cut -d' ' -f1` OUT_HGT=`echo "$CROPPARMS" | cut -d' ' -f2` UPLFT_X=`echo "$CROPPARMS" | cut -d' ' -f3` UPLFT_Y=`echo "$CROPPARMS" | cut -d' ' -f4` if test "$OUT_WID" = "" then exit fi ############################### ## Prepare the output filename. ############################### FILEMIDNAME=`echo "$FILENAME" | cut -d\. -f1` FILEOUT="${FILEMIDNAME}_CROPPED_${OUT_WID}x${OUT_HGT}.mp4" if test -f "$FILEOUT" then rm -f "$FILEOUT" fi ################################################################### ## Use 'ffmpeg' to make the cropped 'mp4' file. ################################################################### ## FOR TEST: # set -x xterm -hold -fg white -bg black -geometry 90x48+100+100 -e \ $EXE_FFMPEG -i "$FILENAME" \ -filter:v "crop=${OUT_WID}:${OUT_HGT}:${UPLFT_X}:${UPLFT_Y}" \ -c:a copy "$FILEOUT" ## FOR TEST: # set - ################################### ## Show the (cropped) movie file. ## ## Note: If ffmpeg is installed, ## then ffplay should be installed. ################################### if test ! -f "$FILEOUT" then exit fi # MOVIEPLAYER="/usr/bin/vlc" # MOVIEPLAYER="/usr/bin/mplayer" # MOVIEPLAYER="/usr/bin/gnome-mplayer" # MOVIEPLAYER="/usr/bin/totem" MOVIEPLAYER="/usr/bin/ffplay -stats" xterm -fg white -bg black -hold -geometry 90x24+100+100 -e \ $MOVIEPLAYER "$FILEOUT" ############################################## ## Use a user-specified MOVIEPLAYER. Someday? ############################################## # . $HOME/.freedomenv/feNautilusScripts/set_DIR_NautilusScripts.shi # . $DIR_NautilusScripts/.set_VIEWERvars.shi # $MOVIEPLAYER "$FILEOUT" &