Linux Bash scripts to separate channels

GTA Driver

Well-Known Member
Joined
Apr 5, 2015
Messages
1,255
Reaction score
597
Location
Greater Toronto Area
Country
Canada
Dash Cam
Iroad 3300CH, G1W-c, Mobius C, A119 v1 & v3, A118-c2
I wrote two scripts that split multi channel mp4 files that use ffmpeg

chanSplit.sh
Splits a mp4 file to a suddirectory (folder) called chanSplit. Before running, you need to define a variable called input. Example :​
input=myfile.mp4​
chanSplitAll.sh
Splits all MP4 files in current directory (folder) to a subfolder called chanSplit. You do NOT need to define the input variable as it runs all mp4 files in the directory.​
Edit: I mentioned earlier you need to set the input variable. That was wrong.​

This was written for my dash cam which uses mp4 files , has channel 0 for audio, 1 for front and 2 for rear. You will need to change accordingly.

The files will need to be copied somewhere in your $PATH and of course you need ffmpeg.
Edit July 1, 2018
The chansplit script files can be acquired from Google drive and box.net​
 
Last edited:
Code:
#chanSplit.sh[/B]
[B]outDir=chanSplit
audio=yes #if you don't want sound then set to no


if [ $audio = "yes" ];then
    sound='-map 0:0'
fi


if [ -z "$input" ]
then
    echo "the \$input variable is NOT define"
    echo you must define \$input before running this script
    echo " "
    echo example
    echo "     input=myfile.mp4"
    echo "     export input"
    exit
fi

mkdir $outDir

#ffmpeg -i $input -map 0:0 -async 1 $outDir/ch0.$input 
ffmpeg -i $input  $sound -map 0:1 -async 1 $outDir/ch1.$input
ffmpeg -i $input  $sound-map 0:2 -async 1 $outDir/ch2.$input
#ffmpeg -i $input -map 0:3 -async 1 $outDir/ch3.$input
 
Last edited:
script to split all files in a directory (folder)
Code:
#chanSplitAll.sh
outDir=chanSplit
mkdir $outDir
audio=yes #if you don't want sound then set to no


if [ $audio = "yes" ];then
     sound='-map a:0'

fi 

for f in `ls *.mp4`
do
    ffmpeg -i $f $sound -map 0:1 -async 1 $outDir/ch1.$f
    ffmpeg -i $f $sound -map 0:2 -async 1 $outDir/ch2.$f
done

---------------
Edit
  • Variable in output changed to ch#.$f (in bold)
  • added "code"
  • changed sound assignment to sound='-map a:0'
 
Last edited:
Looks interesting. I was looking into doing something like this now that I use mint for all my video editing. It's annoying to have to rdp to my windows server or boot to windows just to split the AVIs from my cf100 to be edited. Would be nice if it could have a gui but that's not real easy in bash.
 
There was an error the script in the script chanSplitAll.sh that I caught yesterday morning. I tested on one file in the directory but not several.

incorrect
for f in `ls *.mp4`
do

ffmpeg -i $f $sound -map 0:1 -async 1 $outDir/ch1.$input
ffmpeg -i $f $sound -map 0:2 -async 1 $outDir/ch2.$input
done


correct
for f in `ls *.mp4`
do

ffmpeg -i $f $sound -map 0:1 -async 1 $outDir/ch1.$f
ffmpeg -i $f $sound -map 0:2 -async 1 $outDir/ch2.$f
done
 
Last edited:
question - if you don't set sound before running the script, it will be null, which will result in an extra space in the command line. does that cause any issues? i don't know about ffmpeg, but some things are really anal about the formatting of their command line switches.
 
also, the script can be made a little more universal using the command line switches i used in my splitter vbscript:
Code:
if [ $audio = "yes" ];then
sound='-map a:0'
fi

for f in `ls *.mp4`
do
ffmpeg -i $f $sound -map v:0 -async 1 $outDir/ch1.$f
ffmpeg -i $f $sound -map v:1 -async 1 $outDir/ch2.$f
done

(fyi you ought to use the [ code] BBcode - much simpler and no chance of funkiness like weird quotes or spacing or whatever, and you can use square brackets however syntax demands, without having to put spaces around them.)

