Advertisement
MaxDjently

Ziggle Wump Media Compressor 0.2-beta.09.10.2024

Sep 10th, 2024
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 22.95 KB | Source Code | 0 0
  1. #!/data/data/com.termux/files/usr/bin/bash
  2.  
  3. # ATTENTION:
  4.  
  5. # Copying and pasting the script can introduce formatting that is improper to bash.  If the script doesn't run, you may need to use the dos2unix command to fix it.
  6.  
  7. # ex.  dos2unix ziggle_wump.sh
  8.  
  9. # --------------------
  10. #     Licence
  11. # --------------------
  12.  
  13. # This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
  14.  
  15. # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  16.  
  17. # You should have received a copy of the GNU General Public License along with  this program. If not, see <https://www.gnu.org/licenses/>.
  18.  
  19. # -----------------
  20. #     About
  21. # -----------------
  22.  
  23. # This script is for Termux on Android and is not associated with the apps it uses.
  24.  
  25. # Copyright Joshua Hansen and contributors: Microsoft Co-Pilot, OpenAI ChatGPT and Google Gemini.
  26.  
  27. # Shout out to Webernets https://youtu.be/0aeCfDKLfbs?si=58y58eWSiXurcHpj who gave me the inspiration for this, the one who did the heavy lifting figuring out the command line options. And this video helping me figure out how to do it in Handbrake, but I needed it all in a one-line command line option and this was it, I had to write it myself.
  28.  
  29. # -----------------------
  30. #   Instructions
  31. # -----------------------
  32.  
  33. # Usage: ./ziggle_wump.sh [-r resolution] [-f "ffmpeg_options"] [-h|--help]
  34. #   -r resolution        Custom resolution height preserving aspect ratio, Downscaling your videos will significantly reduce the file size, but may introduce artifacts and shimmering.  Upscaling will produce larger file sizes and not increase quality.
  35. #   -f "ffmpeg_options" Override default FFmpeg options with custom command line options.  ex. bash ./ziggle_wump.sh -f "-c:v libx264 -c:a libmp3lame"
  36. #   -h, --help           Display this help message
  37.  
  38. # 1. Download or Copy this script to a file, and rename it if you want.  e.g., ziggle_wump.sh.  Putting it in your Movies folder will make it easy to find on both Android and Termux, although it's possible to put this in your /usr/bin to use it as a system app.  Your mileage may vary.
  39. # 2. Make it executable: chmod +x ziggle_wump.sh
  40. # 3. Run the script: bash ./ziggle_wump.sh [options]
  41.  
  42. # -------------------
  43. #    README
  44. # -------------------
  45.  
  46. # Ziggle Wump: The Simple FFmpeg Command Line Companion Script for Termux on Android
  47.  
  48. # DISCLAIMER:  THE SCRIPT DOES NOT ALLOW YOU TO CONVERT ENCRYPTED FILES, COPYRIGHTED CONTENT IS GENERALLY ENCRYPTED. THE SCRIPT IN ITSELF DOES NOT VIOLATE COPYRIGHT BUT THE USER MIGHT.  CODE TO PREVENT CIRCUMVENTION IS BEYOND MY CAPABILITY.  NOR SHOULD IT BE MY RESPONSIBILITY, IT'S THE COPYRIGHT HOLDERS RESPONSIBILITY TO ENCRYPT THEIR MEDIA.  IT IS NOT RECOMMENDED TO USE THE SCRIPT TO VIOLATE COPYRIGHT LAW.  US COPYRIGHT LAW ALLOWS FOR SPACESHIFTING, AND FAIR USE OF COPYRIGHTED MATERIAL
  49.  
  50. # NOTE:  Some phones have a battery saving feature such as the Galaxy S24, that can impact the encoding process and leave you with partially encoded files.  Please make sure Termux is in focus otherwise, either full screen or split screen if you want to do other things, and keep the screen on while encoding.
  51.  
  52. # Check out https://dontkillmyapp.com/ for more information and perhaps find a fix for your particular phone.
  53.  
  54. # Supported File Types:
  55. # Video:  mp4 mkv avi mov flv wmv webm mts
  56. # Audio: mp3 wav flac aac ogg m4a
  57.  
  58. # -----------------------------
  59. #        Variables
  60. # -----------------------------
  61.  
  62. # Values for video output settings.  Either the user defined value or the input video original value will be selected, whichever is lower.  (empty implies original value)
  63. resolution=600 # Output resolution by height.  
  64. output_fps=30
  65. max_video_bitrate=1500
  66.  
  67. # Initialize ffmpeg_custom_options
  68. ffmpeg_custom_options="-c:v libx265 -crf 23 -preset slow -x265-params \"deblock=-1:no-sao=1:keyint=250:aq-mode=3:psy-rd=0.75:psy-rdoq=2.0:rd=4:rdoq-level=1:rect=0:strong-intra-smoothing=0\" -c:a libopus -b:a 96k -vbr on -ac 2 -af \"loudnorm=I=-23:LRA=7:TP=-2\" -c:s srt -c:s ass -c:s ssa -c:s mov_text -c:s webvtt -c:s copy"
  69.  
  70. # Full Log file path
  71. log_file="$HOME/storage/shared/Movies/VideoDrop/convert.log"
  72.  
  73. # Shortened log file path for terminal output
  74. log_file_echo=$(echo "$log_file" | sed 's|/data/data/com.termux/files/home|.../home|g')
  75.  
  76. # Full directory paths
  77. video_drop_dir="$HOME/storage/shared/Movies/VideoDrop"
  78. video_processing_dir="$HOME/storage/shared/Movies/VideoProcessing"
  79. output_dir_base="$HOME/storage/shared/Movies/VideoConverted"
  80.  
  81. # Shortened directory paths for terminal output
  82. video_drop_dir_echo=$(echo "$video_drop_dir" | sed 's|/data/data/com.termux/files/home|.../home|g')
  83. video_processing_dir_echo=$(echo "$video_processing_dir" | sed 's|/data/data/com.termux/files/home|.../home|g')
  84. output_dir_base_echo=$(echo "$output_dir_base" | sed 's|/data/data/com.termux/files/home|.../home|g')
  85.  
  86. # Add maxrate and bufsize options if max_video_bitrate is set
  87. if [ -n "$max_video_bitrate" ]; then
  88.     ffmpeg_custom_options="$ffmpeg_custom_options -maxrate ${max_video_bitrate}k -bufsize 15000k"
  89. fi
  90.  
  91. echo "FFmpeg options: $ffmpeg_custom_options" | tee -a "$log_file"
  92. sleep 1
  93.  
  94. # -----------------------------
  95. #    Command Flags
  96. # -----------------------------
  97.  
  98. # Function to display help message
  99. show_help() {
  100.     width=$(tput cols)
  101.     echo "Place your media files in $video_drop_dir_echo." | tee -a "$log_file" | fmt -w $width
  102.     echo "Usage: $0 [-r resolution] [-f \"ffmpeg_options\"] [-h|--help]" | fmt -w $width
  103.     echo "  -r resolution ex. bash $0 -r 720               Custom resolution height preserving aspect ratio, Downscaling your videos will significantly reduce the file size, but may introduce artifacts and shimmering.  Upscaling will produce larger file sizes and not increase quality." | fmt -w $width
  104.     echo "  -f \"ffmpeg_options\"  Override default FFmpeg options with custom command line options.  ex. bash $0 -f \""-c:v libx264 -c:a libmp3lame\" | fmt -w $width
  105.     echo "  -h, --help           Display this help message" | fmt -w $width
  106.     exit 0
  107. }
  108.  
  109. # Parse command-line options
  110. while getopts "r:f:h" opt; do
  111.     case $opt in
  112.         r) resolution="$OPTARG" ;;  # Set custom resolution by height
  113.         f) ffmpeg_custom_options="$OPTARG" ;;  # Set custom FFmpeg options
  114.         h) show_help ;;  # Display help
  115.         *) show_help ;;  # Display help for invalid options
  116.     esac
  117. done
  118.  
  119. shift $((OPTIND -1))
  120.  
  121. # ---------------------------------
  122. #       Dependencies
  123. # ---------------------------------
  124.  
  125. # Ensure dependencies are installed and all packages are up to date.
  126.     echo "Updating, please wait..."
  127.     sleep 1
  128.     pkg update && pkg upgrade -y
  129.     if ! command -v bc &> /dev/null; then
  130.         pkg install bc -y
  131.     fi
  132.     if ! command -v ffmpeg &> /dev/null; then
  133.         pkg install ffmpeg -y
  134.     fi
  135.     if ! command -v ncurses-utils &> /dev/null; then
  136.         pkg install ncurses-utils -y
  137.     fi
  138. echo "Update complete."
  139.     sleep 1
  140.  
  141. # -----------------------------------------------------
  142. #     Create Directories and log file
  143. # -----------------------------------------------------
  144.  
  145. # Create necessary directories if they don't exist
  146. mkdir -p "$video_drop_dir" "$video_processing_dir" "$output_dir_base"
  147.  
  148. # Change to the VideoDrop directory
  149. cd "$video_drop_dir" || { echo "Directory change failed"; exit 1; }
  150.  
  151. # Check if log file exists
  152. if [ -f "$log_file" ]; then
  153.     echo "Old log file found.  Deleting..."
  154.     rm "$log_file"
  155.     echo "File deleted."
  156. else
  157.     echo "Log File does not exist.  The script will create $log_file_echo"
  158. fi
  159.  
  160. # ------------------------
  161. #     Start script
  162. # ------------------------
  163.  
  164. width=$(tput cols)
  165.  
  166. echo "Running... Press Ctrl+C to stop."
  167. sleep 1
  168.  
  169. echo ""
  170. echo "NOTE:  Some phones have a battery saving feature such as the Galaxy S24, that can impact the encoding process and leave you with partially encoded files.  Please make sure Termux is in focus, either full screen or split screen if you want to do other things, and keep the screen on while encoding." | tee -a "$log_file" | fmt -w $width
  171.  
  172. echo ""
  173. echo "Check out https://dontkillmyapp.com/ for more information and perhaps find a fix for your particular phone." | tee -a "$log_file" | fmt -w $width
  174.  
  175. echo ""
  176. # Function to prompt the user to continue or quit
  177. prompt_continue_or_quit() {
  178.     while true; do
  179.         # Recursively find and process videos and audio
  180.         video_count=$(find "$video_drop_dir" -type f \( -iname '*.mp3' -o -iname '*.wav' -o -iname '*.flac' -o -iname '*.aac' -o -iname '*.ogg' -o -iname '*.m4a' -o -iname '*.mp4' -o -iname '*.mkv' -o -iname '*.avi' -o -iname '*.mov' -o -iname '*.flv' -o -iname '*.wmv' -o -iname '*.webm' -o -iname '*.mts' \) | wc -l)
  181.  
  182.         if [ "$video_count" -eq 0 ]; then
  183.             echo "No videos or audio found. $video_drop_dir_echo folder created. Place your videos and audio here including in folders using your favorite file manager for Android, and then run the script again. Supported File Types: Video: mp4 mkv avi mov flv wmv webm mts Audio: mp3 wav flac aac ogg m4a" | tee -a "$log_file" | fmt -w $width
  184.             exit 0
  185.         fi
  186.  
  187.         # Prompt text
  188.         prompt_text="Compatible media files detected in $video_drop_dir_echo. You can start encoding now. Do you wish to proceed? (Y/N): "
  189.  
  190.         # Format the prompt text
  191.         formatted_prompt=$(echo "$prompt_text" | fmt -w $width)
  192.  
  193.         # Read user input with formatted prompt
  194.         read -p "$formatted_prompt" yn
  195.         case $yn in
  196.             [Yy]* ) return 0;;  # Continue
  197.             [Nn]* ) echo "Exiting script."; exit 0;;  # Quit
  198.             * ) echo "Please answer Y or N.";;
  199.         esac
  200.     done
  201. }
  202.  
  203. # Function to clean up file names
  204. clean_file_names() {
  205.     find "$video_drop_dir" -type f \( -iname '*.mp3' -o -iname '*.wav' -o -iname '*.flac' -o -iname '*.aac' -o -iname '*.ogg' -o -iname '*.m4a' -o -iname '*.mp4' -o -iname '*.mkv' -o -iname '*.avi' -o -iname '*.mov' -o -iname '*.flv' -o -iname '*.wmv' -o -iname '*.webm' -o -iname '*.mts' \) | while read -r file; do
  206.         dir=$(dirname "$file")
  207.         base=$(basename "$file")
  208.         new_base=$(echo "$base" | sed 's/[^a-zA-Z0-9 ._-]//g' | tr -s ' ')
  209.         new_file="$dir/$new_base"
  210.         if [ "$file" != "$new_file" ]; then
  211.             mv "$file" "$new_file"
  212.         fi
  213.     done
  214. }
  215.  
  216. # Clean up file names before processing
  217. clean_file_names
  218.  
  219. # Prompt the user to continue or quit?  Comment line to skip prompt prior to encoding.
  220. prompt_continue_or_quit
  221.  
  222. echo "Starting conversion process..." | tee -a "$log_file"
  223. sleep 1
  224.  
  225. # -----------------------------
  226. #    Audio Encoder
  227. # -----------------------------
  228.  
  229. width=$(tput cols)
  230.  
  231. # Function to check the log file for "Killed" message
  232. check_for_killed_message() {
  233.     if grep -q " Killed     " "$log_file"; then
  234.         echo "$(date '+%Y-%m-%d %H:%M:%S') Error: Process was killed. Check log file for details." | tee -a "$log_file"
  235.         return 1
  236.     fi
  237.     return 0
  238. }
  239.  
  240. # Function to process audio files
  241. process_audio() {
  242.     local audio="$1"
  243.     local audio_echo=$(echo "$audio" | sed 's|/data/data/com.termux/files/home|/home|g')
  244.     local relative_path="${audio#$video_drop_dir/}"
  245.     local dir_path=$(dirname "$relative_path")
  246.     local base_name=$(basename "$relative_path" | tr -cd '[:alnum:]._ -')
  247.     local output_dir="$output_dir_base/$dir_path"
  248.     local output_file="$output_dir/${base_name}_converted.opus"
  249.     local temp_output_file="$output_file.tmp"
  250.  
  251.     mkdir -p "$output_dir"  # Create output directory
  252.  
  253.     echo "$(date '+%Y-%m-%d %H:%M:%S') Processing $audio to $output_file" | tee -a "$log_file"
  254.  
  255.     # Construct the FFmpeg command for audio processing
  256.     local ffmpeg_command="ffmpeg -nostdin -loglevel error -stats -stats_period 1 -y -i \"$audio\" -c:a libopus -b:a 96k -vbr on -ac 2 -af \"loudnorm=I=-23:LRA=7:TP=-2\" -f opus \"$temp_output_file\""
  257.  
  258.     # Execute the FFmpeg command
  259.     eval $ffmpeg_command 2>&1 | tee -a "$log_file"
  260.  
  261.     # Check for "Killed" message in the log file
  262.     if ! check_for_killed_message; then
  263.         echo "$(date '+%Y-%m-%d %H:%M:%S') Error: Process was killed. Exiting." | tee -a "$log_file"
  264.         exit 1
  265.     fi
  266.  
  267.     if [ $? -eq 0 ]; then
  268.         mv "$temp_output_file" "$output_file"  # Rename the temporary file to the final output file
  269.         mkdir -p "$video_processing_dir/$dir_path"  # Create processing directory
  270.         mv "$audio" "$video_processing_dir/$relative_path"
  271.         echo ""
  272.         echo "$(date '+%Y-%m-%d %H:%M:%S') Converted $audio_echo. Your original files will be in the $video_processing_dir_echo folder for comparison. Your new files are in $output_dir_base_echo" | tee -a "$log_file" | fmt -w $width
  273.     else
  274.         echo ""
  275.         echo "$(date '+%Y-%m-%d %H:%M:%S') Error processing \"$audio\". Check log file for details." | tee -a "$log_file"
  276.         exit 1
  277.     fi
  278. }
  279.  
  280. # ------------------------------
  281. #      Video Encoder
  282. # ------------------------------
  283.  
  284. width=$(tput cols)
  285.  
  286. # Function to check the log file for "Killed" message
  287. check_for_killed_message() {
  288.     if grep -q " Killed     " "$log_file"; then
  289.         echo "$(date '+%Y-%m-%d %H:%M:%S') Error: Process was killed. Check log file for details." | tee -a "$log_file" | fmt -w $width
  290.         exit 1
  291.     fi
  292. }
  293.  
  294. process_video() {
  295.     local video="$1"
  296.     local video_echo=$(echo "$video" | sed 's|/data/data/com.termux/files/home|.../home|g')
  297.     local relative_path="${video#$video_drop_dir/}"
  298.     local dir_path=$(dirname "$relative_path")
  299.     local base_name=$(basename "$relative_path" | tr -cd '[:alnum:]._ -')
  300.     local output_dir="$output_dir_base/$dir_path"
  301.     local output_file="$output_dir/${base_name}_converted.mkv"
  302.     local scale_filter=""
  303.  
  304.     # Get input video resolution and clean up any trailing commas or spaces
  305.     input_resolution=$(ffprobe -v error -select_streams v:0 -show_entries stream=height -of csv=p=0 "$video" | tr -d '[:space:],')
  306.  
  307.     if [ -n "$resolution" ]; then
  308.         if [ "$input_resolution" -gt "$resolution" ]; then
  309.             scale_filter="scale=-2:$resolution:flags=lanczos"
  310.             echo "Input resolution ($input_resolution) is higher than user-defined resolution ($resolution). Using user-defined resolution." | tee -a "$log_file"
  311.         else
  312.             echo "Input resolution ($input_resolution) is lower or equal to user-defined resolution ($resolution). Keeping original resolution." | tee -a "$log_file"
  313.         fi
  314.     else
  315.         echo "Resolution set to: original" | tee -a "$log_file"
  316.     fi
  317.  
  318.     mkdir -p "$output_dir"  # Create output directory
  319.  
  320.     echo "$(date '+%Y-%m-%d %H:%M:%S') Processing $video to $output_file" | tee -a "$log_file"
  321.  
  322.     # Get the frame rate of the input video
  323.     input_fps=$(ffprobe -v error -select_streams v:0 -show_entries stream=avg_frame_rate,r_frame_rate -of csv=p=0 "$video" | awk -F'/' '{if ($2) print $1/$2; else print $1}' | bc -l)
  324.  
  325.     # Define common frame rates
  326.     common_fps=(23.976 24 25 29.97 30 50 59.94 60)
  327.  
  328.     # Function to find the nearest valid frame rate
  329.     nearest_fps() {
  330.         local fps=$1
  331.         local nearest=${common_fps[0]}
  332.         local min_diff=$(echo "scale=5; $fps - ${common_fps[0]}" | bc | awk '{print ($1 >= 0) ? $1 : -$1}')
  333.         for rate in "${common_fps[@]}"; do
  334.             local diff=$(echo "scale=5; $fps - $rate" | bc | awk '{print ($1 >= 0) ? $1 : -$1}')
  335.             if (( $(echo "$diff < $min_diff" | bc -l) )); then
  336.                 min_diff=$diff
  337.                 nearest=$rate
  338.             fi
  339.         done
  340.         echo $nearest
  341.     }
  342.  
  343.     # Round the frame rate to the nearest valid frame rate
  344.     rounded_fps=$(nearest_fps $input_fps)
  345.  
  346.     # Determine the lower frame rate
  347.     if (( $(echo "$rounded_fps > $output_fps" | bc -l) )); then
  348.         final_fps=$output_fps
  349.     else
  350.         final_fps=$rounded_fps
  351.     fi
  352.  
  353. # Set the initial video filter option
  354. video_filter_option="${scale_filter},fps=$final_fps"
  355.  
  356. # Detect the pixel format using ffprobe
  357. input_file="$video"
  358. pix_fmt=$(ffprobe -v error -select_streams v:0 -show_entries stream=pix_fmt -of default=noprint_wrappers=1:nokey=1 "$input_file")
  359.  
  360. echo "Pixel format: $pix_fmt"
  361. sleep 1
  362.  
  363. # Validate the pixel format
  364. valid_pix_fmt=$(ffmpeg -pix_fmts | grep -w "$pix_fmt")
  365.  
  366. # Check if 10-bit encoding is selected
  367. if [[ "$pix_fmt" == *"10le"* || "$pix_fmt" == *"10be"* ]]; then
  368.     video_filter_option="$video_filter_option,deband=1thr=0.01:2thr=0.01:3thr=0.01:4thr=0.01:range=4:direction=-3.14:blur=1:coupling=0"
  369. fi
  370.  
  371. # Check if the video is progressive or interlaced
  372. field_order=$(ffprobe -v error -select_streams v:0 -show_entries stream=field_order -of default=noprint_wrappers=1:nokey=1 "$input_file")
  373.  
  374. # Apply yadif filter if the video is interlaced or if field_order is unknown
  375. if [ "$field_order" == "progressive" ]; then
  376.     if [ -n "$scale_filter" ]; then
  377.         video_filter_option="${scale_filter},fps=$final_fps"
  378.     else
  379.         video_filter_option="fps=$final_fps"
  380.     fi
  381. else
  382.     if [ -n "$scale_filter" ]; then
  383.         video_filter_option="yadif=2,${scale_filter},fps=$final_fps"
  384.     else
  385.         video_filter_option="yadif=2,fps=$final_fps"
  386.     fi
  387. fi
  388.  
  389. # Add noise to the output video to simulate film grain and add dithering to smooth out bright colors.
  390. video_filter_option="$video_filter_option,noise=alls=2:allf=t+u"
  391.  
  392. # Log the final video filter option
  393. echo "Video filter option: $video_filter_option" | tee -a "$log_file"
  394. sleep 1
  395.  
  396. # Detect subtitle codecs and convert unsupported ones
  397. subtitle_codecs=$(ffprobe -v error -select_streams s -show_entries stream=codec_name -of csv=p=0 "$input_file")
  398. subtitle_map=""
  399. if [ -n "$subtitle_codecs" ]; then
  400.     i=0
  401.     while read -r codec; do
  402.         case "$codec" in
  403.             srt|ass|ssa|webvtt|dvdsub|pgs|vobsub)
  404.                 subtitle_map="$subtitle_map -c:s:$i copy"
  405.                 ;;
  406.             mov_text|other_unsupported_codec)
  407.                 subtitle_map="$subtitle_map -c:s:$i srt"
  408.                 ;;
  409.             *)
  410.                 echo "Unsupported subtitle codec: $codec. Skipping." | tee -a "$log_file"
  411.                 ;;
  412.         esac
  413.         i=$((i + 1))
  414.     done <<< "$subtitle_codecs"
  415. else
  416.     echo "No subtitle streams detected." | tee -a "$log_file"
  417. fi
  418.  
  419. # Combine common and custom FFmpeg options
  420. combined_ffmpeg_options="-nostdin -loglevel error -stats -stats_period 5 -analyzeduration 2147483647 -probesize 2147483647 -y -i \"$video\" $ffmpeg_custom_options"
  421.  
  422. # Construct the FFmpeg command
  423. local ffmpeg_command
  424. if [ -n "$valid_pix_fmt" ]; then
  425.     if [ -n "$subtitle_map" ]; then
  426.         ffmpeg_command="ffmpeg $combined_ffmpeg_options -vf \"$video_filter_option\" -pix_fmt $pix_fmt $subtitle_map"
  427.     else
  428.         ffmpeg_command="ffmpeg $combined_ffmpeg_options -vf \"$video_filter_option\" -pix_fmt $pix_fmt"
  429.     fi
  430. else
  431.     if [ -n "$subtitle_map" ]; then
  432.         ffmpeg_command="ffmpeg $combined_ffmpeg_options -vf \"$video_filter_option\" $subtitle_map"
  433.     else
  434.         ffmpeg_command="ffmpeg $combined_ffmpeg_options -vf \"$video_filter_option\""
  435.     fi
  436. fi
  437.  
  438. # Ensure all subtitle streams are marked as "default: off"
  439. subtitle_streams=$(ffprobe -v error -select_streams s -show_entries stream=index -of csv=p=0 "$input_file")
  440. if [ -n "$subtitle_streams" ]; then
  441.     for stream_index in $subtitle_streams; do
  442.         ffmpeg_command="$ffmpeg_command -disposition:s:$stream_index 0"
  443.     done
  444. fi
  445.  
  446. # Add the output file name at the end
  447. ffmpeg_command="$ffmpeg_command \"$output_file\""
  448.  
  449. echo "FFmpeg command: $ffmpeg_command" | tee -a "$log_file"
  450. sleep 1
  451.  
  452. # Execute the FFmpeg command
  453. eval $ffmpeg_command 2>&1 | tee -a "$log_file"
  454.  
  455.     # Check for "Killed" message in the log file
  456.     check_for_killed_message
  457.  
  458.    if [ $? -eq 0 ]; then
  459.         mkdir -p "$video_processing_dir/$dir_path"  # Create processing directory
  460.         mv "$video" "$video_processing_dir/$relative_path"
  461.         echo ""
  462.         echo "$(date '+%Y-%m-%d %H:%M:%S') Converted $video_echo. Your original files will be in the $video_processing_dir_echo folder for comparison. Your new files are in $output_dir_base_echo" | tee -a "$log_file" | fmt -w $width
  463.     else
  464.         echo ""
  465.         echo "$(date '+%Y-%m-%d %H:%M:%S') Error processing \"$video\". Check log file for details." | tee -a "$log_file"
  466.         exit 1
  467.     fi
  468. }
  469.  
  470. # --------------------------------------
  471. #    Start Batch Encoding
  472. # --------------------------------------
  473.  
  474. width=$(tput cols)
  475.  
  476. # Recursively find and process videos and audio
  477. video_count=$(find "$video_drop_dir" -type f \( -iname '*.mp3' -o -iname '*.wav' -o -iname '*.flac' -o -iname '*.aac' -o -iname '*.ogg' -o -iname '*.m4a' -o -iname '*.mp4' -o -iname '*.mkv' -o -iname '*.avi' -o -iname '*.mov' -o -iname '*.flv' -o -iname '*.wmv' -o -iname '*.webm' -o -iname '*.mts' \) | wc -l)
  478.  
  479. # Process each audio file found
  480. find "$video_drop_dir" -type f \( -iname '*.mp3' -o -iname '*.wav' -o -iname '*.flac' -o -iname '*.aac' -o -iname '*.ogg' -o -iname '*.m4a' \) | while read -r audio; do
  481.  
  482.     stop_processing=false
  483.  
  484.     # Function to handle SIGINT (Ctrl+C)
  485.     handle_sigint() {
  486.         echo ""
  487.         echo "Caught SIGINT (Ctrl+C). Exiting immediately." | fmt -w $width
  488.         exit 1  # Exit immediately without performing cleanup
  489.     }
  490.  
  491.     # Trap SIGINT and call the handle_sigint function
  492.     trap handle_sigint SIGINT
  493.  
  494.     if [ "$stop_processing" = true ]; then
  495.         echo "Stopping processing due to SIGINT."
  496.         exit 1
  497.     fi
  498.     process_audio "$audio" || exit 1
  499.  
  500.     # Remove the relative path folder if it's empty
  501.     rmdir "$(dirname "$audio")" --ignore-fail-on-non-empty
  502. done
  503.  
  504. # Process each video found
  505. find "$video_drop_dir" -type f \( -iname '*.mp4' -o -iname '*.mkv' -o -iname '*.avi' -o -iname '*.mov' -o -iname '*.flv' -o -iname '*.wmv' -o -iname '*.webm'  -o -iname '*.mts' \) | while read -r video; do
  506.  
  507.     stop_processing=false
  508.  
  509.     # Function to handle SIGINT (Ctrl+C)
  510.     handle_sigint() {
  511.         echo ""
  512.         echo "Caught SIGINT (Ctrl+C). Exiting immediately." | fmt -w $width
  513.         exit 1  # Exit immediately without performing cleanup
  514.     }
  515.  
  516.     # Trap SIGINT and call the handle_sigint function
  517.     trap handle_sigint SIGINT
  518.  
  519.     if [ "$stop_processing" = true ]; then
  520.         echo "Stopping processing due to SIGINT."
  521.         exit 1
  522.     fi
  523.     process_video "$video" || exit 1
  524.  
  525.     # Remove the relative path folder if it's empty
  526.     rmdir "$(dirname "$video")" --ignore-fail-on-non-empty
  527. done
  528.  
  529. # -----------------------------
  530. #     Finishing Up
  531. # -----------------------------
  532.  
  533. width=$(tput cols)
  534.  
  535. # final output message
  536. echo ""
  537. echo "Log file is in $video_drop_dir_echo.  There may be unprocessed media files or other incompatible files.  Some files may need to be remuxed for compatibility." | tee -a "$log_file" | fmt -w $width
  538. exit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement