riimzzai
riimzzai

Reputation: 123

bash script : test for video files failed

I have written a little bash script to extract audio from video files in batch mode.

Sound is extracted from each mp4 file to flac format using avconv (and the flac codec).

#!/bin/sh
#
# Batch conversion of audio extraction from video

FOLDER_SRC="/home/Me/Music/TestBatchConv"

for myvid in $(find ${FOLDER_SRC} | grep mp4)
do
avconv -i $myvid -acodec flac "${myvid}.flac"
done

exit 0

It works fine, but I would like to improve it.

How do I test if the file is a video ? I tried something like

for myvid in $(find ${FOLDER_SRC})
do
    if [ file -i $myvid | grep video ]
        then avconv -i $myvid -acodec flac "${myvid}.flac"
    fi
done

but i cant get it done (yes i am new to this).

Any help appreciated.

Upvotes: 2

Views: 1835

Answers (3)

Wing Tang Wong
Wing Tang Wong

Reputation: 792

The use of 'file' works against magic numbers, so it can be wrong sometimes.

I've used 'mplayer' to grab the data:

mplayer -ao null -vo null -endpos 0.01 ${MEDIAFILE} 2>/dev/null | egrep "AUDIO:|VIDEO:"

This will give matches against audio and video. You can omit one or the other or add a '-c' to the egrep so you can do a match:

if [ `mplayer -ao null -vo null -endpos 0.01 ${MEDIAFILE} | egrep -c "VIDEO:"` -gt 0 ]; then
    # HANDLE VIDEO FILE
fi

However, since you are extracting audio from video files, you'd probably want to make sure that a video file you want to process also has an audio component:

AVCHECK=`mplayer -ao null -vo null -endpos 0.01 ${MEDIAFILE} 2>/dev/null | egrep "AUDIO:|VIDEO:"`

if [ `echo "${AVCHECK}" | grep -c AUDIO` && `echo "${AVCHECK}" | grep -c VIDEO` ]; then
    # STRIP AUDIO FROM VIDEO FILE
fi

Upvotes: 1

shellter
shellter

Reputation: 37268

rewrite your new test as

 if  file -i $myvid | grep -q video  ; then

The -q option means quiet, so grep returns true if it finds the search target and false if not. The if responds appropriately depending on the true or false state that is returned.

Braces used with if statements are really an alias tot the test cmd, so something like

  if [ $(file -i $myvid | grep video) = "video" ] ; then

would also work.

To learn how to get this sort of thing right, just work on the command line, and add one bit at a time, i.e.

 file -i $myvid 

then

file -i $myvid | grep video

OR

file -i $myvid | grep -q video ; echo $?

And to see the inverse, change to

file -i $myvid | grep nonesuch ; echo $?

EDIT

And to test for more than one thing, you can use egrep, i.e.

 if  file -i $myvid | egrep -q 'video|application/octet'  ; then

IHTH

Upvotes: 5

H.-Dirk Schmitt
H.-Dirk Schmitt

Reputation: 1169

I would first create a file list

   find ${FOLDER_SRC} -type f -exec file \{\} +

Only one invocation of file, see man find and look for "-exec command {} +"

Add a simple workaround for spaces

   find ${FOLDER_SRC} -type f -exec file \{\} + |tr ' ' '°'

Simple and sufficient. An alternative is the use of mapfile.

Iterate over the file list and define actions in a case statement

   for line in $(find ${FOLDER_SRC} -type f -exec file \{\} + |tr ' ' '°')
   do
     file=${line%%:*}
     file=${file//°/ }          
     content=${line#*:}
     content=${content//°/ }          
     case "${content}" in
         *video/mp2p*) myConvertFunctionA;;
         *video/mpeg*) myConvertFunctionB;;
         *video*) echo "found unsupported video type: ${content}";;
     esac
   done
  • string manipulations via bash builtins are fast
  • case is easy to understand
  • avoid multiple instantion of grep

Upvotes: 2

Related Questions