FFmpeg tricks and hints with some VLC grab sample too

Lot of you I know are trying to convert some multimedia file in some other..

The intention of this article is just to keep track of what was not so easy to perform

Did you ever ask yourself how to convert just the audio channel in an AVI film from AC3 to MP3?

———- 

In our example case the source Audio encoding is AC3 with audio 5.1 and yoy’d like to convert it in a much more supported mp3 audio, you must reduce audio from 5.1 channels to 2 with the option “-ac 2”.

Below there is an example of the command string:

   ffmpeg.exe -y -i “myvideo.avi” -async 1 -f avi -vcodec copy -acodec libmp3lame -ab 128k -ac 2   “myvideo(NEW).avi” 

That outputs the following:

Seems stream 0 codec frame rate differs from container frame rate: 23.98 (65535/2733) -> 23.98 (2997/125)
Input #0, avi, from ‘myvideo.avi’:
  Duration: 00:55:24.74, start: 0.000000, bitrate: 1767 kb/s
    Stream #0.0: Video: mpeg4, yuv420p, 640×272 [PAR 1:1 DAR 40:17], 23.98 tbr, 23.98 tbn, 23.98 tbc
    Stream #0.1: Audio: ac3, 48000 Hz, 5.1, s16, 384 kb/s
Output #0, avi, to ‘myvideo(NEW).avi’:
    Stream #0.0: Video: mpeg4, yuv420p, 640×272 [PAR 1:1 DAR 40:17], q=2-31, 23.98 tbn, 23.98 tbc
    Stream #0.1: Audio: libmp3lame, 48000 Hz, stereo, s16, 128 kb/s
Stream mapping:
  Stream #0.0 -> #0.0
  Stream #0.1 -> #0.1
Press [q] to stop encoding
[ac3 @ 0x271a230]frame sync error
Error while decoding stream #0.1
frame=79714 fps=172 q=-1.0 Lsize=  614666kB time=3324.74 bitrate=1514.5kbits/s
video:557553kB audio:51950kB global headers:0kB muxing overhead 0.847237%

I don’t know why the “frame sync error” occurred, but anyway the output AVI was perfectly working.

The option really necessary was the  ” -async 1 ” option to avoid the typical audio/video async .

———- 

Other example: extract a sample jpeg image from the 10th second of the MOV video.

Extract  from MOV video myvideo.MOV:

   ffmpeg.exe -v 8 -i myvideo.MOV -r 1 -s 640×480 -vframes 1 -ss 10 -f image2 myvideo.MOV-VIDEO-PREVIEW.jpeg

———- 

Convert MOV video to OGG container with vorbis audio and theora video (Ogg Theora even named OGV for OGgVideo):

   ffmpeg.exe -v 8 -i myvideo.MOV -f ogg -vcodec libtheora -ab 128K -acodec libvorbis -b 2000K myvideo.ogv

further reduce audio size using OGG Vorbis audio variable bit rate: 

   ffmpeg.exe -v 8 -i myvideo.MOV -f ogg -acodec libvorbis  -aq 1 -vcodec libtheora -ab 2000K myvideo.ogv

-aq 1  stands for Audio Quality. It’s valid for ogg only (and other codecs but not all) and is variable rate about equivalent of about 80Kbit/sec fixed rate.

-aq 0 is the lowest and it’s the equivalent of about 60Kbit/sec fixed rate.

———- 

Convert MOV video to FLV (Adobe flash):

   ffmpeg.exe -v 8 -i myvideo.MOV -f flv -ab 128K -acodec libmp3lame -b 2000K myvideo.flv

———-  

Convert MP3, OGG or whatever audio back to standard WAV:

   ffmpeg.exe -v 10 -i “my audio.mp3” -f wav -acodec pcm_s16le  myaudio.wav

———-  

Extract or cut audio chunk (10 seconds) from a source and re-encode it in OGG vorbis (start seconds expressed in HH:MM:SS):

   ffmpeg -y -i “my audio.mp3” -ss 00:05:00 -t 10 -acodec libvorbis -aq 5 “my audioExtract.ogg”

