2

I have about 300 videos, on a Debian server, stored in the following manner:

/mediaroot/1/m32.mp4
/mediaroot/2/m421.mp4
/mediaroot/n/mx.mp4

They all need to be deinterlaced, and I want to do it with FFmpeg.

With the assistance of another helpful sole, I have reached a somewhat tolerable result with the following steps:

  1. extract audio
  2. transcode video, example

    ffmpeg -y -i m148.mp4 -pix_fmt yuv420p -an -pass 1 -passlogfile m148.x600.1351896878.log -an -vcodec libx264 -b:v 600k -preset medium -tune film -threads 0 m148.x600.1351896878.mp4
    ffmpeg -y -i m148.mp4 -pix_fmt yuv420p -an -pass 2 -passlogfile m148.x600.1351896878.log -an -vcodec libx264 -b:v 600k -preset medium -tune film -threads 0 m148.x600.1351896878.video.mp4
    
  3. mux new video with audio extracted in step 1.

  4. use qt-faststart to move the atoms

    ffmpeg/qt-faststart m148.x600.1351896878.mp4 m148.x600.1351896878.atom.mp4
    

My question is then: How do I make it automatically deinterlace and replace all the videos?

2 Answers 2

2

To deinterlace, use the YADIF filter. Just add -filter:v yadif somewhere within the command line after the -i input.mp4 bit.

You don't need to extract the audio then re-mux. FFMPEG is willing to copy the source audio from the input stream to the output if you ask nicely by adding -acodec copy to your encoding command(s). Again, it needs to appear after the -i input.mp4 option, and maybe after the -f container option, too. I tend to place it after all the video options, just as a matter of personal style.

As far as replacing the input file, that should be clear: you encode to a temporary output file, then if that succeeds, your script says something like mv /tmp/whatever.mp4 input.mp4.

1

Write a simple shell scrip - you basically have everything done already, just need to put it together "under one roof" (in one script file).

#!/bin/bash

# loop over all arguments to the script - place each single
# one into variable f (further referenced to by $f) and execute
# the commands in the loop
for f in "$@"; do
    # create new variable holding filename without the extension
    n=${m%.mp4}

    # commands you mentioned above go here, you only need to
    # replace the strings that correspond to actual filename
    # with "$f" or "$n". Use the quotes around in case your
    # filenames contained spaces. e.g.:
    ffmpeg -y -i "$f" -pix_fmt yuv420p -an -pass 1 -passlogfile "$n".x600.1351896878.log -an -vcodec libx264 -b:v 600k -preset medium -tune film -threads 0 "$n".x600.1351896878.mp4
    ffmpeg -y -i "$f" -pix_fmt yuv420p -an -pass 2 -passlogfile "$n".x600.1351896878.log -an -vcodec libx264 -b:v 600k -preset medium -tune film -threads 0 "$n".x600.1351896878.video.mp4

    # more commands...
done

Then run the script with filenames to convert as its arguments:

script.sh file1.mp4 /another/directory/file2/mp4 ...

You will either need to make it executable: chmod a+x script.sh or run it through the shell interpreter explicitely: bash script.sh ...

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .