<p>All that you need is to put an &amp; at the end of the ffmpeg command line. This will make the ffmpeg process to run in background, allowing it to be executed simultaneously with other processes.</p>

<pre><code>#!/bin bash
# add this code to a file called encode or whatever you want
# make it executable: chmod ugo+x encode
# and you are ready to run: ./encode

for i in *.mov; do 
    name=``echo $i | cut -d'.' -f1``; 
    echo $name; 
    TIMECODE=$(ffprobe "$i" -v error -show_entries stream_tags=timecode -of default=noprint_wrappers=1:nokey=1 | awk -F: '{ print $1 "\\:" $2 "\\:" $3 "\\:" $4 }') ;
    ffmpeg -i "$i" -vf "trim=start_frame=192,setpts=PTS-STARTPTS,scale=1280:-1:force_original_aspect_ratio=decrease,drawtext=fontfile=/usr/share/fonts/truetype/droid/DroidSansMono.ttf: fontsize=28: timecode='00\:00\:00\:00': r=24: x=(w-tw)/2: y=25: fontcolor=white: box=1: boxcolor=0x00000099" -threads 4 -c:v mpeg1video -b:v 5000k -af "atrim=start=8,asetpts=PTS-STARTPTS" -c:a libmp3lame -b:a 192k "${name}_mpeg1.mpeg" &amp;;

    # limit ffmpeg processes to 5
    while [$(ps | grep ffmpeg | wc -l) -eq 5]; do
        echo "ffmpeg queue is full, waiting...";
        # amount of seconds to wait till we check again
        sleep 10;
    done
done;
</code></pre>

CC BY-SA 3.0
2017-05-22T15:52:13.190Z
Will this start a process for each loop member at once? If yes, is there a way to limit the number?
Gyan
CC BY-SA 3.0
2017-05-22T16:46:05.973Z
Yes @Mulvya, added a loop that limits simultaneous ffmpeg processes to 5, you can change that on the -eq 5 to the number that best fit your needs. Important to notice that it will consider any process that has 'ffmpeg' in its name, but that shouldn't be a problem.
Gustavo Jantsch
CC BY-SA 3.0
2017-05-22T13:08:05.753Z
2017-05-22T16:53:55.023Z
2017-05-22T16:53:55.023Z
Gustavo Jantsch
<h3>Put it into a flexible wrapper script</h3>

<p>There's a few benefits to doing it this way, for example, the provided script;</p>

<ol>
<li>Uses <code>find</code> and array variables to handle complex and crazy filenames, and the process management</li>
<li>Records the process ID's as it spawns <code>ffmpeg</code> and then periodically checks them if they are active</li>
<li>If a file already exists in it's desired output form (i.e. file_mpeg1.mpeg), that file is skipped; this prevents saying running a loop of 100 files, failing for some reason after 90 files, and then re-running the whole thing from the start.  (there is however no check at this stage to see if the existing file was complete or not.  This goes a bit deeper into error checking / maybe a length compare based on original / an ffprobe, etc... )</li>
<li>The flexible template allows you easily manipulate the flow.</li>
</ol>

<p>I tested it to process 4 random files downloaded off youtube:</p>

<p><a href="https://i.sstatic.net/2R9q6.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/2R9q6.png" alt="enter image description here"></a></p>

<p>As you can see it handles silly filenames quite well.</p>

<p>Here is the wrapper script based on your commands:</p>

<p>The syntax is: <code>./scriptname.sh [ext] [maxprocesses]</code></p>

<ul>
<li>So, to look to look for *.mov files and run 5 processes:

<ul>
<li>If the script name was <code>script.sh</code>, then you'd run 

<ul>
<li><code>./script.sh mov 5</code></li>
</ul></li>
</ul></li>
</ul>

<p><strong>Wrapper Script:</strong></p>

<pre><code>#!/usr/bin/env bash

ffprocess () {
    file="$1"
    output="$2" 
    TIMECODE=$(ffprobe "$file" -v error -show_entries stream_tags=timecode -of default=noprint_wrappers=1:nokey=1 | awk -F: '{ print $1 "\\:" $2 "\\:" $3 "\\:" $4 }')
    ffmpeg -i "$file" \
    -vf "trim=start_frame=192,setpts=PTS-STARTPTS,scale=1280:-1:force_original_aspect_ratio=decrease,drawtext=fontfile=/usr/share/fonts/truetype/droid/DroidSansMono.ttf: fontsize=28: timecode='00\:00\:00\:00': r=24: x=(w-tw)/2: y=25: fontcolor=white: box=1: boxcolor=0x00000099" \
    -threads 4 \
    -c:v mpeg1video \
    -b:v 5000k \
    -af "atrim=start=8,asetpts=PTS-STARTPTS" \
    -c:a libmp3lame -b:a 192k \
    "${output}"
}

#This function gets called when a process is no longer valid and needs removing from the array

removeps () {
    trtmp=()
    for tmpps in "${ffpsid[@]}"
    do
        [[ $tmpps != "$1" ]] &amp;&amp; trtmp+=($tmpps)
    done
    ffpsid=("${trtmp[@]}")
    unset trtmp
    return
}

#Checks to see if each process is still active
checkffpsid () {
    for ffps in "${ffpsid[@]}" 
    do 
    ps -p $ffps &gt; /dev/null || removeps "$ffps"
done

}


if [[ "$#" -lt 2 ]]; then echo -e "Usage: $0 [ext] [maxproc]\ni.e. $0 .mov 5" ; exit ; fi

ext="$1"
maxproc="$2"
find . -maxdepth 1 -iname "*.$ext" &gt; inputlist.txt   # Find files with ext specified
IFS=$'\n' read -rd '' -a filelist &lt;&lt;&lt;"$(cat inputlist.txt)" 
for file in "${filelist[@]}"
    do
    name=$(basename "$file")
    name="${name%.*}"                                  # remove ext for name var
    outname="${name}_mpeg1.mpeg"                       # Set output name
    checkffpsid 
    if [ -f "$outname" ]
        then 
        echo "$outname" already exists, skipping ...
    else
        until [[ "${#ffpsid[@]}" -le "$maxproc" ]]
        do
            checkffpsid
            sleep 5
        done
        ffprocess "$file" "$outname" &amp; ffpsid+=("$!") 
    fi
done
</code></pre>

<hr>

<p><strong>Just a couple notes</strong></p>

<ol>
<li>Your "$TIMECODE" variable never gets used ... This is as per your original script.</li>
<li>You're better off letting <code>ffmpeg</code> manage its own threads by passing <code>-threads 0</code> instead of 4</li>
</ol>

CC BY-SA 3.0
2017-05-23T01:41:07.133Z
2017-05-23T02:14:44.053Z
2017-05-23T02:14:44.053Z
hmedia1
<p>I have a ffmpeg command that will happily process all video files in a folder one by one, but how can i make it process them simultaneously?</p>

<p>here's my current command:</p>

<p><code>for i in *.mov; do name=``echo $i | cut -d'.' -f1``; echo $name; TIMECODE=$(ffprobe "$i" -v error -show_entries stream_tags=timecode -of default=noprint_wrappers=1:nokey=1 | awk -F: '{ print $1 "\\:" $2 "\\:" $3 "\\:" $4 }') ; ffmpeg -i "$i" -vf "trim=start_frame=192,setpts=PTS-STARTPTS,scale=1280:-1:force_original_aspect_ratio=decrease,drawtext=fontfile=/usr/share/fonts/truetype/droid/DroidSansMono.ttf: fontsize=28: timecode='00\:00\:00\:00': r=24: x=(w-tw)/2: y=25: fontcolor=white: box=1: boxcolor=0x00000099" -threads 4 -c:v mpeg1video -b:v 5000k -af "atrim=start=8,asetpts=PTS-STARTPTS" -c:a libmp3lame -b:a 192k "${name}_mpeg1.mpeg"</code></p>

<ffmpeg>
FFMPEG Batch Processing
Mells
# FFMPEG Batch Processing

(Asked by: username_0 on 2017-05-22)

I have a ffmpeg command that will happily process all video files in a folder one by one, but how can i make it process them simultaneously?

here's my current command:

`for i in *.mov; do name=``echo $i | cut -d'.' -f1``; echo $name; TIMECODE=$(ffprobe "$i" -v error -show_entries stream_tags=timecode -of default=noprint_wrappers=1:nokey=1 | awk -F: '{ print $1 "\\:" $2 "\\:" $3 "\\:" $4 }') ; ffmpeg -i "$i" -vf "trim=start_frame=192,setpts=PTS-STARTPTS,scale=1280:-1:force_original_aspect_ratio=decrease,drawtext=fontfile=/usr/share/fonts/truetype/droid/DroidSansMono.ttf: fontsize=28: timecode='00\:00\:00\:00': r=24: x=(w-tw)/2: y=25: fontcolor=white: box=1: boxcolor=0x00000099" -threads 4 -c:v mpeg1video -b:v 5000k -af "atrim=start=8,asetpts=PTS-STARTPTS" -c:a libmp3lame -b:a 192k "${name}_mpeg1.mpeg"`

**Tags:** ffmpeg


---

## 2 answers

### Answer by username_1 on 2017-05-22. Score: 1

All that you need is to put an & at the end of the ffmpeg command line. This will make the ffmpeg process to run in background, allowing it to be executed simultaneously with other processes.
#!/bin bash
# add this code to a file called encode or whatever you want
# make it executable: chmod ugo+x encode
# and you are ready to run: ./encode

