Have you ever asked yourself how sites like YouTube are working? Why it is possible grabbing videos from there that simple? How it’s built? I guess that’s some questions now. But if you don’t mind, I’ll answer some…
Let’s start with our web browser and hit a video portal. As an example we could even take YouTube:
Let’s assume that everything web based has to be downloaded to your computer to be displayed in your browser. In our case it’s a website and the embedded flash video object which should even be cached on disc. The clue here is the fact that if you hit the reload button, the video is already ready to be played instantly.
As a proof you can empty your browser cache and reload the site again – et voilà, we’re downloading it again. Having an empty browser cache is a nice thing, especially if you are looking for objects inside. Regarding our experiment here, we should have the swf flash movie in there, the website itself and some images.
But if you watch your cache carefully, there’s more in it – a strange file named .flv which leads back to Macromedia if you google for it. Let’s watch another video without clearing the cache and see what happens: The swf file stays pretty much the same – just the flv file count increases.
Now let’s add 1 and 1 and hope its result is 2: If I am right, the flv file is the video we’re searching for. For confirming my suspicion I just rename the one of the flv files to something more meaningful and move it out of the cache. If the flv file actually is the video it should be possible decoding it. A rather crude attempt would be trying mplayer:
~ $ mplayer PenguinsLinuxAd.flv MPlayer dev-SVN-r27120-4.3.1 (C) 2000-2008 MPlayer Team CPU: Genuine Intel(R) CPU T2500 @ 2.00GHz (Family: 6, Model: 14, Stepping: 8) CPUflags: MMX: 1 MMX2: 1 3DNow: 0 3DNow2: 0 SSE: 1 SSE2: 1 Compiled with runtime CPU detection. Playing PenguinsLinuxAd.flv. libavformat file format detected. [lavf] Video stream found, -vid 0 [lavf] Audio stream found, -aid 1 VIDEO: [FLV1] 480x360 0bpp 28.083 fps 0.0 kbps ( 0.0 kbyte/s) ========================================================================== Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family Selected video codec: [ffflv] vfm: ffmpeg (FFmpeg Flash video) ========================================================================== ========================================================================== Opening audio decoder: [mp3lib] MPEG layer-2, layer-3 AUDIO: 44100 Hz, 2 ch, s16le, 64.0 kbit/4.54% (ratio: 8000->176400) Selected audio codec: [mp3] afm: mp3lib (mp3lib MPEG layer-2, layer-3) ========================================================================== AO: [alsa] 48000Hz 2ch s16le (2 bytes per sample) Starting playback... VDec: vo config request - 480 x 360 (preferred colorspace: Planar YV12) VDec: using Planar YV12 as output csp (no 0) Movie-Aspect is undefined - no prescaling applied. VO: [xv] 480x360 => 480x360 Planar YV12 A: 7.4 V: 7.4 A-V: -0.000 ct: 0.000 0/ 0 5% 0% 2.5% 2 0
Believe it or not: It worked. So the fla file is definitively the video. My next idea is using ffmpg for recoding the fla file to something more ‘useful’ for me. What about mp4?
~ $ ffmpeg -i PenguinsLinuxAd.flv PenguinsLinuxAd.mp4 FFmpeg version UNKNOWN, Copyright (c) 2000-2008 Fabrice Bellard, et al. configuration: --prefix=/usr --libdir=/usr/lib --shlibdir=/usr/lib --mandir=/usr/share/man --enable-static --enable-shared --cc=i686-pc-linux-gnu-gcc --disable-altivec --disable-debug --disable-ffplay --disable-network --disable-optimizations --enable-libfaac --enable-libmp3lame --enable-libvorbis --enable-libxvid --enable-liba52 --enable-libdc1394 --enable-pthreads --enable-x11grab --enable-libfaad --enable-libamr-nb --enable-libamr-wb --enable-nonfree --enable-gpl --enable-postproc --enable-avfilter --enable-avfilter-lavf --enable-swscale --disable-stripping libavutil version: 49.6.0 libavcodec version: 51.53.0 libavformat version: 52.12.0 libavdevice version: 52.0.0 libavfilter version: 0.0.0 built on Jul 2 2008 16:52:29, gcc: 4.3.1 Seems stream 0 codec frame rate differs from container frame rate: 1000.00 (1000/1) -> 28.08 (337/12) Input #0, flv, from 'PenguinsLinuxAd.flv': Duration: 00:00:51.1, start: 0.000000, bitrate: 64 kb/s Stream #0.0: Video: flv, yuv420p, 480x360, 28.08 tb(r) Stream #0.1: Audio: mp3, 44100 Hz, stereo, 64 kb/s Output #0, mp4, to 'PenguinsLinuxAd.mp4': Stream #0.0: Video: mpeg4, yuv420p, 480x360, q=2-31, 200 kb/s, 28.08 tb(c) Stream #0.1: Audio: libfaac, 44100 Hz, stereo, 64 kb/s Stream mapping: Stream #0.0 -> #0.0 Stream #0.1 -> #0.1 Press [q] to stop encoding frame= 1420 fps= 46 q=31.0 Lsize= 2047kB time=50.6 bitrate= 331.6kbits/s video:1629kB audio:388kB global headers:0kB muxing overhead 1.477593%
And there we go. My theory is now that grabber software just does what we have done here manually – It downloads the flv file and recodes it to the format you want to have it.
Let’s assume we can reverse the whole process and convert video files into flv format which can be used for flash movies that can be played while being loaded – just like a video stream without a streaming server. I guess we do know the basics for doing our own player now – but that will be a topic for another post here.