My thoughts on Slackware, life and everything

Month: December 2011

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

KDE 4.7.4 – last of the 4.7 series

The KDE team has already released two betas of the upcoming KDE 4.8, but I am not so much in a hurry. First things first! There is the last update in the 4.7 series, which was released earlier today. The Slackware KDE 4.7.4 packages are ready and you can grab them if you like.

For those who are trying my 4.7 packages for the first time and wonder why the hell am I offering so many packages, please read my earlier post about KDE 4.7.0 which explains more about splitting KDE for Slackware into many more (and smaller) packages.

My packages have been compiled on Slackware-current. Even though several people had reported that previous KDE 4.7 packages worked fine on Slackware 13.37, there has been an incompatible update to slackware-current recently (the glibc package). As a result, these new KDE 4.7.4 packages will only work on slackware-current (64-bit and 32-bit). If you are running Slackware 13.37, then stick to your currently installed version of KDE, or install my 4.6.5 packages (or upgrade your Slackware to -current).

Read the accompanying README file for installation and upgrade instructions!

Some of the highlights of these KDE packages:

  • Since this is the last edition of KDE 4.7, I decided to add updated versions of KDE related packages that I do not usually include: amarok, skanlite, ktorrent. I have no idea when Slackware-current will start moving again, but this set of packages allows you to have a complete, stable and up to date KDE environment for the time to come.
  • There are several updated dependencies compared to Slackware’s own KDE 4.5.5: PyQt, QScintilla, akonadi, attica, clucene, ebook-tools, hunspell, libdbusmenu-qt, phonon, polkit-qt-1, qt, raptor2, rascal, redland, shared-desktop-ontologies, sip, soprano, strigi, system-config-printer and virtuoso-ose.
  • In comparison with my previous KDE 4.7.3 the number of updated dependencies is a much smaller: attica, libktorrent, libmsn, and soprano. Note that libktorrent is now located in “deps” instead of “kde” directory because it has become a dependency for more than just ktorrent.
  • KDE dpendencies that are not part of Slackware 13.37 at all (yet): grantlee, herqq, libatasmart, libbluedevil, libssh, phonon-gstreamer, phonon-xine, sg3_utils and udisks. Note that I added phonon-gstreamer and phonon-xine only after I had already released KDE 4.7.0 packages because people reported that they no longer had sound. These two packages solve that issue.

Also worth mentioning is some stuff which is not completely new, since I added these to previous releases of KDE 4.7 already (but if you are new to KDE 4.7 this will certainly interest you):

  • You will find some additional useful new applications, which are not part of the KDE core set. They are new, compared to Slackware’s own version of KDE. I already added bluedevil to my 4.6.5 package-set. Bluedevil is the new KDE bluetooth stack with a nice GUI, based on the BlueZ libraries already present in Slackware. And with KDE 4.7.0, I included kplayer, a KDE front-end to MPlayer. With KDE 4.7.2, I added Quanta Plus, which disappeared from KDE4 because that migrated from Qt3 to Qt4. It is now being worked on again, but no longer as a standalone application – instead it is available as a plugin to the Kdevelop Platform. And with KDE 4.7.3, I added a native WICD applet for KDE, called “wicd-kde“. It can replace the GTK based “wicd-client” which is part of the wicd package.
  • I also added oxygen-gtk, which is not really an application, but a theme engine. It (optionally) makes GTK applications visually blend in with KDE’s own Oxygen theme. There is a README in its documentation directory which explains how to enable it.
  • Since KDE 4.7.2, I include a “test” directory. This directory contains Networkmanager, plus some other dependencies, that allow to create a KDE package for “networkmanagement” which is an applet plus a kcontrol (i.e. a plugin for KDE’s systemsettings). This test, which sofar has proved to be quite successful, allows you to switch from WICD to NetworkManager as your basic network management service. The applet plus kcontrol make it quite easy to configure your network in KDE (wired, wireless, vpn, dsl and mobile broadband). No new Gnome libraries had to be added for this (NM itself plus its supporting tools have no dependency on the rest of Gnome). I have added NM installation/configuration instructions to the README.

A small aside I want to mention:

There was one bug that has been plaguing me ever since KDE 4.7.0 (and I may have had this occasionally before 4.7 but I cannot remember for certain). The bug seems to be ALSA related, but unsure is whether the fault is with ALSA or with KDE. The “kde deamon (kded4)” crashes every time when I login to KDE. Surely, it will automatically restart but it is ugly. It was still there in KDE 4.7.3 and it is described in these two bug reports:

There is a workaround though. If you disable “KMixD Mixer Service (kmixd)” from being started at logon, the crash does not occur anymore and so far I have not found any lost functionality. My laptop’s hardware volume keys still work, and the KDE mixer applet is still functional. Go to System Settings > Startup and Shutdown > Service Manager, and remove the check in the checkbox for KMix Daemon.

The KDE 4.7.4 packages for Slackware-current are available for download from my “ktown” repository and several mirrors (taper will be in sync when I post this, the other mirrors will have to catch up):

Have fun! Eric

Recipe: traditional moussaka

Last weekend I prepared another diner which I had not cooked for a very long time.

I love rich oven dishes, and traditional greek “moussaka” is a long-time favourite of mine. I learnt how to cook it while I lived in a student home.

