Overlay Images on Video Using MPlayer and MEncoder
http://www.linuxjournal.com/content/overlay-images-video-using-mplayer-and-mencoder
In the ongoing saga of What doesn't work after the upgrade? I tried to run mylogo-overlay scriptthe other day to add the Linux Journal logo to a videoand, as you may have guessed, it didn't work.In this case I'd been forewarned...
When I say I'd been forewarned, what I mean is that a reader/commentor onone of my posts had alerted me to the fact that the feature in ffmpegthat I was using (the "vhook" feature) was being deprecated andhad already been removed from the development trunk.Of course I didn't do anything about it at the time, cuz hey, it's working for me.Well, now it's not!
The latest versions of ffmpeg have replaced the "vhook" mechanismwith "avfilters". These are not the actual overlay feature, rather theyare the way that "filters" were introduced into the processing chain.The new "avfilters" supposedly contain an "overlay" filter, but the avfiltercapability does not appear to be compiled into the openSUSE version of ffmpeg.I downloaded the latest ffmpeg from development repository and configured it and built it withthe avfilters enabled but that didn't produce the overlay filter either.Furthermore, I couldn't find anything in the downloaded source that appearedto be an overlay filter.I didn't feel like spending too much time trying to figure that out soI started looking for another solution.
I started looking at mencoder (part of the mplayer project) and noticed the -vf bmovl option,which is the bitmap overlay (bmovl) video filter (-vf).My first attempts with it didn't seem to be working but fortunately someoneelse had already figured it out and documented ithere.I thought it would be useful to reproduce the guts of it hereand add a bit of my own explanation as well as show a bit more of whatcan be done with this feature.The following is in essence the same as what you'll find at the link above,it overlays a bitmap onto a video and outputs a new video.
logo=logo.png
logo_width=600
logo_height=500
input_video=input.ogv
output_video=output.raw
rm -f $output_video
rm -f tfifo
rm -f tlogo.rgba
mkfifo tfifo
# Convert logo to RGBA.
convert $logo tlogo.rgba
# Copy logo to fifo.
(echo "RGBA32 $logo_width $logo_height 0 0 0 1" ; cat tlogo.rgba ) >tfifo &
# Convert input video with overlay from fifo.
mencoder -oac pcm -ovc raw -vf bmovl=0:0:tfifo -o $output_video $input_video
rm -f tfifo
rm -f tlogo.rgba
Mencoder does video encoding/converting much the same as ffmpeg does.One of its features is the ability to overlay data coming from a fifoon top of the video. In this case I'm taking the logo that I wantto overlay and converting it to RGBA32 format (which is essentiallyjust the uncompressed/unencode image data, 32 bits for each pixel).Then a mencoder fifo command and the RGBA32 data are fed into the fifo:
(echo "RGBA32 $logo_width $logo_height 0 0 0 1" ; cat tlogo.rgba ) >tfifo &
Mencoder runs in the foreground and converts the input video whilesimultaneously overlaying the data coming from the fifo.
mencoder -oac pcm -ovc raw -vf bmovl=0:0:tfifo -o $output_video $input_video
Note that for this to be of any value your logo (overlay bitmap) needsto have an alpha channel, i.e. it needs to be transparent everywhere except where the logo is.
The option of interest here is the -vf bmovl=0:0:tfifo option.This tells mencoder to apply a video filter (-vf) to the conversion/encoding,in this case the bitmap overlay filter (bmovl).The bmovl options are: hidden:opaque:fifo, where:
- hidden specifies whether the overlaid bitmap should hidden or visible,here 0 means visible (not hidden).
- opaque specifies whether the overlaid bitmap should allow the videoto show through or should block it, here 0 means transparent (not opaque)so that the transparent part of the logo bitmap does not block the rest of the video.
- fifo is just the name of the fifo file, here it is tfifo.
Also of interest is the fifo command that precedes the bitmap datain the fifo: RGBA32 $logo_width $logo_height 0 0 0 1.The RGBA32 specifies that the data is in RGBA32 format, itsparameters are "width height xpos ypos alpha clear", where:
- width / height specify the width and height of the bitmap data in pixels (not bytes).The bitmap file (the .rgba file) should be width * height * 4 bytes in size.Here the size of the logo overlay image is specified.
- xpos / ypos specify the X and Y position in the video at which the bitmap data is to be overlaid.Here the position is simply 0,0.
- alpha allows you to modify the alpha-ness of your bitmap (see below).Here 0 means don't change the alpha-ness of the bitmap.
- clear specifies if the existing bitmap data in the fifo is cleared beforeapplying the new bitmap data or if the new bitmap data is overwrittenon top of the existing bitmap data.Here 1 means clear the data, this may be moot since we only have one bitmap imagebut just in case there's garbage by default we specify 1 to clear it.
The alpha option probably requires a bit more explanation.The alpha option takes a value between -255 and 255.Values from -1 down to -255 make your bitmap ever more transparentallowing more of the video to show through, at -255 your bitmapis completely transparent and only the video will be visible.Values from 1 up to 255 make your bitmap ever more opaque allowingless of the video to show through,at 255 your bitmap is completely opaque and none of the video will be visibilein the area where the bitmap is.
To back up a bit, the mencoder/mplayer fifo is not a single command fifo, it canaccept multiple commands and bitmaps (if the command requires bitmap data).So by passing increasing or decreasing alpha values we can fade in and fade outbitmap overlays on a video.For example, we can fade in and then fade out a bitmap on top ofa playing video with the following sequence of commands:
rm -f tfifo
rm -f overlay.rgba
mkfifo tfifo
convert overlay.png overlay.rgba
(
alpha=-255
fade=20
while [[ $alpha -le 0 ]]
do
(echo "RGBA32 200 200 0 0 $alpha 1"; cat overlay.rgba) >tfifo
sleep 0.1
let t=alpha+fade
if [[ $alpha -ne 0 && $t -gt 0 ]]; then t=0; fi
alpha=$t
done
sleep 0.5
while [[ $alpha -ge -255 ]]
do
(echo "RGBA32 200 200 0 0 $alpha 1"; cat overlay.rgba) >tfifo
sleep 0.1
let t=alpha-fade
if [[ $alpha -ne 0 && $t -le -255 ]]; then t=-255; fi
alpha=$t
done
) &
pid=$!
mplayer -vf bmovl=0:0:tfifo video.ogv
rm -f tfifo
rm -f overlay.rgba
if kill -0 $pid; then kill -9 $pid; fi
You'll notice that this script uses mplayer and not mencoder.My initial thought was that I could do this with mencoder to overlay the sequenceof bitmaps as the video was encoded by mencoder and save the video in a new file,but so far I haven't been able to make that happen.Mencoder just encodes and so it doesn't sequence things atthe rate that data appears in the fifo: it just goes as fast as it can, whichmeans most of the fifo commands are missed.There may be a way to make it work, but I haven't found it yet.See the attached video for a sample of run of the script.
Back to the original problem though for just a second, that of overlaying the LJ logo on a video.Using mencoder turned out to be a less than useful solution since in addition tomy overlay script breaking, my video recorder solution (xvidcap) also isbroken after the upgrade.It captures video but it's jerky on playback.So that required me to change recorder programs and start using recordmydesktopfor recording video.It works reasonably well (it did not the last time I'd tried it) althoughxvidcap has a better UI.
However, recordmydesktop only captures .ogv video and mencoder won't output .ogv files.So I had to overlay the logo onto the captured .ogv file and output raw video.Then I had to use ffmpeg to convert the raw video (with the logo) backto .ogv (and to .mp4) so that I had both .ogv and .mp4 files.Unfortunately, ffmpeg screws up the audio/video sync in the converted .ogv file,so using that sequence of operations wasn't going to work very well.
My final solution will wait till next time. And my apologies for this twisted tail.
更多推荐
所有评论(0)