alternative (seconds expressed in cent of seconds HH:MM:SS.cc):

   ffmpeg -y -i “my audio.mp3” -ss 00:05:00.55 -t 10 -acodec libvorbis -aq 5 “my audioExtract.ogg”

alternative (seconds expressed in just seconds SSSSS):

   ffmpeg -y -i “my audio.mp3” -ss 300 -t 10 -acodec libvorbis -aq 5 my audioExtract.ogg”

extract from “my audio.mp3” only 10 seconds of soundstream starting from 301st second to 310th second and encode it in ogg writing to “my audio OggEncoded.ogg”.

———-  

Now suppose you have an audio/video stream like this:

W:\PortableApps\ffmpeg-0.5\FFmpeg-svn-19159>ffmpeg.exe -i “D:\my film.avi”
FFmpeg version SVN-r19159-Sherpya, Copyright (c) 2000-2009 Fabrice Bellard, et al.
  libavutil     50. 3. 0 / 50. 3. 0
  libavcodec    52.30. 2 / 52.30. 2
  libavformat   52.34. 0 / 52.34. 0
  libavdevice   52. 2. 0 / 52. 2. 0
  libavfilter    0. 5. 0 /  0. 5. 0
  libswscale     0. 7. 1 /  0. 7. 1
  libpostproc   51. 2. 0 / 51. 2. 0
  built on Jun 12 2009 04:25:02, gcc: 4.5.0 20090517 (experimental)
[NULL @ 0x2828070]Invalid and inefficient vfw-avi packed B frames detected
Input #0, avi, from ‘D:\
my film.avi’:
  Duration: 01:31:20.20, start: 0.000000, bitrate: 1072 kb/s
    Stream #0.0: Video: mpeg4, yuv420p, 672×286 [PAR 1:1 DAR 336:143], 25 tbr, 25 tbn, 25 tbc
    Stream #0.1: Audio: mp3, 44100 Hz, stereo, s16, 112 kb/s
At least one output file must be specified

If you would like to extract or “cut-away” 3 minutes (180 secs) of audio chunk from this audio/video source and keep encoding (seconds expressed in HH:MM:SS):

   ffmpeg -y -i “my audio.avi” -ss 01:25:00 -t 180 -acodec copy “my audioExtract.mp3″

I’ll get my MP3 audio sound encoded in the same way.

   ffmpeg -y -v 10  -i “my audio.avi” -ss 01:25:00 -t 180-ab 128K -acodec libmp3lamemy audioExtract.mp3″

I’ll get my MP3 audio sound encoded in mp3 128K. Of course, if source is 112K I won’t get any better sound only waste of more space 🙁 !!

———- 

This is how to add MetaTags like Interpreter and Title of an audio song:

The tag is: -metadata string=string

Like: -metadata Title=”This is my title” -metadata Artist=”and this is the Artist”

The problem IS that for the OGG audio at this moment there seem to be a bug so that VLC doesn’t recognize the metatag and ffmpeg too.

And you can even copy metadata from input to output with the command line option:

-map_meta_data outfile:infile

never tried to tell the truth!!!

———- 

 

Just to verify the encoding streams; if audio or video or both and their size:

C:\ffmpeg-0.5\FFmpeg-svn-19159>ffmpeg.exe -i mysound.ogg
FFmpeg version SVN-r19159-Sherpya, Copyright (c) 2000-2009 Fabrice Bellard, et al.
  libavutil     50. 3. 0 / 50. 3. 0
  libavcodec    52.30. 2 / 52.30. 2
  libavformat   52.34. 0 / 52.34. 0
  libavdevice   52. 2. 0 / 52. 2. 0
  libavfilter    0. 5. 0 /  0. 5. 0
  libswscale     0. 7. 1 /  0. 7. 1
  libpostproc   51. 2. 0 / 51. 2. 0
  built on Jun 12 2009 04:25:02, gcc: 4.5.0 20090517 (experimental)
Input #0, ogg, from ‘
mysound.ogg’:
  Duration: 00:00:15.62, start: 0.000000, bitrate: 158 kb/s
    Stream #0.0: Audio: vorbis, 44100 Hz, stereo, s16, 160 kb/s

