#!/bin/bash
# Desc: Extracts audio from video files
# Usage: bk_export_audio.sh [input_dir] ([output_dir])
-# Version: 0.0.1
+# Version: 0.1.2
+# Depends: bash 5.1.16, GNU Coreutils (8.32)
+# Plumbing
+max_jobs="$(nproc --all)"; # max parallel audio conversion jobs
declare -Ag appRollCall # Associative array for storing app status
declare -Ag fileRollCall # Associative array for storing file status
declare -Ag dirRollCall # Associative array for storing dir status
# arg2: desired output file extension
# arg3: output dir path
# Output: audio file at path [arg3]/[arg1].[arg2]
- local file_in file_in_ext dir_out file_in_basename;
+ local file_in file_in_ext dir_out file_in_basename path_out;
file_in="$1";
file_in_ext="$2";
dir_out="$3";
+ file_in_basename="$(basename "$file_in")";
+ path_out="$dir_out"/"$file_in_basename"."$file_in_ext";
+
+ # Skip if output file already exists.
+ if [[ -f "$path_out" ]]; then return 1; fi;
# Extract audio file
- file_in_basename="$(basename "$file_in")";
- ffmpeg -i "$file_in" -vn -acodec copy "$dir_out"/"$file_in_basename"."$file_in_ext";
-}
+ ffmpeg -i "$file_in" -vn -acodec copy "$path_out";
+} # Create audio file from video file
+count_jobs() {
+ # Desc: Count and return total number of jobs
+ # Usage: count_jobs
+ # Input: None.
+ # Output: stdout integer number of jobs
+ # Depends: Bash 5.1.16
+ # Example: while [[$(count_jobs) -gt 0]]; do echo "Working..."; sleep 1; done;
+ # Version: 0.0.1
+
+ local job_count;
+ job_count="$(jobs -r | wc -l | tr -d ' ' )";
+ #yell "DEBUG:job_count:$job_count";
+ if [[ -z $job_count ]]; then job_count="0"; fi;
+ echo "$job_count";
+}; # Return number of background jobs
+job() {
+ # Input: arg1: file : file to check and, if audio, export
+ # arg2: dir_out: output dir
+ local file dir_out;
+ file="$1";
+ dir_out="$2";
+ aud_format="$(get_audio_format "$file")"; # Get audio format as file extension string
+ file_basename="$(basename "$file")"; # Get basename for debugging
+ yell "DEBUG:file_basename:$file_basename";
+ yell "DEBUG:aud_format:$aud_format";
+ yell "DEBUG:";
+ # Ignore files that return blank $aud_format
+ if [[ -z $aud_format ]]; then
+ yell "DEBUG:Not an audio file:$file";
+ return 1;
+ fi;
+
+ # Convert video to audio
+ extract_audio_file "$file" "$aud_format" "$dir_out";
+}; # One file check and extraction job
main() {
+ # Depends: yell(), die(), try()
+ # checkapp(), checkfile(), checkdir(), displayMissing(), showUsage(),
+ # extract_audio_file() get_audio_format()
+ # BK-2020-03: count_jobs v0.0.1
script_pwd="$(pwd)";
dir_in="$1";
dir_out="$2";
fi;
# Check apps, dirs
- checkapp ffmpeg ffprobe date;
+ checkapp ffmpeg ffprobe date nproc;
displayMissing;
if ! checkdir "$dir_in"; then
# Do work
yell "DEBUG:dir_in:$dir_in":
yell "DEBUG:dir_out:$dir_out";
- for file in "$dir_in"/*; do
- aud_format="$(get_audio_format "$file")"; # Get audio format as file extension string
- file_basename="$(basename "$file")"; # Get basename for debugging
- yell "DEBUG:file_basename:$file_basename";
- yell "DEBUG:aud_format:$aud_format";
- yell "DEBUG:";
+ while read -r file; do
+ yell "DEBUG:count_jobs:$(count_jobs)";
+ while [[ "$(count_jobs)" -ge $max_jobs ]]; do sleep 0.1; done; # limit jobs
+ job "$file" "$dir_out" &
+ done < <(find "$dir_in" -type f);
- # Ignore files that return blank $aud_format
- if [[ -z $aud_format ]]; then
- yell "DEBUG:Not an audio file:$file";
- continue;
- fi;
-
- extract_audio_file "$file" "$aud_format" "$dir_out";
- done;
-} # main program
+ # Announce completion
+ while [[ "$(count_jobs)" -gt 0 ]]; do sleep 1; done;
+ printf "\n" 1>&2; yell "STATUS:Done.";
+}; # main program
+#export -f get_audio_format count_jobs extract_audio_file;
main "$@";
# Author: Steven Baltaktei Sandoval