Tag Archives: ffmpeg

VideoLAN releases VLC 3.0.7

largeVLCThe new 3.0.7 release for the VideoLAN multimedia player VLC was tagged in git almost two weeks ago but it took until today to find official tarballs on their web site. By the looks of the git log I can only assume that the VideoLAN developers needed to fix some annoying post-release bugs first.
The ChangeLog documents that the focus of the developers is mostly on the Android, MacOS and Windows platforms, presumably because that is where most of the issues are found? Also – through sponsoring by the European Commission’s EU-FOSSA2 program – more than 35 security bugs were fixed.
So I built new ‘vlc‘ packages for Slackware 14.2 and -current yesterday and uploaded them to my repository. Between the previous 3.0.6 and this 3.0.7 release I u
pdated some of the packages’ internal libraries: bluray, dav1d, dvdnav, ebml, matroska. If you want to know what you can expect from the VLC 3.x releases (as opposed to the 2.x releases which took way too many years to get obsoleted) you can read this older article on my blog.

A note about dependencies for the new package:

My Slackware packages for VLC are mostly self-contained with all of the supporting libraries compiled into the package. This makes for a minimal dependency on external libraries/packages. But there are some caveats with the new release: most importantly, its interface has switched from Qt4 to Qt5.
While Slackware contains a ‘qt4’ package, it does not contain ‘qt5’ and therefore, the vlc-3.x package introduces some new external dependencies, all related to the Qt5 GUI: SDL_sound, OpenAL, libxkbcommon, qt5. Hopefully Qt5 will get added to Slackware-current sometime in the future.
On Slackware 14.2, two more packages are needed – they have already been incorporated into Slackware-current: libinput and libwacom .

A note on compiling:

When you want to compile VLC 3 yourself, be sure to install java8 and apache-ant or your build will fail.
If you are running Slackware 14.2 you will additionally need the following four packages (required to compile the ‘dav1d‘ decoder): meson, ninja, python3, python3-setuptools .

Where to find the new VLC packages:

Rsync access is offered by the mirror server: rsync://slackware.nl/mirrors/people/alien/restricted_slackbuilds/vlc/ .

For BluRay support, read a previous article for hints about the aacs keys that you’ll need.

My usual warning about patents: versions that can not only DEcode but also ENcode AAC audio can be found in my alternative repository where I keep the packages containing code that might violate stupid US software patents.

Chromium 64 – and 32bit pain

The new release of the Chromium sources gives us version 64 of Google’s browser. I have created Slackware packages for you, but that was not entirely trivial.
The Chromium compilation on my 32bit Slackware OS kept failing on the embedded ffmpeg. I am afraid the fact that some of the bigger distros are dropping 32bit variants starts showing and things are coming apart at the seams.
When you are a developer and there’s no 32bit release of your favorite OS, this makes it quite difficult to test the validity of code paths when you only compile and test your code on a 64bit platform. This is what’s happening with Google’s Chromium code and it will probably only get worse.

For now, I could get away by disabling assembly code in the 32bit avcodec library, but in order to get that going I had to study the Chromium code carefully – Google does not use the standard autotools or cmake configurations that the Average Joe would employ when compiling ffmpeg, instead they re-invent the wheel every so often to keep everyone on edge. First it was Gyp, but that did not work out too well and the current fad is called GN (as Google state themselves “GN is a meta-build system that generates Ninja build files so that you can build Chromium with Ninja“).

Some time soon, I need to dissect Chromium’s embedded ffmpeg code, to see if I can get assembly code compiling again on 32bit. Else it may be more prudent to start depending on an external (system-wide) ffmpeg installation, which I can compile without any pain on 32bit Slackware.

We’re fine for now, at least. Let’s hope it does not get worse.

Get your chromium 64 packages for Slackware 14.2 and -current:

Cheers, Eric

Fixing audio sync with ffmpeg

The ffmpeg developers and their libav antipodes are engaged in a healthy battle. Ever since there was a fall-out and the ffmpeg developer community split in two (forking ffmpeg into “libav”), ffmpeg itself has seen many releases which tend to incorporate the good stuff from the other team as well as their own advancements.

Last in series is ffmpeg-0.9 for which I built Slackware packages (if you want to be able to create mp3 or aac sound, get the packages with MP3 and AAC encoding enabled instead.

The package will come in handy if you want to try what I am going to describe next.

Re-sync your movie’s audio.

You probably have seen the issue yourself too: for instance, I have a file “original.avi” which has an audio track (or “stream“) which is slightly out of sync with the video… just enough to annoy the hell out of me. I need to delay the audio by 0.2 seconds to make the movie playback in sync. Luckily, ffmpeg can fix this for you very easily.

Let’s analyze the available streams in the original video (remember, UNIX starts counting at zero):

$ ffmpeg -i original.avi

Input #0, avi, from ‘original.avi’:

Stream #0.0: Video: mpeg4, yuv420p, 672×272 [PAR 1:1 DAR 42:17], 23.98 fps, 23.98 tbr, 23.98 tbn, 23.98 tbc
Stream #0.1: Audio: mp3, 48000 Hz, stereo, s16, 128 kb/s

You see that ffmpeg reports a “stream #0.0” which is the first stream in the first input file (right now we have only one input file but that will change later on) – the video. The second stream, called “stream #0.1“, is the audio track.

What I need is to give ffmpeg the video and audio as separate inputs, instruct it to delay our audio and re-assemble the two streams into one resultant movie file. The parameters which define two inputs where the second input will be delayed for N seconds, goes like this:

$ ffmpeg -i inputfile1 -itsoffset N -i inputfile2

However, we do not have a separate audio and video tracks, we just have the single original AVI file. Luckily, the “inputfile1” and “inputfile2” can be the same file! We just need to find a way to tell ffmpeg what stream to use from which input. Look at how ffmpeg reports the content of input files if you list the same file twice:

$ ffmpeg -i original.avi -i original.avi

Input #0, avi, from ‘original.avi’:

Stream #0.0: Video: mpeg4, yuv420p, 672×272 [PAR 1:1 DAR 42:17], 23.98 fps, 23.98 tbr, 23.98 tbn, 23.98 tbc
Stream #0.1: Audio: mp3, 48000 Hz, stereo, s16, 128 kb/s

Input #1, avi, from ‘original.avi’:

Stream #1.0: Video: mpeg4, yuv420p, 672×272 [PAR 1:1 DAR 42:17], 23.98 fps, 23.98 tbr, 23.98 tbn, 23.98 tbc
Stream #1.1: Audio: mp3, 48000 Hz, stereo, s16, 128 kb/s

You see that the different streams in multiple input files are all numbered uniquely. We will need this defining quality. I colored the numbers with red & purple – these colors will show up in my example commands below.

Our remaining issue is that ffmpeg must be told that it has to use only the video stream of the first inputfile, and only the audio stream of the second inputfile. Ffmpeg will then have to do its magic and finally re-assemble the two streams into a resulting movie file. That resulting AVI file also expects video as the first stream, and audio as the second stream, just like our original AVI is laid out. Movie players will get confused otherwise.

Ffmpeg has the “map” parameter to specify this. I have looked long and hard at this parameter and its use… it is not easy for me to follow the logic. A bit like the git version control system, which does not fit into my brain conceptually, either. But perhaps I can finally explain it properly, to myself as well as to you, the reader.

Actually, we need two “map” parameters, one to map the input to the output video and another to map the input to the output audio. Map parameters are specified in the order the streams are going to be added to the output file. Remember, we want to delay the audio, so inherently the audio track must be taken from the second inputfile.

In the example below, the first “-map 0:0” parameter specifies how to create the first stream in the output. We need the first stream in the output to be video. The “0:0” value means “first_inputfile:first_stream“.

The second “-map 1:1” parameter specifies where ffmpeg should find the audio (which is going to be the second stream in the output). The value “1:1” specifies “second_inputfile:seccond_stream.

$ ffmpeg -i original.avi -itsoffset 0.2 -i original.avi -map 0:0 -map 1:1

There is one more thing (even though it looks like ffmpeg is smart enough to do this without explicitly telling so). I do not want any re-encoding of the audio or video to happen, so I instruct ffmpeg to “copy” the audio and video stream without intermediate decoding and re-encoding. The “‘-acodec copy” and “-vcodec copy” parameters take care of this.

We now have the information to write a ffmpeg commandline which takes audio and video streams from the same file and re-assembles the movie with the audio stream delayed by 0.2 seconds. The resulting synchronized movie is called “synced.avi” and the conversion takes seconds, rather than minutes:

$ ffmpeg -i original.avi -itsoffset 0.2 -i original.avi -map 0:0 -map 1:1  -acodec copy -vcodec copy synced.avi

Cheers, Eric

Re-encoding video for Android

So I bought myself a nice Android phone in april. It’s a HTC Desire, a real “tweakers’ phone”. It runs Android 2.1 – and before the end of the year, HTC should have an update to Android 2.2 available.

It is an impressive piece of work, and when I compare it to the iPhone or Windows Mobile based phones some of my friends/collegues carry with them, it clearly gives me a lot of freedom – I do not have any desire to “root” or “jailbreak” my phone in order to make it do what I want. I dream of putting Slackware on it, sometimes, but then I usually wake up fast… It’s a real Linux phone (with a SSH and a VNC client installed from the Android Market!), and the HTC Sense interface makes it just perfect and enjoyable as it is.

It goes without saying that I took a flat-fee Internet subscription; this kind of phone is not fully functional unless it is always online. I have been running a bandwidth metering app which told me that I transfered 440 MB in my first month. That would result in a pretty heavy bill if I did not have unlimited traffic.

I may write some more about my experiences with the Desire in future posts (so may exciting things to tell!), but for this one I want to talk about video playback on Android. Android has decent multimedia support out of the box, and audio as well as video players can make use of the standard codec libraries that the Android platform offers.

The “native format” I think you may call it that, for the Android seems to be H.264 video and AAC audio in a MP4 container. There are some limitations however, as people found out when trying unsuccessfully to play MP4  video files on their Android device that would not have had playback issues on a normal PC or mediabox.

Android only supports the H.264 baseline profile, meaning that some of the fancy encoding tricks that give you great video quality at lower bitrates (but require more processing power on playback) can not be used for videos you want to play on your Android device.

And rest assured, you do want to watch videos on the 800 x 480 pixel WVGA screen of the Desire! The AMOLED display has fantastic vibrant colours.

So, in order to create a video file that fits the display dimensions perfectly (without the scaling/resizing which would result in an ugly picture) and contains fully compatible MP4 video, I once again turned to my faithful companion… ffmpeg.

Here is a ffmpeg command line for you. This will take a video file (any supported format will work as input) and produce an Android-compliant MP4 file with WVGA dimensions (800 by 480 pixels). The input file will be transcoded in a two-pass process in order to achieve the best possible results. The transcoding will take a long time, so find something else to do in the meantime.

$ ffmpeg -i [inputfile] -threads 0 -vcodec libx264 \
    -vpre slow_firstpass -vpre baseline -b 480k -r 13 \
    -acodec aac -ab 128k -sameq \
    -pass 1 -f rawvideo -an -y /dev/null && \
    ffmpeg -i [inputfile] -threads 0 -vcodec libx264 \
    -vpre slow -vpre baseline -b 480k -r 13 \
    -acodec aac -ab 128k -ac 2 -sameq -pass 2 [outputfile].mp4

If you are on Slackware, then you get lucky. My ffmpeg packages (the variant that supports AAC audio encoding) are right here: http://slackware.org.uk/people/alien/restricted_slackbuilds/ffmpeg/

Have fun experimenting!

Eric

ffmpeg fully supports webm video

Today, the ffmpeg developers have completed the integration of the Google-sponsored VP8 codec and associated new WebM video container format.

The WebM video container format as well as VP8 decoding were added a little while ago, and the last part – VP8 video encoding – has entered the repository now. External patches are no longer required.

The ffmpeg package which I had built for Slackware 13.1 a couple of days ago, can encode VP8 too but I had to apply the patches made available by the WebM project (and which have now been more or less completely absorbed by ffmpeg). I’ll rebuild my ffmpeg package soon, getting rid of the patches, thus having a less complex build.

The only thing that seems to be missing compared to the patches from the WebM project, are the preset files specific to the VP8 encoder. As an example, ffmpeg has several preset files for x264 – they greatly simplify the ffmpeg commandline by gathering a lot of encoder settings into one configuration file. I’ll look at how I can add those presets to my package, in case the ffmpeg folk don’t do it first.

Eric