Created
March 26, 2025 18:49
-
-
Save ariunbayar/163dfd98400baa00beb12b1a13bcc3a6 to your computer and use it in GitHub Desktop.
Joins same day video by date. Original files are archived into a `processed` dir.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # --- Configuration --- | |
| # Video encoding options (same as your example) | |
| VCODEC="libx264" | |
| CRF="23" | |
| PRESET="medium" | |
| ACODEC="aac" | |
| ABITRATE="192k" | |
| OUTPUT_EXT="mp4" # Output container format extension | |
| # Directory to move processed source files | |
| PROCESSED_DIR="processed" | |
| # --- Script Logic --- | |
| # Create the target directory for processed files if it doesn't exist | |
| mkdir -p "$PROCESSED_DIR" | |
| if [ ! -d "$PROCESSED_DIR" ]; then | |
| echo "Error: Could not create directory '$PROCESSED_DIR'." | |
| exit 1 | |
| fi | |
| echo "Scanning for unique dates in MPG filenames..." | |
| # Find unique dates (YYYY-MM-DD) from filenames matching the pattern | |
| # Using find for safety, extracting date with cut, sorting uniquely | |
| # Using process substitution and mapfile (or readarray) to store dates. | |
| mapfile -t unique_dates < <(find . -maxdepth 1 -name '????-??-??_????_M*.MPG' -printf '%f\n' | cut -c1-10 | sort -u) | |
| # Check if any dates were found | |
| if [ ${#unique_dates[@]} -eq 0 ]; then | |
| echo "No MPG files found matching the pattern YYYY-MM-DD_HHMM_M*.MPG in the current directory." | |
| exit 0 | |
| fi | |
| echo "Found dates to process: ${unique_dates[*]}" | |
| echo "Starting processing..." | |
| echo "--------------------" | |
| # Loop through each unique date | |
| for date in "${unique_dates[@]}"; do | |
| echo "Processing date: $date" | |
| # Find and sort all .MPG files for the current date | |
| # Using find for safety and storing results in an array using mapfile | |
| mapfile -t files_for_date < <(find . -maxdepth 1 -name "${date}_????_M*.MPG" -printf '%f\n' | sort) | |
| # Check if files were actually found for this date (should always be true here, but good practice) | |
| if [ ${#files_for_date[@]} -eq 0 ]; then | |
| echo " Warning: No files found for date $date during processing loop (unexpected)." | |
| continue | |
| fi | |
| echo " Files found for $date: ${files_for_date[*]}" | |
| # Construct the ffmpeg concat input string (e.g., file1.MPG|file2.MPG) | |
| # Using IFS and array expansion for safe joining | |
| input_concat_string=$(IFS='|'; echo "${files_for_date[*]}") | |
| # Determine the output filename: Use the date and the timestamp from the *first* sorted file | |
| # Removes the _M* part and changes extension, e.g., 2014-09-08_0907.mp4 | |
| first_file_basename="${files_for_date[0]}" | |
| # Using sed to replace the last underscore segment and extension | |
| output_name=$(echo "$first_file_basename" | sed "s/_[^_]*\.MPG$/.${OUTPUT_EXT}/") | |
| echo " Output file will be: $output_name" | |
| # Check if output file already exists to prevent accidental overwrite or re-processing | |
| if [ -f "$output_name" ]; then | |
| echo " SKIPPING: Output file '$output_name' already exists." | |
| # Optional: Decide if you want to move source files even if output exists | |
| # echo " Moving source files for skipped date..." | |
| # for file in "${files_for_date[@]}"; do mv -- "$file" "$PROCESSED_DIR/"; done | |
| echo "--------------------" | |
| continue | |
| fi | |
| # Prepare the ffmpeg command arguments in an array for robustness | |
| ffmpeg_cmd=( | |
| ffmpeg | |
| -i "concat:$input_concat_string" | |
| -c:v "$VCODEC" | |
| -crf "$CRF" | |
| -preset "$PRESET" | |
| -c:a "$ACODEC" | |
| -b:a "$ABITRATE" | |
| # Optional: Add -map 0 if you encounter channel mapping issues | |
| "$output_name" | |
| ) | |
| echo " Executing FFmpeg..." | |
| # Use "${ffmpeg_cmd[@]}" to correctly handle arguments with spaces if any | |
| if "${ffmpeg_cmd[@]}"; then | |
| echo " SUCCESS: FFmpeg finished for $date." | |
| echo " Moving original files to '$PROCESSED_DIR/'..." | |
| # Move source files to the 'processed' directory *only on success* | |
| for file in "${files_for_date[@]}"; do | |
| # Use -- to handle filenames that might start with a dash | |
| mv -- "$file" "$PROCESSED_DIR/" | |
| done | |
| echo " Moved ${#files_for_date[@]} files for $date." | |
| else | |
| echo " FAILURE: FFmpeg failed for $date. Original files were NOT moved." | |
| # Optional: You might want to delete the potentially incomplete output file on failure | |
| # rm -f "$output_name" | |
| fi | |
| echo "--------------------" | |
| done | |
| echo "All processing finished." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment