Compile FFMPEG for Ubuntu 12.04

Compile FFmpeg on Ubuntu

Sorry it is just a link to another site. More of a reminder to myself

Share Button

How to convert videos/movies for the VTech Innotab using FFMPEG (SOLVED)

The VTech Innotab is a young children’s tablet for learning. When I picked up two of them from the local Target, we installed the six free games but was rather disappointed with the video capabilities listed in the manual:

  • File Type: AVI
  • Resolution: 480 x 272
  • Video Codec: MJPEG
  • Video Bit rate: 2400kbps
  • Frame rate: 15fps
  • Audio Sampling Rate: 22.05kHz
  • Audio Channel: Mono
  • Audio Encoder: PCM

MJPEG is a very poor codec as it produces quite large files and tends to be very blocky with any type of motion. After a bit of research, I discovered that the Innotab would accept MPEG4 video but the audio still had to be PCM mono. So the MPEG4 video file specification:

  • File Type: AVI
  • Resolution: 480 x 272
  • Video Codec: MPEG4 with a video tag of “XVID”
  • Video Bit rate: variable or a maximum of 3000kbps
  • Frame rate: 29.997fps
  • Audio Sampling Rate: 22.05kHz
  • Audio Channel: Mono
  • Audio Encoder: PCM

I chose to use ffmpeg as it is available on all major platforms. There are a few steps that need to be performed to create a working video:

Convert the video. We use “-1” for the height as we want to keep the aspect of the original video

ffmpeg -i "input.wmv" -r 65535/2733 -vcodec mpeg4 -vtag XVID -q:v 8 -vf "scale=480:-1" -an -y "video_out.mp4"

Extract the audio to mp3 format. This is necessary as the pcm_s16le codec is very finicky on the audio input

ffmpeg -i "input.wmv" -r 65535/2733 -vn -c:a libmp3lame -ar 22050 -ac 1 -ab 128k -y "audio_out.mp3"

Increase the volume (if necessary). Change the “10” if it is too loud or quiet

mp3gain -g 10 "audio_out.mp3"

Convert the mp3 to PCM and combine with the video to produce the avi file

ffmpeg -i "video_out.mp4" -i "audio_out.mp3" -r 65535/2733 -vcodec copy -map 0:0 -c:a pcm_s16le -ar 22050 -ac 1 -map 1:0 -y video_ready_for_innotab.avi

HINT: you get three free games for each Innotab device but the games, ebooks, etc are tied to the VTech account not to each device. This allows you to save $$ if you have more than one Innotab device.

Share Button

Perl Script to Convert an Audiobook (m4b) to mp3 files splitting on the chapters

I have an Nissan Altima with a BOSE radio that allows me to hook up an USB thumbdrive containing mp3 files. The problem is most of my audiobooks are in m4b format. Previously I’ve used tools like mp3splt and tried to split on ‘silence’ or timed increments (say 15 min) but I was getting mp3 files that would be split in midsentence and sometimes midword. It became very annoying after awhile.

So, I came up with a really simple script to convert an audiobook (m4b) into mp3 files splitting on the chapters. We are dependent on FFmpeg::Command and a modified FFprobe Perl module.

In the following example, we are converting a Ben Bova audiobook but we are going to specify to start the track numbering at “10” because the 2nd file ended with track “9”.

jason@jason-Inspiron-1545 ~/bin $ ./test_mp4_info.pl -i "/home/jason/Audiobooks/Ben Bova/Mars/Mars 3.m4b" -o mp3 -a "Mars" -t 10
Converting "Mars 3.m4b" to "mp3/010 Mars.mp3"...
	album: Mars
	artist: Ben Bova
	title: 010 - Mars
	genre: Audiobook
	track: 10
	... COMPLETE
Converting "Mars 3.m4b" to "mp3/011 Mars.mp3"...
	album: Mars
	artist: Ben Bova
	title: 011 - Mars
	genre: Audiobook
	track: 11
	... COMPLETE
Converting "Mars 3.m4b" to "mp3/012 Mars.mp3"...
	album: Mars
	artist: Ben Bova
	title: 012 - Mars
	genre: Audiobook
	track: 12
	... COMPLETE