At least one output file must be specified

The error above can be managed but is OK you can grab the output via PHP in order to get codec infos and audio length.

———- 

For a complete article I cannot avoid a reverse example of conversion: Ogg/Theora -> AVI (mpeg h264+mp3)

 

      ffmpeg.exe -y -v 10 -i C:\test\2009-12-07_00.00.01-Video.ogv -ss 00:03:04 -async 1 -f avi -acodec libmp3lame -ab 128K -vcodec libx264 -b 12K C:\test\2009-12-07_00.00.01-Video.mpg

FFmpeg version SVN-r19159-Sherpya, Copyright (c) 2000-2009 Fabrice Bellard, et al.
  libavutil     50. 3. 0 / 50. 3. 0
  libavcodec    52.30. 2 / 52.30. 2
  libavformat   52.34. 0 / 52.34. 0
  libavdevice   52. 2. 0 / 52. 2. 0
  libavfilter    0. 5. 0 /  0. 5. 0
  libswscale     0. 7. 1 /  0. 7. 1
  libpostproc   51. 2. 0 / 51. 2. 0
  built on Jun 12 2009 04:25:02, gcc: 4.5.0 20090517 (experimental)
[theora @ 0x27ca990]7 bits left in packet 82
Input #0, ogg, from ‘C:\test\2009-12-07_00.00.01-Video.ogv‘:
  Duration: 03:22:29.47, start: 0.000000, bitrate: 641 kb/s
    Stream #0.0: Audio: vorbis, 44100 Hz, stereo, s16, 128 kb/s
    Stream #0.1: Video: theora, yuv420p, 384×288, PAR 1:1 DAR 4:3, 25 tbr, 25 tbn, 25 tbc
    Stream #0.2: Invalid Codec type -1
[libx264 @ 0x280ad60]using SAR=1/1
[libx264 @ 0x280ad60]using cpu capabilities: MMX2 SSE2Fast SSSE3 Cache64
[libx264 @ 0x280ad60]profile Baseline, level 2.1
[theora @ 0x27ca990]7 bits left in packet 82
Output #0, avi, to ‘C:\test\2009-12-07_00.00.01-Video.mpg‘:
    Stream #0.0: Video: libx264, yuv420p, 384×288 [PAR 1:1 DAR 4:3], q=2-31, 512 kb/s, 25 tbn, 25 tbc
    Stream #0.1: Audio: libmp3lame, 44100 Hz, stereo, s16, 128 kb/s
Stream mapping:
  Stream #0.1 -> #0.0
  Stream #0.0 -> #0.1
Press [q] to stop encoding
[vorbis @ 0x279a090]Not a Vorbis I audio packet.
adding 116 audio samples of silence  10kB time=10000000000.00 bitrate=   0.0kbits/s dup=0 drop=0
adding 99182 audio samples of silence652kB time=341.32 bitrate= 663.7kbits/s dup=0 drop=0
adding 67437 audio samples of silence663kB time=341.60 bitrate= 663.4kbits/s dup=0 drop=0
adding 35693 audio samples of silence
frame=58182 fps=  7 q=26.0 size=  188603kB time=2327.28 bitrate= 663.9kbits/s dup=0 drop=0

Note:  As it was a recording it started some minutes before and so the -ss option to keep off the first 3 minutes and 4 seconds (-ss 00:03:04).

 

The correct way to just repair without re-encoding would have been:

      ffmpeg.exe -v 10 -i C:\test\2009-12-07_00.00.01-Video.ogv -ss 00:03:04 -t 01:56:10 -async 1 -acodec libvorbis -aq 3 -vcodec copy C:\test\2009-12-07_00.00.01-VideoOriginalasync1.ogv

 

The problem is that this solution do not prevent asynch from audio/video for which I’ll have to experiment video drop frame option:

`-vsync parameter’
Video sync method. Video will be stretched/squeezed to match the timestamps, it is done by duplicating and dropping frames. With -map you can select from which stream the timestamps should be taken. You can leave either video or audio unchanged and sync the remaining stream(s) to the unchanged one.

 

I really don’t know what happened to “Stream #0.2: Invalid Codec type -1” but this was kept off re-encoding everything. The error arose using VLC client to grab a streaming TV with a command line like the following:

    “”C:\vlc.exe” “http://mystream” –vlm-conf “C:\VLCData\settings\vlcrc.cfg” –no-plugins-cache –config “C:\VLCData\settings\vlcrc.cfg” –http-user-agent=”Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.6) Gecko/2009020911 Ubuntu/8.10 (intrepid) Firefox/3.1.0;” –sout=#transcode{vcodec=theora,vb=512,scale=1,acodec=vorb,ab=128
,channels=2,samplerate=44100}:duplicate{dst=std{access=file,mux=ogg,dst=2009-12-07_00.00.00-Video.ogv},dst=display} “

The  “–http-user-agent=” used is necessary as some streamer only support streams towards “supposed” http clients.

I don’t know what happened as the required output channels where only 2: 

  1. video theora and  
  2. audio ogg (stereo)

the third was really unexpected!
Another comment is necessary for audio video synch neithere “-async 1” nor “-vsync 1” helped even when used with the 10 parameter. Remember that 1 is a special case in which ONLY at the stream start a “proper” adjustment is made. Instead with parms other than 1 it seems that a check is made against a timestamp. At the time of writing though I wasn’t able to get a synchronized output. Video is always far behind the audio.

 

———-

By the way an input “file” can even be “instead” an http stream. As an example, this is an “ILoveRadio” capture of 3 minutes:

      ffmpeg.exe -v 0 -i http://iloveradio.newradiostream.com:8090/ -t 00:03:00 -acodec copy -map_meta_data ILoveRadioTest2.mp3:http://iloveradio.newradiostream.com:8090/  ILoveRadioTest3.mp3

FFmpeg version SVN-r19159-Sherpya, Copyright (c) 2000-2009 Fabrice Bellard, et al.
  libavutil     50. 3. 0 / 50. 3. 0
  libavcodec    52.30. 2 / 52.30. 2
  libavformat   52.34. 0 / 52.34. 0
  libavdevice   52. 2. 0 / 52. 2. 0
  libavfilter    0. 5. 0 /  0. 5. 0
  libswscale     0. 7. 1 /  0. 7. 1
  libpostproc   51. 2. 0 / 51. 2. 0
  built on Jun 12 2009 04:25:02, gcc: 4.5.0 20090517 (experimental)
[mp3 @ 0x22aeb80]big_values too big
[mp3 @ 0x22aeb80]overread, skip -7 enddists: -6 -6
[mp3 @ 0x22aeb80]overread, skip -5 enddists: -4 -4
Input #0, mp3, from ‘http://iloveradio.newradiostream.com:8090/’:
  Duration: N/A, start: 0.000000, bitrate: 192 kb/s
    Stream #0.0: Audio: mp3, 44100 Hz, stereo, s16, 192 kb/s
Output #0, mp3, to ‘ILoveRadioTest3.mp3’:
    Stream #0.0: Audio: libmp3lame, 44100 Hz, stereo, s16, 192 kb/s
Stream mapping:
  Stream #0.0 -> #0.0
Press [q] to stop encoding
size=    4220kB time=180.01 bitrate= 192.0kbits/s
video:0kB audio:4220kB global headers:0kB muxing overhead 0.000741%

 

 

———-

In attacment there is the FFMpeg.exe binaries downloaded from (as far as I remember):

http://oss.netfarm.it/mplayer-win32.php  

that has a link to:

http://sourceforge.net/projects/mplayer-win32/files/FFmpeg/revision%2020472/FFmpeg-svn-20472.7z/download

Then I attached a software supplied by me AS IS. It is freeware, RUN AT YOUR OWN RISK!!!

It searches for all *.MOV files in the current dir you’ll run the AvcV1.8.exe and all recursive subdirs. It will converts ALL met *.MOV (h264) files creating:

  1. samefile.MOV.jpeg  (a Preview Image of 640×480 after 10 seconds of the MOV file)
  2. samefile.MOV.ogg   (an ogg compatible and visible with FireFox V.3.5, 2Megabit/sec encoded hi quality))
  3. samefile.MOV.flv     (a flash file 2Megabit/sec encoded hi quality)

 

———-  

Joining two video file is not directly supported by FFMpeg but in the http://ffmpeg.org/faq.html you can find a solution:

 

3.17 How can I join video files?

A few multimedia containers (MPEG-1, MPEG-2 PS, DV) allow to join video files by merely concatenating them.

Hence you may concatenate your multimedia files by first transcoding them to these privileged formats, then using the humble cat command (or the equally humble copy under Windows), and finally transcoding back to your format of choice.

ffmpeg -i input1.avi -sameq intermediate1.mpg
ffmpeg -i input2.avi -sameq intermediate2.mpg
cat intermediate1.mpg intermediate2.mpg > intermediate_all.mpg
ffmpeg -i intermediate_all.mpg -sameq output.avi

Notice that you should either use -sameq or set a reasonably high bitrate for your intermediate and output files, if you want to preserve video quality.

Also notice that you may avoid the huge intermediate files by taking advantage of named pipes, should your platform support it:

mkfifo intermediate1.mpg
mkfifo intermediate2.mpg
ffmpeg -i input1.avi -sameq -y intermediate1.mpg < /dev/null &
ffmpeg -i input2.avi -sameq -y intermediate2.mpg < /dev/null &
cat intermediate1.mpg intermediate2.mpg |\
ffmpeg -f mpeg -i - -sameq -vcodec mpeg4 -acodec libmp3lame output.avi

Similarly, the yuv4mpegpipe format, and the raw video, raw audio codecs also allow concatenation, and the transcoding step is almost lossless. When using multiple yuv4mpegpipe(s), the first line needs to be discarded from all but the first stream. This can be accomplished by piping through tail as seen below. Note that when piping through tail you must use command grouping, { ;}, to background properly.

For example, let’s say we want to join two FLV files into an output.flv file:

mkfifo temp1.a
mkfifo temp1.v
mkfifo temp2.a
mkfifo temp2.v
mkfifo all.a
mkfifo all.v
ffmpeg -i input1.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null &
ffmpeg -i input2.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null &
ffmpeg -i input1.flv -an -f yuv4mpegpipe - > temp1.v < /dev/null &
{ ffmpeg -i input2.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp2.v ; } &
cat temp1.a temp2.a > all.a &
cat temp1.v temp2.v > all.v &
ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i all.a \
-f yuv4mpegpipe -i all.v \
-sameq -y output.flv
rm temp[12].[av] all.[av]

———-  

Raising the volume can be a very useful audio “effect” when a recording has a very low volume.In my tests executed with FFmpeg-svn-20900 it seems that the -vol option does work only reducing the volume.  So this is how to do it during a transcoding:

    ffmpeg -y -i ABS-06-nelly.mp3 -acodec libmp3lame -ab 128K -vol 256 ABS-06-nelly2.mp3

 doesn’t have any effect on the volume as 256 is 100% volume. But this instead:

    ffmpeg -y -i ABS-06-nelly.mp3 -acodec libmp3lame -ab 128K -vol 50 ABS-06-nelly2.mp3

Reduces by more than 1/5 the volume of input file.

To raise the volume you have to use something like:

    ffmpeg -y -i ABS-06-nelly.mp3 -acodec libmp3lame -ab 128K -vol 512 ABS-06-nelly2.mp3

But I’m not feeling it really raise the volume that much.. 😉

And by the way with this version, I getthe following errors.. I don’t know if they’re real errors or just this version is not enough stable:

  [mp3 @ 023f8260]Header missingtrate= 128.0kbits/s
  Error while decoding stream #0.0
  [libmp3lame @ 0244cbd0]lame: output buffer too small (buffer index: 9195, free bytes: 597)
  Audio encoding failed

 

———-  

 

I don’t know why, but using PHP you need to specify -v 0 in order not to stuck with your encoding in batch executions under Apache!!

More on FFmpeg and PHP programming, later on this site!

 

That’s all for now.

L.R.