There are many variants of moussaka which do not honour the original method of preparation. Things like potatoes do not belong in moussaka.. while cinnamon, oregano and lots of vegetable oil do belong! I try to follow a more traditional approach. Any greek readers, please come up with improvements if your Mom had a different recipe!

The result will be a heavenly smell in your kitchen while the dish is finishing in the oven. Your belly will be all warm and fuzzy after emptying your plate.

The prime ingredient in moussaka is the aubergine, or eggplant. This fruit (commonly mistaken for a vegetable!)  is one of the family of nightshades – like tomatoes, cayenne, and even tobacco. It’s easy to spot in the pic below that this is a fruit – it contains seeds. Like with tomatoes and potatoes, there is a certain bitterness in the eggplant which you can eliminate by “sweating”, steaming or grilling. I am going to grill the eggplant.

Another ingredient which deserves a separate mention, is the béchamel sauce. This sauce of butter, flour and milk is thought by many people to be difficult to make, but in fact it is dead easy, The béchamel, along with grated cheese, will create a beautiful soft-crunchy crust on top of the moussaka.

Ingredients (4 persons):

  • One eggplant
  • one onion, chopped up
  • three cloves of garlic, chopped up (do not squeeze them out)
  • 400 grams of minced lamb meat (beef will do as well)
  • one can of peeled tomatoes
  • 150ml olive oil (sunflower oil will do)
  • plenty of cinnamon and oregano
  • pepper, salt
  • 50 grams of butter
  • 50 grams of flour
  • 1/2 liter of milk
  • 200 grams of grated young cheese

Preparation:

  • Pre-heat the oven to 200°C
  • First we create the meat/tomato sauce. Heat a few tablespoons of oil in a pan, add the chopped onion and garlic and let it cook for a few minutes until the onion gets a nice golden-brown color. Keep stirring with a wooden spoon to prevent the garlic from getting black and bitter.
  • Add the minced meat, turn up the heat and let it cook for a few minutes until all of the meat has turned brown. Add salt and pepper to taste. Add lots of cinnamon powder and oregano. Don’t hold back! In this dish, more is better. In particular, you can never have too much cinnamon.
  • Leave the meat and onions to simmer on a low fire for a few minutes. Then turn up the heat under the pan again, and add the peeled tomatoes. If these are not chopped-up tomato parts, you cut the tomatoes up into smaller pieces before you add them to the pan. Allow the tomato to integrate with the meat and onions; there is a lot of liquid in the tomatoes which needs to boil away. Then turn down the heat and leave it to simmer on low heat with the lid on the pan. We will not need the meat sauce until later and we might just as well allow the flavors to mix for as long as possible – it will enhance the dish. Don’t forget to taste! It may require more salt and cinnamon.
  • We continue with the béchamel and the eggplant. You can work on these in parallel.

Eggplant:

  • If you have a grill-pan, put it on the stove and heat it up. If you do not have a grill-pan, you can do with a flat frying pan, or use the oven grill – we are going to grill the eggplant
  • Cut the top and bottom off the eggplant, removing the leaves. Cut the eggplant along its long side in slices of 0.5 cm (0.2 inch). Once exposed to the air, the slices will color brownish after a while so it is best to cut only a few slices at a time and apply the next step in the preparations.
  • Brush both sides of an eggplant slice with olive oil and place it in the grill-pan. Leave it on the grill for a minute or two and then turn it over. This will make it tender, eliminate the bitter taste and sweeten the eggplant. You can put several slices in the grill pan at a time, to speed up the process.

Béchamel:

  • Melt the butter in a pan (low heat) or in the microwave.
  • Add the flour (all at once) and keep stirring the mixture (with the heat kept low!) so that you get a smooth mixture. Let the mixture (the “roux”) cook on low heat for about 4 minutes, this will eliminate the floury taste. While stirring, take the pan off the fire from time to time to keep the flour from turning brown – we want the béchamel to keep its white color.
  • Gently, add the milk while you keep stirring the mix. Let it cook for another 10 minutes at least, stirring the béchamel sauce from time to time to keep it smooth and prevent burning. Then turn off the heat.

We continue with the final part:

  • Brush the inside of an oven dish with olive oil. More is better. The oil will prevent the eggplant from sticking to the dish when it bakes in the oven.
  • Cover the bottom of the oven dish with slices of grilled eggplant. On top of that, pour half of your meat/tomato sauce until it covers the eggplant. Then, add a new layer of eggplant slices and on top of that you pour the remaining half of the meat/tomato sauce. Sprinkle this with a generous amount of grated cheese. If you still have eggplant slices left, you can place those on top.
  • Grab the pan with the béchamel sauce,, and pour it over the other ingredients in the oven dish. It will trickle down into the dish, but the majority will remain on top. Sprinkle some more grated cheese over the béchamel. Not too much cheese, the béchamel must remain visible! We do not want a burnt cheese crust, we want to create a soft crust of cheese mixed with the béchamel.
  • Place the dish in the middle of your oven and let it bake for 20 minutes. The moussaka is ready when the crust starts turning light brown.

Serve it with some greek white wine like retsina.

I could eat this every week… but it took years to find an opportunity cook it because my son dislikes the taste of the eggplant. He still did not like it much… but he ate it all anyway.

Enjoy your meal!

Eric

© 2024 Alien Pastures

Theme by Anders NorenUp ↑