Converting "Mars 3.m4b" to "mp3/013 Mars.mp3"...
	album: Mars
	artist: Ben Bova
	title: 013 - Mars
	genre: Audiobook
	track: 13
	... COMPLETE
Converting "Mars 3.m4b" to "mp3/014 Mars.mp3"...
	album: Mars
	artist: Ben Bova
	title: 014 - Mars
	genre: Audiobook
	track: 14
	... COMPLETE

Source code:

#!/usr/bin/perl

use strict;
use warnings;

use lib qw(/home/jason/bin);

use Getopt::Std;
use File::Basename;
use FFmpeg::Command;
use FFprobe;

$|++;

###############################
sub _encode_mp3 {
  my ($input_file, $output_dir, $album, $starting_track) = @_;

  my %tags = ();
  my $track_number;
  my $mp4 = FFprobe->probe_file($input_file);
  my $base_output_file = basename($input_file);
  $base_output_file =~ s/\.\w+$//;

  if (exists $mp4->{format}->{'TAG:comment'}) {
    $tags{genre} = $mp4->{format}->{'TAG:comment'};
    $tags{genre} =~ s/("')//g;
  }

  if (exists $mp4->{format}->{'TAG:genre'}) {
    $tags{genre} = $mp4->{format}->{'TAG:genre'};
    $tags{genre} =~ s/("')//g;
  }

  if (exists $mp4->{format}->{'TAG:artist'}) {
    $tags{artist} = $mp4->{format}->{'TAG:artist'};
    $tags{artist} =~ s/("')//g;
  }

  if ($album) {
    $tags{album} = $album;
  } elsif (exists $mp4->{format}->{'TAG:album'}) {
    $tags{album} = $mp4->{format}->{'TAG:album'};
  }

  $tags{album} =~ s/("')//g;
  $track_number = $starting_track if $starting_track;

  foreach my $chapter (sort keys %{$mp4->{chapters}}) {
    unless ($starting_track) {
      $track_number = $chapter;
    }

    my $output_file = sprintf "%s/%03d %s.mp3", $output_dir, $track_number, $tags{album};
    my $start = $mp4->{chapters}->{$chapter}->{start};
    my $duration = $mp4->{chapters}->{$chapter}->{end} - $start;
    my @options = ();

    if ($album) {
      $tags{title} = sprintf "%03d - %s", $track_number, $album;
    } else {
      if (exists $mp4->{format}->{'TAG:title'}) {
        $tags{title} = sprintf "%03d - %s", $track_number, $mp4->{format}->{'TAG:title'};
      } else {
        $tags{title} = sprintf "%03d - %s", $track_number, $base_output_file;
      }
    }

    $tags{title} =~ s/("')//g;

    my $ffmpeg = FFmpeg::Command->new;

    $ffmpeg->input_options({
        file => $input_file,
     });

    $ffmpeg->output_options({
     'file' => $output_file,
     'audio_codec' => 'libmp3lame',
     'audio_bit_rate' => 64,
     });

    printf "Converting \"%s\" to \"%s\"...\n", basename($input_file), $output_file;

Share Button

Audiobook chapter support for FFprobe (Perl) module

I have multiple audiobook files (m4b) that ffprobe is able to retrieve the chapters from just fine… except the chapter information is printed to stderr and never in the formatted (STDOUT) output. The Perl module FFprobe doesn’t handle the chapters so I submitted feature request #73803

Feature request is to format the chapter output.

jason@jason-Inspiron-1545 ~/bin $ ffprobe "/home/jason/Audiobooks/Ben Bova/Mars/Mars 1.m4b" 1>/dev/null
  libavutil    51.  7. 0 / 51.  7. 0
  libavcodec   53.  5. 0 / 53.  5. 0
  libavformat  53.  2. 0 / 53.  2. 0
  libavdevice  53.  0. 0 / 53.  0. 0
  libavfilter   2.  4. 0 /  2.  4. 0
  libswscale    2.  0. 0 /  2.  0. 0
  libpostproc  52.  0. 0 / 52.  0. 0
[mov,mp4,m4a,3gp,3g2,mj2 @ 0xddfac0] max_analyze_duration reached
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/jason/Audiobooks/Ben Bova/Mars/Mars 1.m4b':
  Metadata:
    major_brand     : M4B 
    minor_version   : 0
    compatible_brands: M4B mp42isom
    creation_time   : 2009-09-08 16:19:29
    album           : Mars
    artist          : Ben Bova
    genre           : Audiobook
  Duration: 03:51:23.41, start: 0.000000, bitrate: 81 kb/s
    Chapter #0.0: start 0.000000, end 2779.567914
    Metadata:
      title           : Mars - 01 of 24
    Chapter #0.1: start 2779.567914, end 5555.049161
    Metadata:
      title           : Mars - 02 of 24
    Chapter #0.2: start 5555.049161, end 8334.617075
    Metadata:
      title           : Mars - 03 of 24
    Chapter #0.3: start 8334.617075, end 11110.098322
    Metadata:
      title           : Mars - 04 of 24
    Chapter #0.4: start 11110.098322, end 13883.419864
    Metadata:
      title           : Mars - 05 of 24
    Stream #0.0(und): Audio: aac, 44100 Hz, stereo, s16, 80 kb/s
    Metadata:
      creation_time   : 2009-09-08 16:19:29
    Stream #0.1(eng): Subtitle: text / 0x74786574
    Metadata:
      creation_time   : 2009-09-08 17:31:00
Unsupported codec with id 94213 for input stream 1

patch to add m4b chapter support:

82c82
< my ($tree, $branch, $tag, $stream);
---
>     my ($tree, $branch, $tag, $stream, $chapter);
100c100,108
< }
---
> 	} elsif ($line =~ m/Chapter \#(\d+\.*\d+): start (\d+\.*\d+)\, end (\d+\.*\d+)/i) {
>       my ($start, $end) = ($2, $3);
>       $chapter = $1;
>       $chapter =~ s/\.//g;
>       $chapter =~ s/^0+(\d)/$1/;
> 
>       $$tree{chapters}{$chapter} = { start => $start, end => $end };
>     } elsif ($line =~ /title\s+: (.+)$/) {
>       $$tree{chapters}{$chapter}{title} = $1;
101a110
>   }
Share Button

How to create an iTunes/iPod compatible audiobook (MPEG4 m4b) on Linux using MP4Box and mp4v2 v1.9.1 – it can be done!

I’ve been wracking my brains over this for the past few weeks and it finally struck me how to create an m4b audiobook with chapters that is compatible with your iPod, iTunes, VLC, etc.  It was very simple once I figured it out:

Step 1:

encode the mp3 files to “aac” (mpeg4) using your favorite converter (I use ffmpeg):

ffmpeg -i "track1.mp3" -y -vn -acodec libfaac -ab 128k -ar 44100 -threads 3 -f mp4 track1.aac

Step 2:

Create a chapters file so that MP4Box can understand it:

* Common syntax : CHAPTERX=h:m:s[:ms or .ms] on one line and CHAPTERXNAME=name on the other – the order is not important but chapter lines MUST be declared sequencially (same X value expected for 2 consecutive lines).

track1.chapters:

CHAPTER1=00:00:00.000
CHAPTER1NAME=Chapter 001
CHAPTER2=00:30:00.139
CHAPTER2NAME=Chapter 002
CHAPTER3=01:00:00.728
CHAPTER3NAME=Chapter 003
CHAPTER4=01:30:01.269
CHAPTER4NAME=Chapter 004
CHAPTER5=02:00:01.858
CHAPTER5NAME=Chapter 005
CHAPTER6=02:30:02.375
CHAPTER6NAME=Chapter 006
CHAPTER7=03:00:02.964
CHAPTER7NAME=Chapter 007
CHAPTER8=03:30:03.553
CHAPTER8NAME=Chapter 008
CHAPTER9=04:00:04.094
CHAPTER9NAME=Chapter 009
CHAPTER10=04:30:04.683
CHAPTER10NAME=Chapter 010
CHAPTER11=05:00:05.224
CHAPTER11NAME=Chapter 011
CHAPTER12=05:30:05.765
CHAPTER12NAME=Chapter 012
CHAPTER13=05:46:14.106
CHAPTER13NAME=Chapter 013
CHAPTER14=06:16:14.143
CHAPTER14NAME=Chapter 014
CHAPTER15=06:46:14.732
CHAPTER15NAME=Chapter 015
CHAPTER16=07:16:15.249
CHAPTER16NAME=Chapter 016
CHAPTER17=07:46:15.790
CHAPTER17NAME=Chapter 017
CHAPTER18=08:16:16.331
CHAPTER18NAME=Chapter 018
CHAPTER19=08:46:16.920
CHAPTER19NAME=Chapter 019
CHAPTER20=09:16:17.460
CHAPTER20NAME=Chapter 020
CHAPTER21=09:46:18.050
CHAPTER21NAME=Chapter 021
CHAPTER22=10:16:18.639
CHAPTER22NAME=Chapter 022

Step 3:

Add the chapters to the audio file (creates Nero format chapter markers):

MP4Box -add track1.aac -chap track1.chapters test.mp4

Step 4:

Convert the Nero chapter markers to Quicktime chapter markers using mp4chaps from the mp4v2 project (you will want v1.9.1 or higher):

mp4chaps --convert --chapter-qt test.mp4
converting chapters in file "test.mp4" from Nero to QuickTime

Step 5:

Rename the file from .mp4 to .m4b extension so iTunes will see it as an audiobook:

mv test.mp4 test.m4b

Proof that it works:

and VLC showing the chapters:

Of course, we aren’t putting in any tags such as “author” or “genre” in this example. Use your favorite tags editor to do so.

Share Button

Howto convert an entire directory of videos to play on your Sony Playstation 3 using ffmpeg

I think a lot of people have been struggling with mass converting of videos for the ps3…
I’ve been searching for a way to mass convert my videos (mostly podcasts) to play on my Sony PlayStation 3 over the wire with Mediatomb.  For a long time I’ve been using a hodpodge of mp4box and mencoder to convert the videos.  The problem was that mp4box more often then not would crash or get stuck in a loop where it fills up a 1TB harddrive converting a 20mb file.  There had to be a better way.

If your ffmpeg doesn’t support x264 (video) or aac (audio) encoding, like all Ubuntu Linux distributions, then you will have to recompile ffmpeg.  Don’t worry, it is easier then you think!

FakeOutdoorsman over on the Ubuntu Forums posted the method to build ffmpeg from scratch:

Choose your Ubuntu

0.The instructions on the page are for Ubuntu Jaunty Jackalope 9.04 and Ubuntu Intrepid Ibex 8.10. Separate instructions are also available for other releases:

* Install FFmpeg and x264 on Ubuntu Hardy Heron 8.04 LTS
* Install FFmpeg and x264 on Ubuntu Dapper Drake 6.06 LTS

Getting the Dependencies

1. Uninstall x264, libx264-dev, and ffmpeg if they are already installed. Open a terminal and run the following:

sudo apt-get purge ffmpeg x264 libx264-dev

2. Next, get all of the packages you will need to install FFmpeg and x264 (you may need to enable the universe and multiverse repositories):

Code:

sudo apt-get update
sudo apt-get install build-essential subversion git-core checkinstall yasm texi2html libfaac-dev libfaad-dev libmp3lame-dev libsdl1.2-dev libtheora-dev libx11-dev libxvidcore4-dev zlib1g-dev

Install x264
3. Get the most current source files from the official x264 git repository, compile, and install. You can run “./configure –help” to see what features you can enable/disable. If you are behind a firewall or unable to use git, then daily source tarballs are also available.

cd
git clone git://git.videolan.org/x264.git
cd x264
./configure
make
sudo checkinstall --fstrans=no --install=yes --pkgname=x264 --pkgversion "1:0.svn`date +%Y%m%d`-0.0ubuntu1" --default

Install FFmpeg
4. Get the most current source files from the official FFmpeg svn, compile, and install. Run “./configure –help” to see what features you can enable/disable. If you are behind a firewall or unable to use subversion, then nightly FFmpeg snapshots are also available.

cd
svn checkout svn://svn.ffmpeg.org/ffmpeg/trunk ffmpeg
cd ffmpeg
./configure --enable-gpl --enable-nonfree --enable-pthreads --enable-libfaac --enable-libfaad --enable-libmp3lame --enable-libtheora --enable-libx264 --enable-libxvid --enable-x11grab
make
sudo checkinstall --fstrans=no --install=yes --pkgname=ffmpeg --pkgversion "3:0.svn`date +%Y%m%d`-12ubuntu3" --default 

That’s it for installation. You can keep the ~/x264 and ~/ffmpeg directories if you later want to update the source files to a new revision. See “Updating Your Installation” below for more details.

Now that we have a working ffmpeg, we can go on to the converting the video files (convert_videos.sh):

#!/bin/bash

function print_usage {
  echo "============================================================================================="
  echo "        convert_videos.sh [file|directory] [output directory] {bb|bb_storm|ps3} {file prefix}" 
  echo "============================================================================================="
}

function verify_file {
  echo j
}

function process_file {
  ORIG_FILE="$1"
  DEST_DIR="$2"

  if [[ -z ${BLACKBERRY} ]]; then
    DEST_FILE=${DEST_DIR}/${FILE_PREFIX}$( basename "${ORIG_FILE}" | perl -ne 's/\.(?:[a-z,A-Z,0-9]{3,4})$/\.mp4/; print $_' )
  else
    DEST_FILE=${DEST_DIR}/${FILE_PREFIX}$( basename "${ORIG_FILE}" | perl -ne 's/\.(?:[a-z,A-Z,0-9]{3,4})$/_bb\.mp4/; print $_' )
  fi

  if [[ -f "${DEST_FILE}" ]]; then
    echo "    We already processed \"${ORIG_FILE}\" ... skipping"
  else
    VID_INFO_FPS=$( mplayer -identify -nosound -vo null -nocache -really-quiet -frames 1 "${ORIG_FILE}" 2>/dev/null | grep FPS ) 
    VID_INFO_FPS=${VID_INFO_FPS#*=}
    VID_INFO_WIDTH=$( mplayer -identify -nosound -vo null -nocache -really-quiet -frames 1 "${ORIG_FILE}" 2>/dev/null | grep WIDTH ) 
    VID_INFO_WIDTH=${VID_INFO_WIDTH##*=}
    VID_INFO_HEIGHT=$( mplayer -identify -nosound -vo null -nocache -really-quiet -frames 1 "${ORIG_FILE}" 2>/dev/null | grep HEIGHT ) 
    VID_INFO_HEIGHT=${VID_INFO_HEIGHT##*=}
    VID_INFO_ASPECT=$( mplayer -identify -nosound -vo null -nocache -really-quiet -frames 1 "${ORIG_FILE}" 2>/dev/null | grep ASPECT ) 
    VID_INFO_ASPECT=${VID_INFO_ASPECT##*=}

    AUD_INFO_FORMAT=$( mplayer -identify -ao null -vo null -nocache -really-quiet -frames 1 "${ORIG_FILE}" 2>/dev/null | grep AUDIO_FORMAT ) 
    AUD_INFO_FORMAT=${AUD_INFO_FORMAT##*=}
    AUD_INFO_CHANNELS=$( mplayer -identify -ao null -vo null -nocache -really-quiet -frames 1 "${ORIG_FILE}" 2>/dev/null | grep AUDIO_NCH ) 
    AUD_INFO_CHANNELS=${AUD_INFO_CHANNELS##*=}
    AUD_INFO_BITRATE=$( mplayer -identify -ao null -vo null -nocache -really-quiet -frames 1 "${ORIG_FILE}" 2>/dev/null | grep ID_AUDIO_BITRATE ) 
    AUD_INFO_BITRATE=${AUD_INFO_BITRATE##*=}

    if (( ${AUD_INFO_BITRATE} < 163840 )); then
      AUD_INFO_BITRATE=160
    else
      AUD_INFO_BITRATE=$( expr ${AUD_INFO_BITRATE} / 1024 )
    fi

    ###############
    #  We need to make the frame rate an acceptible amoun
    ###############
    case ${VID_INFO_FPS} in
      60.000)
        # HD
        VID_INFO_FPS=59.94
        ;;
      30.000)
        # NTSC
        VID_INFO_FPS=29.97
        ;;
      24.000)
        # PAL
        VID_INFO_FPS=23.97
        ;;
    esac 

    ###############
    #  We need to make the video resolution a multiple of 16 for it to be properly compressed
    ###############
    if (( ${VID_INFO_HEIGHT} % 16 )); then
      VID_BORDER_VERTICAL=$( expr 16 - ${VID_INFO_HEIGHT} % 16 )
      VID_BORDER_VERTICAL=$( expr ${VID_BORDER_VERTICAL} / 2 )

      if (( ${VID_BORDER_VERTICAL} % 2 )); then
        let VID_BORDER_VERTICAL_TOP+=$( expr ${VID_BORDER_VERTICAL} - 1 )
        let VID_BORDER_VERTICAL_BOTTOM+=$( expr ${VID_BORDER_VERTICAL} + 1 )
      else
        VID_BORDER_VERTICAL_TOP=${VID_BORDER_VERTICAL}
        VID_BORDER_VERTICAL_BOTTOM=${VID_BORDER_VERTICAL}
      fi
    else
      VID_BORDER_VERTICAL_TOP=0
      VID_BORDER_VERTICAL_BOTTOM=0
    fi
 
    if (( ${VID_INFO_WIDTH} % 16 )); then
      VID_BORDER_HORIZONTAL=$( 16 - ${VID_INFO_WIDTH} % 16 )
      VID_BORDER_HORIZONTAL=$( ${VID_INFO_WIDTH} / 2 )

      if (( ${VID_BORDER_HORIZONTAL} % 2 )); then
        let VID_BORDER_HORIZONTAL_RIGHT+=$( expr ${VID_BORDER_HORIZONTAL} + 1 )
        let VID_BORDER_HORIZONTAL_LEFT+=$( expr ${VID_BORDER_HORIZONTAL} - 1 )
      else
        VID_BORDER_HORIZONTAL_RIGHT=${VID_BORDER_HORIZONTAL}
        VID_BORDER_HORIZONTAL_LEFT=${VID_BORDER_HORIZONTAL}
      fi
    else
      VID_BORDER_HORIZONTAL_LEFT=0
      VID_BORDER_HORIZONTAL_RIGHT=0
    fi

    if &#91;&#91; -z ${VID_INFO_ASPECT} &#93;&#93; || &#91;&#91; ${VID_INFO_ASPECT} == "0.0000" &#93;&#93;; then
      VID_INFO_ASPECT="16:9"
    fi

    if &#91;&#91; -z ${AUD_INFO_CHANNELS} &#93;&#93;; then
      AUD_INFO_CHANNELS=2
    fi


    ##############
    # If we're not converting for the blackberry, perform a normal conversion 
    ##############
    if &#91;&#91; -z ${BLACKBERRY} &#93;&#93;; then
      VID_INFO_RESOLUTION="${VID_INFO_WIDTH}x${VID_INFO_HEIGHT}"

      convert_file_first_pass 

      if &#91;&#91; ! -z ${FIRST_PASS_BITRATE} &#93;&#93;; then
        BITRATE=${FIRST_PASS_BITRATE}
      fi
    else
      ############
      # if we have a blackberry, set the resolution appropriately
      ############
      case ${BB_TYPE} in
        STORM)
          VID_INFO_RESOLUTION="480x360"
          ;;
        *)
          VID_INFO_RESOLUTION="240x180"
          ;;
      esac
    fi

    convert_file_second_pass 
  fi
}

function process_directory {
 ORIG_VIDEO_DIR="$1"
 DEST_VIDEO_DIR="$2"

  if &#91;&#91; -d "${ORIG_VIDEO_DIR}" &#93;&#93; && &#91;&#91; -d "${DEST_VIDEO_DIR}" &#93;&#93;; then
    IFS=$'\n'

    for ORIG_VIDEO_FILE in $( find "${ORIG_VIDEO_DIR}" -depth -maxdepth 1 -type f -readable -iregex '.*\.\(3gp\|3g2\|avi\|divx\|flv\|m4v\|mj2\|mov\|mp1\|mp2\|mp4\|mpe\|mpeg\|mpeg4\|mpg\|mkv\|mv\|ogm\|rm\|rmvb\|rv\|qt\|wmv\)' ); do
      process_file "${ORIG_VIDEO_FILE}" "${DEST_VIDEO_DIR}"
    done
  fi 
}

function convert_file_first_pass {
  echo "----------------------------------------------------"
  echo "   First pass: ${ORIG_FILE}"
  echo "ffmpeg -i \"${ORIG_FILE}\" -an -pass 1 \
    -vcodec libx264 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 \
    -me_method epzs -subq 1 -trellis 0 -refs 1 -bf 3 -b_strategy 1 -level 31 -coder 1 -me_range 16 -g 250 -keyint_min 25 \
    -sc_threshold 40 -i_qfactor 0.71 -bt 200kb -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 1 -qmax 51 -qdiff 4 \
    -padtop ${VID_BORDER_VERTICAL_TOP} -padbottom ${VID_BORDER_VERTICAL_BOTTOM} \
    -padleft ${VID_BORDER_HORIZONTAL_LEFT} -padright ${VID_BORDER_HORIZONTAL_RIGHT} \
    -threads 2 \
    -s ${VID_INFO_RESOLUTION} -aspect ${VID_INFO_ASPECT} -f rawvideo -y /dev/null" 

  ffmpeg -i "${ORIG_FILE}" -an -pass 1 \
    -vcodec libx264 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 \
    -me_method epzs -subq 1 -trellis 0 -refs 1 -bf 3 -b_strategy 1 -level 31 -coder 1 -me_range 16 -g 250 -keyint_min 250 \
    -sc_threshold 40 -i_qfactor 0.71 -bt 200kb -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 1 -qmax 51 -qdiff 4 \
    -padtop ${VID_BORDER_VERTICAL_TOP} -padbottom ${VID_BORDER_VERTICAL_BOTTOM} \
    -padleft ${VID_BORDER_HORIZONTAL_LEFT} -padright ${VID_BORDER_HORIZONTAL_RIGHT} \
    -threads 2 \
    -s ${VID_INFO_RESOLUTION} -aspect ${VID_INFO_ASPECT} -f rawvideo -y /dev/null 2>&1 | tee pass2.out

  BITRATE=$( grep -e "\[libx264.*kb\/s" pass2.out )
  BITRATE=${BITRATE##*:}
  BITRATE=${BITRATE/.*}

  echo "average first pass bitrate: ${BITRATE}"

  if [[ -n ${BITRATE} ]]; then
    if (( ${BITRATE} % 16 )); then
      let BITRATE+=$( expr ${BITRATE} % 16 )
    fi
  else
    if (( ${VID_INFO_WIDTH} > 1024 )); then
       BITRATE=15360
    elif (( ${VID_INFO_WIDTH} > 900 )); then
       BITRATE=10240 
    elif (( ${VID_INFO_WIDTH} > 719 )); then
       BITRATE=8192
    elif (( ${VID_INFO_WIDTH} > 620 )); then
       BITRATE=2560
    else
       BITRATE=512
    fi
  fi

  MAX_BITRATE=$( expr ${BITRATE} + 512 )
}

function convert_file_second_pass {
  echo "----------------------------------------------------"
  echo "   Second pass: ${ORIG_FILE}"

  if [[ -n ${BLACKBERRY} ]]; then
    echo "ffmpeg -i \"${ORIG_FILE}\" -vcodec mpeg4 -vtag XVID -s ${VID_INFO_RESOLUTION} \
      -qscale 10 -ab 48k -ar 22050 -ac 2 -acodec libmp3lame -deinterlace \
      -b 512kb -qmin 1 -qmax 51 \
      -padtop ${VID_BORDER_VERTICAL_TOP} -padbottom ${VID_BORDER_VERTICAL_BOTTOM} \
      -padleft ${VID_BORDER_HORIZONTAL_LEFT} -padright ${VID_BORDER_HORIZONTAL_RIGHT} \
      -aspect ${VID_INFO_ASPECT} \"${DEST_FILE}\""

    ffmpeg -i "${ORIG_FILE}" -vcodec mpeg4 -vtag XVID -s ${VID_INFO_RESOLUTION} \
      -ab 48k -ar 22050 -ac 2 -acodec libmp3lame -deinterlace \
      -b 512kb -qmin 1 -qmax 51 \
      -padtop ${VID_BORDER_VERTICAL_TOP} -padbottom ${VID_BORDER_VERTICAL_BOTTOM} \
      -padleft ${VID_BORDER_HORIZONTAL_LEFT} -padright ${VID_BORDER_HORIZONTAL_RIGHT} \
      -aspect ${VID_INFO_ASPECT} "${DEST_FILE}"
  else
    echo "ffmpeg -i \"${ORIG_FILE}\" -acodec libfaac -ar 44100 -ac ${AUD_INFO_CHANNELS} \
      -async 1 -f mp4 -pass 2 -vcodec libx264 -vtag XVID -flags +loop+ilme -cmp +chroma \
      -partitions +parti4x4+partp8x8+partb8x8 -flags2 +mixed_refs -me_method umh -subq 5 \
      -trellis 1 -refs 5 -bf 3 -b_strategy 1 -level 31 -coder 1 -me_range 16 \
      -g 250 -keyint_min 250 -sc_threshold 40 -i_qfactor 0.71 -bt 200kb \
      -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 3 -qmax 15 -qdiff 4 \
      -s ${VID_INFO_RESOLUTION} -aspect ${VID_INFO_ASPECT} \
      -padtop ${VID_BORDER_VERTICAL_TOP} -padbottom ${VID_BORDER_VERTICAL_BOTTOM} \
      -padleft ${VID_BORDER_HORIZONTAL_LEFT} -padright ${VID_BORDER_HORIZONTAL_RIGHT} \
      -b ${BITRATE}kb -maxrate ${MAX_BITRATE}kb \
      -bufsize ${MAX_BITRATE}kb -ab ${AUD_INFO_BITRATE}kb \
      -threads 2 \
      -r ${VID_INFO_FPS} \"${DEST_FILE}\""

    ffmpeg -i "${ORIG_FILE}" -acodec libfaac -ar 44100 -ac ${AUD_INFO_CHANNELS} \
      -async 1 -f mp4 -pass 2 -vcodec libx264 -vtag XVID -flags +loop+ilme -cmp +chroma \
      -partitions +parti4x4+partp8x8+partb8x8 -flags2 +mixed_refs -me_method umh -subq 5 \
      -trellis 1 -refs 5 -bf 3 -b_strategy 1 -level 31 -coder 1 -me_range 16 \
      -g 250 -keyint_min 250 -sc_threshold 40 -i_qfactor 0.71 -bt 200kb \
      -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 1 -qmax 51 -qdiff 4 \
      -s ${VID_INFO_RESOLUTION} -aspect ${VID_INFO_ASPECT} \
      -padtop ${VID_BORDER_VERTICAL_TOP} -padbottom ${VID_BORDER_VERTICAL_BOTTOM} \
      -padleft ${VID_BORDER_HORIZONTAL_LEFT} -padright ${VID_BORDER_HORIZONTAL_RIGHT} \
      -b ${BITRATE}kb -maxrate ${MAX_BITRATE}kb \
      -bufsize ${MAX_BITRATE}kb -ab ${AUD_INFO_BITRATE}kb \
      -threads 2 \
      -r ${VID_INFO_FPS} "${DEST_FILE}"
  fi
}

if [[ -n "$1" ]] && [[ -n "$2" ]]; then
  if [[ -n "$3" ]]; then
    case "$3" in
      bb)
        BLACKBERRY=1
        BB_TYPE="norm"
        ;;
      bb_storm)
        BLACKBERRY=1
        BB_TYPE="STORM"
        ;;
      ps3)
        ;;
      *)
        ;;
    esac
  fi

  if [[ -n "$4" ]]; then
    FILE_PREFIX="${4}_"
  else
    FILE_PREFIX=""
  fi

  if [[ -f "$1" ]]; then
    process_file "$1" "$2"
  elif [[ -d "$1" ]]; then
    process_directory "$1" "$2"
  fi
else
  print_usage
  exit
fi

The ffmpeg parameters are based off of Using ffmpeg to transcode video for the PS3. Hope his works for you too.

Share Button