all i changed from your script was the map commands. basically this tells ffmpeg to use the first audio channel it finds (no matter which ch it actually is). same for video - it uses the first and second video ch's it finds in the input file, rather than hard-coding which ch your camera actually uses. this will make it more useful to people who may not know which ch their camera records the audio on, and also make it work on more cameras. i think some of the ones my script works on actually record audio on ch2 or ch3 rather than ch0.

i'm not sure how we could make it work on AVI and MP4 in the same script without using a second for loop, unless FOR allows you to use OR, which case it would be dead simple. sorry if my green is showing - i'm still pretty new to bash, and i'm on my work (win7) machine so can't get to the linux box right now to try it, and looking at my vbscript won't help either since that actually makes the user specify every source file at the beginning of the script, and for each file they pick it verifies that the extension is either avi or mp4 before adding that file/path to the array of files it's going to split. and now that i've used my own script a bunch for making my dashcam chronicle videos, i think that your approach of just splitting every file in a directory is a good one and may add it to a future version of the vbscript.
 
I will answer your questions this evening and do some research/testing on some of the things you pointed out. At work now and my co-worker was inquiring about things during my lunch.
 
Looks interesting. I was looking into doing something like this now that I use mint for all my video editing. It's annoying to have to rdp to my windows server or boot to windows just to split the AVIs from my cf100 to be edited. Would be nice if it could have a gui but that's not real easy in bash.


Curious, what editor do you use in Mint.

I like working in bash shell. I have some Linux servers running Samba and I connect to them in windows using text editor, office and explorer. I will have a window open using ssh client and do some work with such things as grep or shell scripts.
 
question - if you don't set sound before running the script, it will be null, which will result in an extra space in the command line. does that cause any issues? i don't know about ffmpeg, but some things are really anal about the formatting of their command line switches.


I have run the script with and without using sound. Having a null value here does not seem to effect it. Most of the time in bash excessive spaces does not seem to effect the script. Conditional statements such as seem to crash with poor use of spaces and formating
 
also, the script can be made a little more universal using the command line switches i used in my splitter vbscript:
Your vbscript influenced the writing of this. I was considering using "-front" and "-rear" but that would take more time to write. It could be written later.


i'm not sure how we could make it work on AVI and MP4 in the same script without using a second for loop, unless FOR allows you to use OR, which case it would be dead simple.

Only problem with that is if we add code , we have to add to both blocks. I will play around with boolean OR ("-o" )
http://stackoverflow.com/questions/15534595/bash-scripting-multiple-conditions-in-while-loop
 
i'm not sure how we could make it work on AVI and MP4 in the same script without using a second for loop, unless FOR allows you to use OR,

At work, I use "for ls" yet but never considering using "or" . It appears -o ("Or") can use to connect to different ls statements

Code:
for f in `ls *.mp4` -o f in `ls *.avi`

Tested by copying an mp4 file to be an avi
 
Why is it I feel like I'm back at work again? :rolleyes::D
 
script to split all files in a directory (folder)
Code:
#chanSplitAll.sh
outDir=chanSplit
mkdir $outDir
audio=yes #if you don't want sound then set to no


if [ $audio = "yes" ];then
     sound='-map a:0'

fi

for f in `ls *.mp4`
do
    ffmpeg -i $f $sound -map 0:1 -async 1 $outDir/ch1.$f
    ffmpeg -i $f $sound -map 0:2 -async 1 $outDir/ch2.$f
done

---------------
Edit
  • Variable in output changed to ch#.$f (in bold)
  • added "code"
  • changed sound assignment to sound='-map a:0'
you need to also use the V option for -map if you use the A option. this is because ch1 or ch2 may not always be video depending on the source file. in fact in the case of my cf-100, i'm pretty sure ch0 is front video, ch1 is rear video, and ch2 is audio. so if your script was changed to allow avi instead of mp4, it would create ch1.$f containing rear video(+audio if yes), and ch2.$f would be just audio, or it may throw an error if you have audio=yes because you'd be telling it to put the same audio track into a file twice. so changing the 0:1 and 0:2 to v:0 and v:1 in the do/done loop will cure that.

also, there appears to be a stray bold bbcode tag at the top of the first script inside the code block. ;)
 
Why is it I feel like I'm back at work again? :rolleyes::D
some of us are broken that way. :D

gpf19990201y09ez.png
 
Curious, what editor do you use in Mint.

I like working in bash shell. I have some Linux servers running Samba and I connect to them in windows using text editor, office and explorer. I will have a window open using ssh client and do some work with such things as grep or shell scripts.

kdenlive. it's sometimes a little flaky, but i like it.

it's funny... i'm learning powershell for work since we're a windows shop. quite often i'll catch myself typing ls -l at a prompt... and then as i'm reading through the directory listing, THEN i realize that i just used ls on a windows machine... and it worked (in powershell, but not in a normal cmd window). will have to try piping it to grep and see if that works, too. :D

Your vbscript influenced the writing of this. I was considering using "-front" and "-rear" but that would take more time to write. It could be written later.

Only problem with that is if we add code , we have to add to both blocks. I will play around with boolean OR ("-o" )
http://stackoverflow.com/questions/15534595/bash-scripting-multiple-conditions-in-while-loop
i'd been thinking about writing a linux version myself, but don't know enough bash to do it. i'd want it to have a gui as well to be easier for newbies trying out *buntu or whatever, each time a new version of windows comes out, or just for people who are allergic to a CLI.

basically in order to add the "front" and "audio" stuff to the filenames, i had to break them apart into filenames and extensions, tack on the extra text, then tack the extension back on.

i can certainly appreciate brevity in code. sometimes it makes it easier to debug. but when you can contain branches inside an IF statement, it's sometimes easier to look at when there's not so many variables in one line. yeah, i'm lazy like that sometimes.
 
Code:
# chanSplit.sh
# Script to split streams from ALL files in current directory with more than one video stream inside.
# Useful for dashcams such as the Blacksys CF-100, and JaeWonCNC Iroad IOne-3300CH
# Highly recommended that script be located in a directory in your PATH

# You may need to customize some of the variables.

# VERSION HISTORY
# v1.00 - 03 Oct 2015: Initial Release
# v1.01 - 05 Oct 2015: Sound map and video map improvements
# v1.02 - 06 Oct 2015: In file name, change from CH# to more clear "front" and rear channel.

outDir=chanSplit
audio=yes #if you don't want sound then set to no


if [ $audio = "yes" ];then
    sound='-map a:0'
fi

if [ -z "$input" ]
then
    echo "the \$input variable is NOT defined!"
    echo you must define \$input before running this script
    echo " "
    echo example
    echo "     input=myfile.mp4"
    echo "     export input"
    exit
fi

mkdir $outDir

ffmpeg -i $input  $sound -map v:0 -async 1 $outDir/front..$input
ffmpeg -i $input  $sound -map v:1 -async 1 $outDir/rear.$input
 
Last edited:
Code:
# chanSplitAll.sh
# Script to split streams from ALL files in current directory with more than one video stream inside.
# Useful for dashcams such as the Blacksys CF-100, and JaeWonCNC Iroad IOne-3300CH
# Highly recommended that script be located in a directory in your PATH

# You may need to customize some of the variables.

# VERSION HISTORY
# v1.00 - 03 Oct 2015:     Initial Release
# v1.01 - 05 Oct 2015:     Looks for both MP4 and AVI in directory,
# v1.02 - 06 Oct 2015:     Sound map and video map improvements.
#            In file name, Change from CH# to more clear "front" and rear channel.
#                  Fixed bug in or statement


outDir=chanSplit
mkdir $outDir
audio=yes #if you don't want sound then set to no


if [ $audio = "yes" ];then
      sound='-map a:0'
fi 

for f in `ls *.mp4` -o  `ls *.avi`
do
    ffmpeg -i $f $sound  -map v:0 -async 1 $outDir/front.$f
    ffmpeg -i $f $sound  -map v:1 -async 1 $outDir/rear.$f
done
 
Last edited:
Yes map switches look good now. And comments always help. I'll have to try the script next time I have a block of time to do some more editing. Thanks!
 
Thread starter Similar threads Forum Replies Date
J Dash Cam Discussion 41
A Dash Cam Discussion 3
Back
Top