for i in *.mov; do 
    name=``echo $i | cut -d'.' -f1``; 
    echo $name; 
    TIMECODE=$(ffprobe "$i" -v error -show_entries stream_tags=timecode -of default=noprint_wrappers=1:nokey=1 | awk -F: '{ print $1 "\\:" $2 "\\:" $3 "\\:" $4 }') ;
    ffmpeg -i "$i" -vf "trim=start_frame=192,setpts=PTS-STARTPTS,scale=1280:-1:force_original_aspect_ratio=decrease,drawtext=fontfile=/usr/share/fonts/truetype/droid/DroidSansMono.ttf: fontsize=28: timecode='00\:00\:00\:00': r=24: x=(w-tw)/2: y=25: fontcolor=white: box=1: boxcolor=0x00000099" -threads 4 -c:v mpeg1video -b:v 5000k -af "atrim=start=8,asetpts=PTS-STARTPTS" -c:a libmp3lame -b:a 192k "${name}_mpeg1.mpeg" &;

    # limit ffmpeg processes to 5
    while [$(ps | grep ffmpeg | wc -l) -eq 5]; do
        echo "ffmpeg queue is full, waiting...";
        # amount of seconds to wait till we check again
        sleep 10;
    done
done;

> **Comments:**
> **username_2**: Will this start a process for each loop member at once? If yes, is there a way to limit the number?  
> **username_1**: Yes @Mulvya, added a loop that limits simultaneous ffmpeg processes to 5, you can change that on the -eq 5 to the number that best fit your needs. Important to notice that it will consider any process that has 'ffmpeg' in its name, but that shouldn't be a problem.  

---

### Answer by username_3 on 2017-05-23. Score: 0

Put it into a flexible wrapper script
There's a few benefits to doing it this way, for example, the provided script;

Uses find and array variables to handle complex and crazy filenames, and the process management
Records the process ID's as it spawns ffmpeg and then periodically checks them if they are active
If a file already exists in it's desired output form (i.e. file_mpeg1.mpeg), that file is skipped; this prevents saying running a loop of 100 files, failing for some reason after 90 files, and then re-running the whole thing from the start.  (there is however no check at this stage to see if the existing file was complete or not.  This goes a bit deeper into error checking / maybe a length compare based on original / an ffprobe, etc... )
The flexible template allows you easily manipulate the flow.

I tested it to process 4 random files downloaded off youtube:

As you can see it handles silly filenames quite well.
Here is the wrapper script based on your commands:
The syntax is: ./scriptname.sh [ext] [maxprocesses]

So, to look to look for *.mov files and run 5 processes:


If the script name was script.sh, then you'd run 


./script.sh mov 5



Wrapper Script:
#!/usr/bin/env bash

ffprocess () {
    file="$1"
    output="$2" 
    TIMECODE=$(ffprobe "$file" -v error -show_entries stream_tags=timecode -of default=noprint_wrappers=1:nokey=1 | awk -F: '{ print $1 "\\:" $2 "\\:" $3 "\\:" $4 }')
    ffmpeg -i "$file" \
    -vf "trim=start_frame=192,setpts=PTS-STARTPTS,scale=1280:-1:force_original_aspect_ratio=decrease,drawtext=fontfile=/usr/share/fonts/truetype/droid/DroidSansMono.ttf: fontsize=28: timecode='00\:00\:00\:00': r=24: x=(w-tw)/2: y=25: fontcolor=white: box=1: boxcolor=0x00000099" \
    -threads 4 \
    -c:v mpeg1video \
    -b:v 5000k \
    -af "atrim=start=8,asetpts=PTS-STARTPTS" \
    -c:a libmp3lame -b:a 192k \
    "${output}"
}

#This function gets called when a process is no longer valid and needs removing from the array

removeps () {
    trtmp=()
    for tmpps in "${ffpsid[@]}"
    do
        [[ $tmpps != "$1" ]] && trtmp+=($tmpps)
    done
    ffpsid=("${trtmp[@]}")
    unset trtmp
    return
}

#Checks to see if each process is still active
checkffpsid () {
    for ffps in "${ffpsid[@]}" 
    do 
    ps -p $ffps > /dev/null || removeps "$ffps"
done

}


if [[ "$#" -lt 2 ]]; then echo -e "Usage: $0 [ext] [maxproc]\ni.e. $0 .mov 5" ; exit ; fi

ext="$1"
maxproc="$2"
find . -maxdepth 1 -iname "*.$ext" > inputlist.txt   # Find files with ext specified
IFS=$'\n' read -rd '' -a filelist <<<"$(cat inputlist.txt)" 
for file in "${filelist[@]}"
    do
    name=$(basename "$file")
    name="${name%.*}"                                  # remove ext for name var
    outname="${name}_mpeg1.mpeg"                       # Set output name
    checkffpsid 
    if [ -f "$outname" ]
        then 
        echo "$outname" already exists, skipping ...
    else
        until [[ "${#ffpsid[@]}" -le "$maxproc" ]]
        do
            checkffpsid
            sleep 5
        done
        ffprocess "$file" "$outname" & ffpsid+=("$!") 
    fi
done


Just a couple notes

Your "$TIMECODE" variable never gets used ... This is as per your original script.
You're better off letting ffmpeg manage its own threads by passing -threads 0 instead of 4


---

