Advertisement
MaxDjently

Ziggle Wump Media Compressor 0.2-beta.09.14.2024

Sep 14th, 2024 (edited)
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 22.65 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: bash ziggle_wump.sh [-r resolution] [-d] [-y] [-h|--help] [-o output_fps] [-b max_video_bitrate] [-a avg_audio_bitrate]
  34. #   -r resolution        Custom resolution height preserving aspect ratio. Downscaling your videos will significantly reduce the file size, but may introduce artifacts and shimmering.
  35. #   -d                   Check and upgrade dependencies.
  36. #   -y                   Automatically say yes to prompts.
  37. #   -o output_fps        Set custom output FPS. ex. bash $0 -o 60
  38. #   -b max_video_bitrate Set custom max video bitrate in kilobits per second. ex. bash $0 -b 2000
  39. #   -a avg_audio_bitrate Set custom average audio bitrate in Kilobits per second. ex. bash $0 -a 128
  40. #   -h, --help           Display this help message
  41.  
  42. # 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.
  43. # 2. Make it executable: chmod +x ziggle_wump.sh
  44. # 3. Run the script: bash ./ziggle_wump.sh [options]
  45.  
  46. # -------------------
  47. #       Title
  48. # -------------------
  49.  
  50. title="Ziggle Wump: The Simple FFmpeg Command Line Companion Script for Termux on Android
  51.  
  52. 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
  53.  
  54. 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.
  55.  
  56. Check out https://dontkillmyapp.com/ for more information and perhaps find a fix for your particular phone."
  57.  
  58.  
  59. # -----------------------------
  60. #        Variables
  61. # -----------------------------
  62.  
  63.  
  64. # Supported File Types
  65. video_ext="mp4 mkv avi mov flv wmv webm mts"
  66. audio_ext="mp3 wav flac aac ogg m4a opus"
  67.  
  68. # Maximum resolution by height in pixels maintaining aspect ratio. Either the user defined value or the input video original value will be selected
  69. resolution=600
  70. max_video_bitrate=1000 # In Kilobits per second.
  71. # Set the audio bitrate for both videos and audio files.
  72. avg_audio_bitrate=96 # In Kilobits per second.
  73. output_fps=30 # Maximum output FPS. Original or user input, whichever is lower.
  74.  
  75. # Initialize ffmpeg_custom_options
  76. ffmpeg_custom_options="-c:v libx265 -x265-params \"deblock=-1:no-sao=1:keyint=250:aq-mode=3:psy-r=0.75:psy-rdoq=2.0:rd=4:rdoq-level=1:rect=0:strong-intra-smoothing=0\" -crf 24 -preset slow -c:a libopus -b:a ${avg_audio_bitrate}k -vbr on -ac 2 -af \"loudnorm=I=-23:LRA=7:TP=-2\""
  77.  
  78. # Full Log file path
  79. log_file="$HOME/storage/shared/Movies/VideoDrop/convert.log"
  80.  
  81. # Shortened log file path for terminal output
  82. log_file_echo=$(echo "$log_file" | sed 's|/data/data/com.termux/files/home|.../home|g')
  83.  
  84. # Full directory paths
  85. video_drop_dir="$HOME/storage/shared/Movies/VideoDrop"
  86. video_processing_dir="$HOME/storage/shared/Movies/VideoProcessing"
  87. output_dir_base="$HOME/storage/shared/Movies/VideoConverted"
  88.  
  89. # Shortened directory paths for terminal output
  90. video_drop_dir_echo=$(echo "$video_drop_dir" | sed 's|/data/data/com.termux/files/home|.../home|g')
  91. video_processing_dir_echo=$(echo "$video_processing_dir" | sed 's|/data/data/com.termux/files/home|.../home|g')
  92. output_dir_base_echo=$(echo "$output_dir_base" | sed 's|/data/data/com.termux/files/home|.../home|g')
  93.  
  94. # combine audio and video extension variables to pass to find command.
  95. filetypes=""
  96. for ext in $audio_ext $video_ext; do
  97.     filetypes="$filetypes -iname '*.$ext' -o"
  98. done
  99. # Remove the trailing ' -o'
  100. filetypes="${filetypes% -o}"
  101.  
  102. # Add maxrate and bufsize options if max_video_bitrate is set
  103. if [ -n "$max_video_bitrate" ]; then
  104.     ffmpeg_custom_options="$ffmpeg_custom_options -maxrate ${max_video_bitrate}k -bufsize 15000k"
  105. fi
  106.  
  107. # -----------------------------
  108. #    Command Flags
  109. # -----------------------------
  110.  
  111. # Function to display help message
  112. show_help() {
  113.     width=$(tput cols)
  114.     echo "Place your media files in $video_drop_dir_echo." | tee -a "$log_file" | fmt -w $width
  115.     echo "Usage: $0 [-r resolution] [-d] [-y] [-h|--help] [-o output_fps] [-b max_video_bitrate] [-a avg_audio_bitrate]" | fmt -w $width
  116.     echo "  -r resolution ex. bash $0 -r 720               Custom resolution height preserving aspect ratio" | fmt -w $width
  117.     echo "  -d                   Check and upgrade dependencies." | fmt -w $width
  118.     echo "  -y                   Automatically say yes to prompts." | fmt -w $width
  119.     echo "  -o output_fps        Set custom output FPS. ex. bash $0 -o 60" | fmt -w $width
  120.     echo "  -b max_video_bitrate Set custom max video bitrate in kilobits per second. ex. bash $0 -b 2000" | fmt -w $width
  121.     echo "  -a avg_audio_bitrate Set custom average audio bitrate in kilobits per second. ex. bash $0 -a 128" | fmt -w $width
  122.     echo "  -h, --help           Display this help message" | fmt -w $width
  123.     exit 0
  124. }
  125.  
  126. # Parse command-line options
  127. auto_yes=false
  128. check_deps=false
  129. while getopts "r:dyho:b:a:" opt; do
  130.     case $opt in
  131.         r) resolution="$OPTARG" ;;  # Set custom resolution by height
  132.         d) check_deps=true ;;  # Check and upgrade dependencies
  133.         y) auto_yes=true ;;  # Automatically say yes to prompts
  134.         o) output_fps="$OPTARG" ;;  # Set custom output FPS
  135.         b) max_video_bitrate="$OPTARG" ;;  # Set custom max video bitrate
  136.         a) avg_audio_bitrate="$OPTARG" ;;  # Set custom average audio bitrate
  137.         h) show_help ;;  # Display help
  138.         *) show_help ;;  # Display help for invalid options
  139.     esac
  140. done
  141.  
  142. shift $((OPTIND -1))
  143.  
  144. # ---------------------------------
  145. #       Dependencies
  146. # ---------------------------------
  147.  
  148. if $check_deps; then
  149.     echo "Checking and upgrading dependencies, please wait..."
  150.     pkg update && pkg upgrade -y
  151.     if ! command -v bc &> /dev/null; then
  152.         pkg install bc -y
  153.     fi
  154.     if ! command -v ffmpeg &> /dev/null; then
  155.         pkg install ffmpeg -y
  156.     fi
  157.     if ! command -v ncurses-utils &> /dev/null; then
  158.         pkg install ncurses-utils -y
  159.     fi
  160.     echo "Update complete."
  161. fi
  162.  
  163. # -----------------------------------------------------
  164. #     Create Directories and log file
  165. # -----------------------------------------------------
  166.  
  167. # Create necessary directories if they don't exist
  168. mkdir -p "$video_drop_dir" "$video_processing_dir" "$output_dir_base"
  169.  
  170. # Change to the VideoDrop directory
  171. cd "$video_drop_dir" || { echo "Directory change failed"; exit 1; }
  172.  
  173. # Check if log file exists
  174. if [ -f "$log_file" ]; then
  175.     echo "Old log file found.  Deleting..."
  176.     rm "$log_file"
  177.     echo "File deleted."
  178. else
  179.     echo "Log File does not exist.  The script will create $log_file_echo"
  180. fi
  181.  
  182. # ------------------------
  183. #     Start script
  184. # ------------------------
  185.  
  186. width=$(tput cols)
  187.  
  188. echo "Running... Press Ctrl+C to stop."
  189.  
  190. echo ""
  191. echo "$title" | tee -a "$log_file" | fmt -w $width
  192.  
  193. echo ""
  194. # Function to prompt the user to continue or quit
  195. prompt_continue_or_quit() {
  196.     while true; do
  197.         # Recursively find and process videos and audio
  198.         video_count=$(eval "find \"$video_drop_dir\" -type f \( $filetypes \) | wc -l")
  199.         echo "Detected $video_count compatible video and audio files in:" | tee -a "$log_file" | fmt -w $width
  200.    
  201.         if [ "$video_count"  -eq 0 ]; then
  202.             echo "$video_drop_dir_echo folder created. Place your videos and audio here including files in folders using your favorite file manager for Android, and then run  the script again.  
  203.  
  204. Supported File Types:
  205.  
  206. Video: $video_ext
  207. Audio: $audio_ext" | tee -a "$log_file" | fmt -w $width
  208.             exit 0
  209.         fi
  210.  
  211.         # Prompt text
  212.         prompt_text="$video_drop_dir_echo. You can start encoding now. Do you wish to proceed? (Y/N): "
  213.  
  214.         # Format the prompt text
  215.         formatted_prompt=$(echo "$prompt_text" | fmt -w $width)
  216.  
  217.         if $auto_yes; then
  218.             echo "$formatted_prompt"
  219.             echo "Y"
  220.             return 0  # Automatically continue
  221.         else
  222.             # Read user input with formatted prompt
  223.             read -p "$formatted_prompt" yn
  224.             case $yn in
  225.                 [Yy]* ) return 0;;  # Continue
  226.                 [Nn]* ) echo "Exiting script."; exit 0;;  # Quit
  227.                 * ) echo "Please answer Y or N.";;
  228.             esac
  229.         fi
  230.     done
  231. }
  232.  
  233. # Function to clean up file names
  234. clean_file_names() {
  235.     eval "find \"$video_drop_dir\" -type f \( $filetypes \)" | while read -r file; do
  236.         dir=$(dirname "$file")
  237.         base=$(basename "$file")
  238.         new_base=$(echo "$base" | sed 's/[^a-zA-Z0-9 ._-]//g' | tr -s ' ')
  239.         new_file="$dir/$new_base"
  240.         if [ "$file" != "$new_file" ]; then
  241.             mv "$file" "$new_file"
  242.         fi
  243.     done
  244. }
  245.  
  246. # Clean up file names before processing
  247. clean_file_names
  248.  
  249. # Prompt the user to continue or quit?
  250. prompt_continue_or_quit
  251.  
  252. echo "Starting conversion process..." | tee -a "$log_file"
  253.  
  254. # -----------------------------
  255. #    Audio Encoder
  256. # -----------------------------
  257.  
  258. width=$(tput cols)
  259.  
  260. # Function to check the log file for "Killed" message
  261. check_for_killed_message() {
  262.     if grep -q " Killed     " "$log_file"; then
  263.         echo "$(date '+%Y-%m-%d %H:%M:%S') Error: Process was killed. Check log file for details." | tee -a "$log_file"
  264.         return 1
  265.     fi
  266.     return 0
  267. }
  268.  
  269. # Function to process audio files
  270. process_audio() {
  271.     local audio="$1"
  272.     local audio_echo=$(echo "$audio" | sed 's|/data/data/com.termux/files/home|/home|g')
  273.     local relative_path="${audio#$video_drop_dir/}"
  274.     local dir_path=$(dirname "$relative_path")
  275.     local base_name=$(basename "$relative_path" | tr -cd '[:alnum:]._ -')
  276.     local output_dir="$output_dir_base/$dir_path"
  277.     local output_file="$output_dir/${base_name}_converted.opus"
  278.     local temp_output_file="$output_file.tmp"
  279.  
  280.     mkdir -p "$output_dir"  # Create output directory
  281.  
  282.     echo "$(date '+%Y-%m-%d %H:%M:%S') Processing $audio to $output_file" | tee -a "$log_file"
  283.  
  284.     # Construct the FFmpeg command for audio processing
  285.     local ffmpeg_command="ffmpeg -nostdin -loglevel error -stats -stats_period 1 -y -i \"$audio\" -c:a libopus -b:a ${avg_audio_bitrate}k -vbr on -ac 2 -af \"loudnorm=I=-23:LRA=7:TP=-2\" -f opus \"$temp_output_file\""
  286.  
  287.     echo "$ffmpeg_command" | tee -a "$log_file"
  288.  
  289.     # Execute the FFmpeg command
  290.     eval $ffmpeg_command 2>&1 | tee -a "$log_file"
  291.  
  292.     # Check for "Killed" message in the log file
  293.     if ! check_for_killed_message; then
  294.         echo "$(date '+%Y-%m-%d %H:%M:%S') Error: Process was killed. Exiting." | tee -a "$log_file"
  295.         exit 1
  296.     fi
  297.  
  298.     if [ $? -eq 0 ]; then
  299.         mv "$temp_output_file" "$output_file"  # Rename the temporary file to the final output file
  300.         mkdir -p "$video_processing_dir/$dir_path"  # Create processing directory
  301.         mv "$audio" "$video_processing_dir/$relative_path"
  302.         echo ""
  303.         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
  304.     else
  305.         echo ""
  306.         echo "$(date '+%Y-%m-%d %H:%M:%S') Error processing \"$audio\". Check log file for details." | tee -a "$log_file"
  307.         exit 1
  308.     fi
  309. }
  310.  
  311. # ------------------------------
  312. #      Video Encoder
  313. # ------------------------------
  314.  
  315. width=$(tput cols)
  316.  
  317. # Function to check the log file for "Killed" message
  318. check_for_killed_message() {
  319.     if grep -q " Killed     " "$log_file"; then
  320.         echo "$(date '+%Y-%m-%d %H:%M:%S') Error: Process was killed. Check log file for details." | tee -a "$log_file" | fmt -w $width
  321.         exit 1
  322.     fi
  323. }
  324.  
  325. process_video() {
  326.     local video="$1"
  327.     local video_echo=$(echo "$video" | sed 's|/data/data/com.termux/files/home|.../home|g')
  328.     local relative_path="${video#$video_drop_dir/}"
  329.     local dir_path=$(dirname "$relative_path")
  330.     local base_name=$(basename "$relative_path" | tr -cd '[:alnum:]._ -')
  331.     local output_dir="$output_dir_base/$dir_path"
  332.     local output_file="$output_dir/${base_name}_converted.mkv"
  333.     local scale_filter=""
  334.  
  335.     # Get input video resolution
  336.     input_resolution=$(ffprobe -v error -select_streams v:0 -show_entries stream=height -of csv=p=0 "$video" | tr -d '[:space:],')
  337.  
  338.     if [ -n "$resolution" ]; then
  339.         if [ "$input_resolution" -gt "$resolution" ]; then
  340.             scale_filter="scale=-2:$resolution:flags=lanczos"
  341.             echo "Input resolution ($input_resolution) is higher than user-defined resolution ($resolution). Using user-defined resolution." | tee -a "$log_file"
  342.         else
  343.             echo "Input resolution ($input_resolution) is lower or equal to user-defined resolution ($resolution). Keeping original resolution." | tee -a "$log_file"
  344.         fi
  345.     else
  346.         echo "Resolution set to: original" | tee -a "$log_file"
  347.     fi
  348.  
  349.     mkdir -p "$output_dir"  # Create output directory
  350.  
  351.     echo "$(date '+%Y-%m-%d %H:%M:%S') Processing $video to $output_file" | tee -a "$log_file"
  352.  
  353.     # Get the frame rate of the input video
  354.     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)
  355.  
  356.     # Define common frame rates
  357.     common_fps=(23.976 24 25 29.97 30 50 59.94 60)
  358.  
  359.     # Function to find the nearest valid frame rate
  360.     nearest_fps() {
  361.         local fps=$1
  362.         local nearest=${common_fps[0]}
  363.         local min_diff=$(echo "scale=5; $fps - ${common_fps[0]}" | bc | awk '{print ($1 >= 0) ? $1 : -$1}')
  364.         for rate in "${common_fps[@]}"; do
  365.             local diff=$(echo "scale=5; $fps - $rate" | bc | awk '{print ($1 >= 0) ? $1 : -$1}')
  366.             if (( $(echo "$diff < $min_diff" | bc -l) )); then
  367.                 min_diff=$diff
  368.                 nearest=$rate
  369.             fi
  370.         done
  371.         echo $nearest
  372.     }
  373.  
  374.     # Round the frame rate to the nearest valid frame rate
  375.     rounded_fps=$(nearest_fps $input_fps)
  376.  
  377.     # Determine the lower frame rate
  378.     if (( $(echo "$rounded_fps > $output_fps" | bc -l) )); then
  379.         final_fps=$output_fps
  380.     else
  381.         final_fps=$rounded_fps
  382.     fi
  383.  
  384. # Set the initial video filter option
  385. video_filter_option="${scale_filter},fps=$final_fps"
  386.  
  387. # Detect the pixel format using ffprobe
  388. input_file="$video"
  389. pix_fmt=$(ffprobe -v repeat+level+error -select_streams v:0 -show_entries stream=pix_fmt -of default=noprint_wrappers=1:nokey=1 "$input_file" | awk 'NR==1{print $1}')
  390.  
  391. echo "Pixel format: $pix_fmt"
  392.  
  393. # Validate the pixel format
  394. valid_pix_fmt=$(ffmpeg -pix_fmts | grep -w "$pix_fmt")
  395.  
  396. # Check if 10-bit encoding is selected
  397. if [[ "$pix_fmt" == *"10le"* || "$pix_fmt" == *"10be"* ]]; then
  398.     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"
  399. fi
  400.  
  401. # Check if the video is progressive or interlaced
  402. field_order=$(ffprobe -v error -select_streams v:0 -show_entries stream=field_order -of default=noprint_wrappers=1:nokey=1 "$input_file")
  403.  
  404. # Apply yadif filter if the video is interlaced or if field_order is unknown
  405. if [ "$field_order" == "progressive" ]; then
  406.     if [ -n "$scale_filter" ]; then
  407.         video_filter_option="${scale_filter},fps=$final_fps"
  408.     else
  409.         video_filter_option="fps=$final_fps"
  410.     fi
  411. else
  412.     if [ -n "$scale_filter" ]; then
  413.         video_filter_option="yadif=2,${scale_filter},fps=$final_fps"
  414.     else
  415.         video_filter_option="yadif=2,fps=$final_fps"
  416.     fi
  417. fi
  418.  
  419. # Add noise to the output video to simulate film grain.
  420. video_filter_option="$video_filter_option,noise=alls=2:allf=t+u"
  421.  
  422. # Define a variable for probe size and analyze duration
  423. probe_analyze_opts="-probesize 2147483647 -analyzeduration 2147483647"
  424.  
  425. # Detect subtitle codecs and convert unsupported ones
  426. subtitle_codecs=$(ffprobe -v error $probe_analyze_opts -select_streams s -show_entries stream=codec_name -of csv=p=0 "$input_file")
  427. subtitle_map=""
  428. if [ -n "$subtitle_codecs" ]; then
  429.     subtitle_map="-map 0:s"  # Include all subtitle streams
  430.     i=0
  431.     while read -r codec; do
  432.         case "$codec" in
  433.             # Text-based subtitles to be copied directly
  434.             srt)
  435.                 subtitle_map="$subtitle_map -c:s:$i copy"
  436.                 ;;
  437.             # Other text-based subtitles to be converted to SRT
  438.             ass|ssa|webvtt|eia_608|eia_708|scc|sami|ttml|smi|teletext|mov_text|microdvd|subviewer)
  439.                 subtitle_map="$subtitle_map -c:s:$i srt"
  440.                 ;;
  441.             # Bitmap-based subtitles to be converted to DVD subtitles
  442.             dvdsub|pgs|vobsub|hdmv_pgs_subtitle|dvd_subtitle)
  443.                 subtitle_map="$subtitle_map -c:s:$i dvdsub"
  444.                 ;;
  445.             # Copy other compatible subtitles
  446.             *)
  447.                 subtitle_map="$subtitle_map -c:s:$i copy"
  448.                 ;;
  449.         esac
  450.         i=$((i + 1))
  451.     done <<< "$subtitle_codecs"
  452. else
  453.     echo "No subtitle streams detected." | tee -a "$log_file"
  454. fi
  455.  
  456. # Combine common and custom FFmpeg options
  457. combined_ffmpeg_options="-nostdin -loglevel error -stats -stats_period 5 $probe_analyze_opts -y -fix_sub_duration -i \"$video\" -map 0:v:0 -map 0:a:0 -map_chapters 0 $ffmpeg_custom_options"
  458.  
  459. # Construct the FFmpeg command
  460. local ffmpeg_command
  461. if [ -n "$valid_pix_fmt" ]; then
  462.     if [ -n "$subtitle_map" ]; then
  463.         ffmpeg_command="ffmpeg $combined_ffmpeg_options -vf \"$video_filter_option\" -pix_fmt $pix_fmt $subtitle_map"
  464.     else
  465.         ffmpeg_command="ffmpeg $combined_ffmpeg_options -vf \"$video_filter_option\" -pix_fmt $pix_fmt"
  466.     fi
  467. else
  468.     if [ -n "$subtitle_map" ]; then
  469.         ffmpeg_command="ffmpeg $combined_ffmpeg_options -vf \"$video_filter_option\" $subtitle_map"
  470.     else
  471.         ffmpeg_command="ffmpeg $combined_ffmpeg_options -vf \"$video_filter_option\""
  472.     fi
  473. fi
  474.  
  475. # Ensure all subtitle streams are marked as "default: off"
  476. subtitle_streams=$(ffprobe -v error $probe_analyze_opts -select_streams s -show_entries stream=index -of csv=p=0 "$input_file")
  477. if [ -n "$subtitle_streams" ]; then
  478.     for stream_index in $subtitle_streams; do
  479.         ffmpeg_command="$ffmpeg_command -disposition:s:$stream_index 0"
  480.     done
  481. fi
  482.  
  483. # Add the output file name at the end
  484. ffmpeg_command="$ffmpeg_command \"$output_file\""
  485.  
  486. echo "FFmpeg command: $ffmpeg_command" | tee -a "$log_file"
  487.  
  488. # Execute the FFmpeg command
  489. if ! eval $ffmpeg_command 2>&1 | tee -a "$log_file"; then
  490.     echo "FFmpeg command failed. Check the log for details." | tee -a "$log_file"
  491.     exit 1
  492. fi
  493.  
  494.     # Check for "Killed" message in the log file
  495.     check_for_killed_message
  496.  
  497.    if [ $? -eq 0 ]; then
  498.         mkdir -p "$video_processing_dir/$dir_path"  # Create processing directory
  499.         mv "$video" "$video_processing_dir/$relative_path"
  500.         echo ""
  501.         echo "$(date '+%Y-%m-%d %H:%M:%S') Complete.  Your original files are in $video_processing_dir_echo.  Your new files are in $output_dir_base_echo" | tee -a "$log_file" | fmt -w $width
  502.     else
  503.         echo ""
  504.         echo "$(date '+%Y-%m-%d %H:%M:%S') Error processing \"$video\". Check log file for details." | tee -a "$log_file"
  505.         exit 1
  506.     fi
  507. }
  508.  
  509. # --------------------------------------
  510. #    Start Batch Encoding
  511. # --------------------------------------
  512.  
  513. width=$(tput cols)
  514.  
  515. stop_processing=false
  516.  
  517. # Process each file found
  518. eval "find \"$video_drop_dir\" -type f \( $filetypes \)" | while read -r file; do
  519.  
  520. # Function to handle SIGINT (Ctrl+C)
  521. handle_sigint() {
  522.     echo ""
  523.     echo "Caught SIGINT (Ctrl+C). Exiting immediately." | fmt -w $width
  524.     stop_processing=true
  525.     exit 1  # Exit immediately without performing cleanup
  526. }
  527.  
  528. # Trap SIGINT and call the handle_sigint function
  529. trap handle_sigint SIGINT
  530.  
  531.     if [ "$stop_processing" = true ]; then
  532.         echo "Stopping processing due to SIGINT."
  533.         exit 1
  534.     fi
  535.  
  536.     case "$file" in
  537.         *.mp3|*.wav|*.flac|*.aac|*.ogg|*.m4a|*.opus)
  538.             process_audio "$file" || exit 1
  539.             ;;
  540.         *.mp4|*.mkv|*.avi|*.mov|*.flv|*.wmv|*.webm|*.mts)
  541.             process_video "$file" || exit 1
  542.             ;;
  543.     esac
  544.  
  545.     # Remove the relative path folder if it's empty
  546.     rmdir "$(dirname "$file")" --ignore-fail-on-non-empty
  547. done
  548.  
  549. # -----------------------------
  550. #     Finishing Up
  551. # -----------------------------
  552.  
  553. width=$(tput cols)
  554.  
  555. # final output message
  556. echo ""
  557. 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
  558. exit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement