Thread: [Vnc2swf-users] Shrinking a vnc2flv file
Status: Alpha
Brought to you by:
euske
From: Brian C. <B.C...@po...> - 2009-11-04 23:26:29
|
This isn't exactly a vnc2flv problem, but I thought this would be a reasonable place to ask anyway. I have used vnc2flv to create a screencast which is 9 mins 27 secs long, at a screen size of 992 x 608. [The large screen area is because the app I'm capturing really needs this much space]. The resulting file is 19.1MB. Now, I would like to reduce the file size significantly. I am happy to reduce the picture 2:1 so that it becomes 496 x 304. I can do this using ffmpeg (*), and the picture quality is usable for my purpose: ffmpeg -i in.flv -s 496x304 -r 4 -acodec copy -y out.flv However the resultant file is still 12MB in size, even after dropping the output frame rate to 4fps! I tried outputting using the 'flashsv' codec (**): ffmpeg -i in.flv -s 496x304 -vcodec flashsv -r 4 -acodec copy -y out-flashsv.flv but now the resultant file is even larger, at 16.2MB. LAME tells me it's encoding the audio at 32kbps mono, in which case that only accounts for about 2.2MB of the total. Here's what 'ffplay -stats' says about the source file (19MB): Input #0, flv, from 'in.flv': 0KB vq= 0KB sq= 0B Duration: 00:09:26.66, start: 0.000000, bitrate: 32 kb/s Stream #0.0: Video: flashsv, bgr24, 992x608, 12 tbr, 1k tbn, 1k tbc Stream #0.1: Audio: mp3, 22050 Hz, mono, s16, 32 kb/s 23.81 A-V: 4.297 aq= 79KB vq= 498KB sq= 0B and the version shrunk as 'flv' (12MB): Input #0, flv, from 'out.flv': vq= 0KB sq= 0B Duration: 00:09:27.00, start: 0.000000, bitrate: 232 kb/s Stream #0.0: Video: flv, yuv420p, 496x304, 200 kb/s, 4 tbr, 1k tbn, 1k tbc Stream #0.1: Audio: mp3, 22050 Hz, mono, s16, 32 kb/s 23.49 A-V: -0.027 aq= 79KB vq= 170KB sq= 0B and the version shrunk as 'flashsv' (16MB): Input #0, flv, from 'out-flashsv.flv': Duration: 00:09:27.00, start: 1257374691.83 A-V: 0.000 aq= 0KB vq= 0KB 0.000000, bitrate: 232 kb/s Stream #0.0: Video: flashsv, bgr24, 496x304, 200 kb/s, 4 tbr, 1k tbn, 1k tbc Stream #0.1: Audio: mp3, 22050 Hz, mono, s16, 32 kb/s 23.00 A-V: -0.015 aq= 80KB vq= 232KB sq= 0B So, do you have any suggestions about how I could improve this? Have I missed an important option from ffmpeg? Is there a better way to shrink a vnc2flv stream? Many thanks, Brian. (*) ffmpeg is the stock version from Ubuntu Jaunty: ii ffmpeg 3:0.svn20090303-1ubuntu6 multimedia player, server and encoder ii gstreamer0.10-ffmpeg 0.10.6.2-1ubuntu2 FFmpeg plugin for GStreamer ii libavcodec-unstripped-52 3:0.svn20090303-1ubuntu2+unstripped1 ffmpeg codec library ii libavdevice52 3:0.svn20090303-1ubuntu6 ffmpeg device handling library ii libavfilter0 3:0.svn20090303-1ubuntu6 ffmpeg video filtering library ii libavformat52 3:0.svn20090303-1ubuntu6 ffmpeg file format library ii libavutil-unstripped-49 3:0.svn20090303-1ubuntu2+unstripped1 ffmpeg utility library ii libpostproc51 3:0.svn20090303-1ubuntu6 ffmpeg video postprocessing library ii libswscale0 3:0.svn20090303-1ubuntu6 ffmpeg video scaling library (**) According to Wikipedia, flash video supports two tiling codecs specifically for screencasts, so I guess that 'flashsv' is one of those. I also saw a recent posting to this list showing '-vcodec flashsv'. |
From: Josh H. <the...@gm...> - 2009-11-04 23:58:14
|
If you're familiar with image formats, then this analogy might help: jpeg : flv png : flashsv That is to say that flashsv is lossless, preserving every pixel exactly. Quite often this works out very well for screencasts where apps tend to have sections of exactly the same color and fewer colors than something like a photo. All of my screen recordings have fared far better as flashsv (smaller file size AND better quality), but that's not going to be the case 100% of the time. Without seeing your screencast specifically, I can only make some general suggestions: - Turn off wallpaper, use only a solid colored background. - Record at the native resolution (if you transcode to a smaller resolution, the antialiasing will add complexity to the image, increasing the file size -- sometimes larger than the original) - Don't drag windows around while recording unless necessary - Set your display to 8-bit color mode (or at least set vnc to 8-bit color mode) If the app you're recording has lots of graphics and motion (e.g. a web browser), then there may not be a clear winner between flv (possibly smaller) and flashsv (definitely better quality), you'll have to decide which works best for you. On Wed, Nov 4, 2009 at 5:26 PM, Brian Candler <B.C...@po...> wrote: > This isn't exactly a vnc2flv problem, but I thought this would be a > reasonable place to ask anyway. > > I have used vnc2flv to create a screencast which is 9 mins 27 secs long, at > a screen size of 992 x 608. [The large screen area is because the app I'm > capturing really needs this much space]. The resulting file is 19.1MB. > > Now, I would like to reduce the file size significantly. I am happy to > reduce the picture 2:1 so that it becomes 496 x 304. I can do this using > ffmpeg (*), and the picture quality is usable for my purpose: > > ffmpeg -i in.flv -s 496x304 -r 4 -acodec copy -y out.flv > > However the resultant file is still 12MB in size, even after dropping the > output frame rate to 4fps! > > I tried outputting using the 'flashsv' codec (**): > > ffmpeg -i in.flv -s 496x304 -vcodec flashsv -r 4 -acodec copy -y > out-flashsv.flv > > but now the resultant file is even larger, at 16.2MB. > > LAME tells me it's encoding the audio at 32kbps mono, in which case that > only accounts for about 2.2MB of the total. > > Here's what 'ffplay -stats' says about the source file (19MB): > > Input #0, flv, from 'in.flv': 0KB vq= 0KB sq= 0B > Duration: 00:09:26.66, start: 0.000000, bitrate: 32 kb/s > Stream #0.0: Video: flashsv, bgr24, 992x608, 12 tbr, 1k tbn, 1k tbc > Stream #0.1: Audio: mp3, 22050 Hz, mono, s16, 32 kb/s > 23.81 A-V: 4.297 aq= 79KB vq= 498KB sq= 0B > > and the version shrunk as 'flv' (12MB): > > Input #0, flv, from 'out.flv': vq= 0KB sq= 0B > Duration: 00:09:27.00, start: 0.000000, bitrate: 232 kb/s > Stream #0.0: Video: flv, yuv420p, 496x304, 200 kb/s, 4 tbr, 1k tbn, 1k > tbc > Stream #0.1: Audio: mp3, 22050 Hz, mono, s16, 32 kb/s > 23.49 A-V: -0.027 aq= 79KB vq= 170KB sq= 0B > > and the version shrunk as 'flashsv' (16MB): > > Input #0, flv, from 'out-flashsv.flv': > Duration: 00:09:27.00, start: 1257374691.83 A-V: 0.000 aq= 0KB vq= > 0KB 0.000000, bitrate: 232 kb/s > Stream #0.0: Video: flashsv, bgr24, 496x304, 200 kb/s, 4 tbr, 1k tbn, 1k > tbc > Stream #0.1: Audio: mp3, 22050 Hz, mono, s16, 32 kb/s > 23.00 A-V: -0.015 aq= 80KB vq= 232KB sq= 0B > > So, do you have any suggestions about how I could improve this? Have I > missed an important option from ffmpeg? Is there a better way to shrink a > vnc2flv stream? > > Many thanks, > > Brian. > > (*) ffmpeg is the stock version from Ubuntu Jaunty: > > ii ffmpeg 3:0.svn20090303-1ubuntu6 > multimedia player, server and encoder > ii gstreamer0.10-ffmpeg 0.10.6.2-1ubuntu2 > FFmpeg plugin for GStreamer > ii libavcodec-unstripped-52 > 3:0.svn20090303-1ubuntu2+unstripped1 ffmpeg codec library > ii libavdevice52 3:0.svn20090303-1ubuntu6 > ffmpeg device handling library > ii libavfilter0 3:0.svn20090303-1ubuntu6 > ffmpeg video filtering library > ii libavformat52 3:0.svn20090303-1ubuntu6 > ffmpeg file format library > ii libavutil-unstripped-49 > 3:0.svn20090303-1ubuntu2+unstripped1 ffmpeg utility library > ii libpostproc51 3:0.svn20090303-1ubuntu6 > ffmpeg video postprocessing library > ii libswscale0 3:0.svn20090303-1ubuntu6 > ffmpeg video scaling library > > (**) According to Wikipedia, flash video supports two tiling codecs > specifically for screencasts, so I guess that 'flashsv' is one of those. I > also saw a recent posting to this list showing '-vcodec flashsv'. > > > ------------------------------------------------------------------------------ > Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day > trial. Simplify your report design, integration and deployment - and focus > on > what you do best, core application coding. Discover what's new with > Crystal Reports now. http://p.sf.net/sfu/bobj-july > _______________________________________________ > Vnc2swf-users mailing list > Vnc...@li... > https://lists.sourceforge.net/lists/listinfo/vnc2swf-users > -- http://theamigo.blogspot.com |
From: Brian C. <B.C...@po...> - 2009-11-05 00:32:13
|
On Wed, Nov 04, 2009 at 05:57:54PM -0600, Josh Harding wrote: > If you're familiar with image formats, then this analogy might help: > jpeg : flv > png : flashsv Yep, that does make sense. However I was hoping (naively) for a 4:1 size reduction when shrinking the image 2:1 along each axis, apart from the audio overhead of course. If you want to have a look at my flv, I'm happy to send it to you privately. It's Firefox using a web application, with a plain white background, some plain colour higlighting, and little motion. > - Set your display to 8-bit color mode (or at least set vnc to 8-bit > color mode) Good suggestion, I'll give that a try. I did also try x11vnc -scale 1/2, which combined with suitable clipping settings on flvrec does seem to give a slightly lower data rate. But it would be nice to keep the full-res capture and then scale it down afterwards. Regards, Brian. |
From: Josh H. <the...@gm...> - 2009-11-05 01:48:40
|
On Wed, Nov 4, 2009 at 6:13 PM, Brian Candler <B.C...@po...> wrote: > > If you want to have a look at my flv, I'm happy to send it to you > privately. > It's Firefox using a web application, with a plain white background, some > plain colour higlighting, and little motion. > Sure, I'll take a look and see if anything jumps out at me. I did also try x11vnc -scale 1/2, which combined with suitable clipping > settings on flvrec does seem to give a slightly lower data rate. But it > would be nice to keep the full-res capture and then scale it down > afterwards. > I haven't tried that, but if it does nearest neighbor sampling (as opposed to something that would include anti-aliasing) it should give a smaller size (but I wouldn't expect a huge savings). Once you've encoded an image, adding some more areas that use the same colors and repeat the same patterns doesn't cost much. What I did at a previous job was record whole screens (2560 x 1024) at full resolution (8-bit color, 4fps) and then just use a flv player to scale the video down during playback. At the time, I wasn't concerned too much about file size, so I did little else to optimize it. While it may not be of much general use, I can also note that for archiving large recordings, running gzip on a raw vnc log results in incredibly small files (even compared to the .flv's). Playback is a bit less convenient as you'd have to uncompress and convert to flv before viewing. -- http://theamigo.blogspot.com |
From: Brian C. <B.C...@po...> - 2009-11-05 09:54:58
|
On Wed, Nov 04, 2009 at 07:41:18PM -0600, Josh Harding wrote: > I can also note that for > archiving large recordings, running gzip on a raw vnc log results in > incredibly small files (even compared to the .flv's). Playback is a > bit less convenient as you'd have to uncompress and convert to flv > before viewing. How did you capture the raw vnc log in a replayable form? I had a look at the vnc traffic using tcpdump -i lo -n -s0 -w /tmp/lo.pcap and at the same time monitored the size of the .flv file being created. I pointed it at a completely static browser window, which didn't have focus so there wasn't even a blinking cursor in it. As expected, the pcap showed an initial flurry of traffic and then was completely static. However the .flv was continuing to grow - I measured this at 200KBytes every 30 seconds. In bits-per-second that's 55kbps for a completely static screen. If it's storing a marker every frame, and 12 frames per second, then that's about 580 bytes per identical frame. I then tried flvrec with -r 4, and it only grew at 72KB per 30 seconds. So the overhead looks to be proportional to frame rate. I think the default frame rate is 12 fps, although the documentation at http://www.unixuser.org/~euske/python/vnc2flv/index.html#flvrec.py says it defaults to 15. Maybe the per-frame overhead is proscribed by the flv format and can't be reduced? :-( I then tried flvrec -K 150 (and no -r flag), and the growth was 147KB instead of 200KB. So the key frames have some effect it seems. Regards, Brian. |
From: Brian C. <B.C...@po...> - 2009-11-05 10:32:45
|
On Thu, Nov 05, 2009 at 09:54:11AM +0000, Brian Candler wrote: > I then tried flvrec -K 150 (and no -r flag), and the growth was 147KB > instead of 200KB. So the key frames have some effect it seems. flvrec -B 64 improves it from 200KB to 108KB per 30 seconds. Looking at the source code, every unchanged block in every frame requires something to be written to the output: if (x,y) in changes: # changed block block = zlib.compress(self.screen.get(x,y)) data += pack('>H', len(block)) + block else: # unchanged block data += pack('>H', 0) '>H' is unsigned short (2 bytes). What a shame the zlib compression happens separately per block, instead of once over the whole frame! Anyway, I was thinking that: - a screen of 992x608 is exactly 31x19 blocks (with default blocksize 32) - each frame consists of 31x19x2 = 1178 zero bytes - so 12 fps would be 414KB per 30 seconds That's about twice what I'm seeing, so clearly I've misunderstood something. All those zeros suggests good gzip compression. My original 19MB flv gzips to 9MB, which isn't brilliant but is OK when you consider it contains audio too. I don't know if ffmpeg has a way to set the blocksize and key frame rate parameters when outputting, but if so I could probably shrink this file quite a lot. Unfortunately, ffmpeg appears to be missing the unchanged-block optimisation for flash screen video. If I record a 20-second static screen with vnc2flv, it takes 142K. If I then copy it using ffmpeg -i static-20secs.flv -r 12 -vcodec flashsv static-full.flv it increases to 497K. If I try to halve the image size at the same time using ffmpeg -i static-20secs.flv -s 496x304 -r 12 -vcodec flashsv static-half.flv then it increases to 900K! Regards, Brian. |
From: Yusuke S. <yu...@cs...> - 2009-11-05 13:22:55
|
On Wed, 4 Nov 2009 23:26:14 +0000, Brian Candler <B.C...@po...> wrote: > This isn't exactly a vnc2flv problem, but I thought this would be a > reasonable place to ask anyway. > > I have used vnc2flv to create a screencast which is 9 mins 27 secs long, at > a screen size of 992 x 608. [The large screen area is because the app I'm > capturing really needs this much space]. The resulting file is 19.1MB. Have you tried "panning" option in flvcat.py? It sometimes works with varied reduction rates. (But in other times the result looks unbearable.) $ flvcat.py -W 640x480 in.flv out.flv Another way would be to shrink the entire screen as you mentioned. Originally, pyvnc2swf has this option. But I dropped it in vnc2flv because it was depending on pygame for image operation. Other than that, I don't have much idea for reducing it. Yusuke |
From: Brian C. <B.C...@po...> - 2009-11-05 14:59:30
|
On Thu, Nov 05, 2009 at 08:22:39AM -0500, Yusuke Shinyama wrote: > > I have used vnc2flv to create a screencast which is 9 mins 27 secs long, at > > a screen size of 992 x 608. [The large screen area is because the app I'm > > capturing really needs this much space]. The resulting file is 19.1MB. > > Have you tried "panning" option in flvcat.py? I did. It made the file even bigger, probably because of all the panning around :-( |
From: Brian C. <B.C...@po...> - 2009-11-06 11:27:34
|
On Thu, Nov 05, 2009 at 08:22:39AM -0500, Yusuke Shinyama wrote: > Another way would be to shrink the entire screen as you mentioned. > Originally, pyvnc2swf has this option. But I dropped it in vnc2flv > because it was depending on pygame for image operation. I would find it useful, but probably the "right" solution here is to teach ffmpeg how to compress flash screen video better, rather than complicate flvcat. That reminds me: do you have any documentation on the FSV1 codec? And in the case where two frames are exactly identical, do you think it would it be possible to leave the frame out entirely? I think this is a common situation for screen video. Regards, Brian. |
From: Yusuke S. <yu...@cs...> - 2009-11-06 13:45:36
|
On Fri, 6 Nov 2009 11:26:58 +0000, Brian Candler <B.C...@po...> wrote: > > That reminds me: do you have any documentation on the FSV1 codec? And in the > case where two frames are exactly identical, do you think it would it be > possible to leave the frame out entirely? I think this is a common situation > for screen video. I've never heard of "FSV" codec, but I do know there's another ScreenVideo V2 codec that doesn't require full update for every frame. With the original ScreenVideo codec, which is the only codec currently supported by vnc2flv, always requires all the blocks presented in every frame. So the way to go is to implement "V2" codec somehow... but I gave up for now because the specification in Flash v10 document seems pretty scarce. And I haven't found any decent sample movie with that codec. Yusuke |
From: Brian C. <B.C...@po...> - 2009-11-06 14:29:54
|
On Fri, Nov 06, 2009 at 08:45:22AM -0500, Yusuke Shinyama wrote: > I've never heard of "FSV" codec I meant the flash screen video codec. I understand there are two versions, and I had seen them referred to elsewhere as FSV1 and FSV2. e.g. http://wiki.multimedia.cx/index.php?title=Flash_screen_video > So the way to go is to implement "V2" codec somehow... Here's someone who might know... http://wiki.multimedia.cx/index.php?title=Small_FFmpeg_Tasks#Implement_the_Flash_Screen_Video_codec_version_2 But I'd say it's reasonable for vnc2flv to encode using the simplest possible codec, and post-process it to v2, since this is a lossless format anyway. At the moment, encoding directly into the v2 form would limit the range of tools you could use to handle it. Your code is a pretty clear spec for the V1 codec, so if I get a chance I'll see if I can have a look at improving ffmpeg's encoding. However I also found this document via google: http://www.schnarff.com/file-formats/flash/flash_fileformat_specification.pdf Unfortunately, it requires you to accept a licence agreement before opening. The licence permits you to write software which outputs FLV. However you are not permitted to write a program which reads or renders FLV, and you have to agree to adding Macromedia branding to your finished product. As a result, you may decide not to read this file :-) Regards, Brian. |
From: Yusuke S. <yu...@cs...> - 2009-11-06 15:22:35
|
On Fri, 6 Nov 2009 14:29:33 +0000, Brian Candler <B.C...@po...> wrote: > However I also found this document via google: > http://www.schnarff.com/file-formats/flash/flash_fileformat_specification.pdf > > Unfortunately, it requires you to accept a licence agreement before opening. > The licence permits you to write software which outputs FLV. However you are > not permitted to write a program which reads or renders FLV, and you have to > agree to adding Macromedia branding to your finished product. As a result, > you may decide not to read this file :-) Adobe recently dropped this restiction. The newest Flash v10 specification is open to anyone. You can download straight from the Adobe site: http://www.adobe.com/devnet/swf/pdf/swf_file_format_spec_v10.pdf But as I said, the FSV2 section is still obscure to me. Seems like ffmpeg guys figured out somehow (after a lot of trials and erros supposedly). Yusuke |
From: Brian C. <B.C...@po...> - 2009-11-06 15:40:43
|
On Fri, Nov 06, 2009 at 10:22:20AM -0500, Yusuke Shinyama wrote: > But as I said, the FSV2 section is still obscure to me. Seems like > ffmpeg guys figured out somehow (after a lot of trials and erros supposedly). I don't think there's any code for this yet. I've just checked out from SVN and flashsv.c / flashsvenc.c are FSV1 only. The encoder looks like it should skip unchanged blocks in the same way as vnc2swf. I'm just building it from source now. If it still makes flv files larger than it's probably just a simple bug to squash. Regards, Brian. |
From: Brian C. <B.C...@po...> - 2009-11-06 16:20:59
|
On Fri, Nov 06, 2009 at 03:40:29PM +0000, Brian Candler wrote: > The encoder looks like it should skip unchanged blocks in the same way as > vnc2swf. I'm just building it from source now. If it still makes flv files > larger than it's probably just a simple bug to squash. I've found the issue, and it's simply due to the frequency of insertion of key frames. By default, ffmpeg is putting a key frame in every second, whereas vnc2flv does it much less frequently - something like one every 150 frames. You can change ffmpeg's behaviour using -g (for "group of pictures"). Taking my 19MB vnc2flv file, and using ffmpeg built from SVN: ffmpeg -i src.flv -vcodec flashsv -acodec copy -r 12 -g 120 same.flv gives a file which is 13.5MB. And scaling it down by 2:1 at the same time, ffmpeg -i src.flv -vcodec flashsv -acodec copy -s 496x304 -r 12 -g 120 half.flv gives a file which is 11.7MB. Remember this includes audio too. I am still a bit surprised that the resizing doesn't reduce the output much, but I am still doing 12 fps here, so 4 fps would probably reduce it more. I haven't yet worked out how the block_height and block_width are set, and whether it's possible to override these too. Regards, Brian. |
From: Brian C. <B.C...@po...> - 2009-11-06 22:33:10
|
On Fri, Nov 06, 2009 at 04:19:58PM +0000, Brian Candler wrote: > Taking my 19MB vnc2flv file, and using ffmpeg built from SVN: > > ffmpeg -i src.flv -vcodec flashsv -acodec copy -r 12 -g 120 same.flv > > gives a file which is 13.5MB. This reduction is because ffmpeg is outputting using 64x64 blocks, rather than the 32x32 that you get by default from vnc2flv. As a result, the space used by idle frames is only about 1/4. > And scaling it down by 2:1 at the same time, > > ffmpeg -i src.flv -vcodec flashsv -acodec copy -s 496x304 -r 12 -g 120 half.flv > > gives a file which is 11.7MB. Remember this includes audio too. I am still a > bit surprised that the resizing doesn't reduce the output much ffmpeg does an very good job of antialiasing the reduced image (even text is legible at half size), and the resulting frames don't compress very well in zlib because of the number of different colours used. I made a simple trick in ffmpeg to quantize to 16 levels of R/G/B: --- libavcodec/flashsvenc.c.orig 2009-11-06 22:13:00.000000000 +0000 +++ libavcodec/flashsvenc.c 2009-11-06 22:13:19.000000000 +0000 @@ -88,7 +88,7 @@ npfptr = pfptr+(i*stride)+dy*3; for (j=0 ; j<w*3 ; j++) { diff |=npfptr[j]^nsptr[j]; - dptr[j] = nsptr[j]; + ((nsptr[j] + 8)/ 17) * 17; } dptr += w*3; } My test file has a video portion of 10543K. When scaling to half size, it only shrunk to 9048K. However with the above patch, it reduced to 4086K, and the total size of the flv with audio was 6.9M. Perhaps I'll propose a flag on the ffmpeg list. Regards, Brian. |