feat(unitproc/bk_export_audio.sh):Run conversion jobs in parallel
authorSteven Baltakatei Sandoval <baltakatei@gmail.com>
Tue, 11 Apr 2023 16:27:39 +0000 (16:27 +0000)
committerSteven Baltakatei Sandoval <baltakatei@gmail.com>
Tue, 11 Apr 2023 16:27:39 +0000 (16:27 +0000)
- Note: Uses `nproc` from GNU Coreutils 8.32

unitproc/bk_export_audio.sh

index 7befc0b2a2c6fa4b1408ae7f771a456508016f7b..1100811e3a7515016b7bc3841394a722f955a1c0 100755 (executable)
@@ -1,8 +1,11 @@
 #!/bin/bash
 # Desc: Extracts audio from video files
 # Usage: bk_export_audio.sh [input_dir] ([output_dir])
-# Version: 0.0.2
+# Version: 0.1.0
+# 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
@@ -232,8 +235,47 @@ extract_audio_file() {
     file_in_basename="$(basename "$file_in")";    
     ffmpeg -i "$file_in" -vn -acodec copy "$dir_out"/"$file_in_basename"."$file_in_ext";
 } # 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";
@@ -245,7 +287,7 @@ main() {
     fi;
 
     # Check apps, dirs
-    checkapp ffmpeg ffprobe date;
+    checkapp ffmpeg ffprobe date nproc;
     displayMissing;
 
     if ! checkdir "$dir_in"; then
@@ -264,22 +306,17 @@ main() {
     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:";
-
-       # 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";
+        yell "DEBUG:count_jobs:$(count_jobs)";
+        while [[ "$(count_jobs)" -ge $max_jobs ]]; do sleep 0.1; done; # limit jobs        
+        job "$file" "$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