I’ve been working a great deal on Flash video related projects the past several years, and just this week I ran across and solved a puzzling issue for a client where the duration value being injected into a very large .flv file kept coming up far short of its real world value. I talked it through on Stefan Richters  great mailinglist FLASHMEDIA  and thanks to Asa Whillock at Adobe on the FMS team, came to a conclusion, so I’m consolidating it all here for the benefit of others.
The video in question was over 8 hours in length, 8 hours 26 minutes and 26 seconds to be exact. It was encoded using the On2 VP6 CODEC and clocked in at 1.4GB in size. Not the typical average length and size for an FLV by any means, but I thought it certainly should be supported as it plays fine when streamed, or progressively downloaded, but the duration value was wrong. The other metadata values were correct, just duration.
Unfortunately this file was to be hosted on bitgravity’s network  using their advanced-progressive delivery  – a customized high performance, scalable version of the pseudo-streaming technique made popular by Stefan Richter and others as described here . So this compounded the problem as the bitgravity player requires the duration to be correct in order to calculate the proper position of the scrub/seek bar and to keep track of the offset of the beginning of the video when jumping/seeking which causes new requests for the video to be sent out, where a server side process looks at the video and its embedded keyframe metadata as well as the duration, recalculates the proper header, and begins sending data from the approximate requested keyframe position onward. So having an incorrect duration really fouled up playback in this specific instance of the bitgravity player.
Each tool I tried using to inject/view the metadata, including: flvtool2 , flvtool++  and jflvtool  all inserted incorrect values – and the results varied from tool to tool. I was going to try Burak Kalaycis FLVMDI metadata injector  tool, but as luck would have it, Burak is also on Stefans mailing list, and he chimed in and mentioned that FLVMDI has some other limitations on the file size of videos that it can process (currently limited to 700MB), and that I would probably hit that issue first. So I didn’t run it through FLVMDI – but Burak did also confirm that his tool also suffers from the same problem, where the duration value would be incorrect, and if he gets a chance to fix it, he would update us on that.
The key issue does indeed relate to the length or duration of the .FLV itself and the FLV container format and specs for how the duration metadata value is stored. For videos that are under approximately 4.5 hours, everything is fine. However, once a video exceeds a little over 4 hours and 39 minutes, this is when the duration values appear incorrect with these tools, and all of them report back a value of around 16777.990 seconds in duration, a little more than half of the 8 hours 26 minutes of the video I was working with, which should have reported 30386 seconds.
I assumed that the problem might have something to do with the extra long duration, so thats when I began doing some research on the maximum length of FLV’s. I determined thanks to some help from Asa Whillock that the problem lies in how the duration value is stored in the .FLV container and the publicly available specs that were available at the time to third party authors that developed these applications. Originally the spec (prior to FMS 1.0) only designated a 3 byte integer type (UI24) to store the duration in milliseconds, or just enough to store a value corresponding to (256*256*256) 16.7 million or 16,777,990 milliseconds or 16777.990 seconds or 4 hours, 39 minutes, 37 seconds. So any video with a duration greater than that that can’t be represented with the single 3 byte sequence as the original FLV spec listed. Asa pointed out that in the recent spec they added an extended 7 byte UI8 tag named “TimeStampExtended”. This tag is to immediately follow the original 3 byte UI24 “TimeStamp” tag, and then both values are used to store the time. In this arrangement the original “TimeStamp” tag acts as the lower 24bits of the duration in milliseconds, and the “TimeStampExtended” acts as the upper 8 bits of the duration in milliseconds. This results in a 4 byte representation when combined, (256*256*256*256) so a maximum of 4.2 billion or 4,294,967,296 milliseconds or 4294967.296 seconds or 1193 hours, 2 minutes and 47 seconds or nearly 50 days straight worth of video. This would certainly allow just about any videos duration to be stored properly in the metadata.
So it looks like the solution to the the problem is to make sure the duration is stored using not only the “TimeStamp” tag but also the “TimeStampExtended” tag in order to store the full value of the duration for any video that exceeds 4 hours, 39 minutes and 37 seconds, otherwise the duration will be truncated to only the first 3 byte representation. To me this looks like a fairly easy fix (although the devil is always in the details). Burak is already aware of the issue, and I have gone ahead and emailed the info to Chris Norman of Facebook who wrote the c++ flvtool++ implementation, as well as Norman Timmler over in Germany who wrote the flvtool2 in Ruby. I still need to write the author of the java based jflvtool. Fernando Florez of Funciton Communications  mentioned a colleague of his has a Python based metadata injector that also suffers from this issue, but they are working on a patch and will try to release that as open source at some point. So I have hope we will have a third party tool capable of handling videos of this length in the short term.
If it helps anyone else working on similar tools, the exact reference to the “TimeStampExtended” tag is on page 9 of Adobes Video File Format Specification Version 9 
I haven’t yet had a chance to see if any commercial products like Sorenson Squeeze, On2 Flix, and the Flash CS3 Video Encoder correctly store the duration for videos over 4:39:37 in length – but will try to validate that and update this article once I’ve had a chance. I’m making an assumption the Adobe’s encoder does support it properly.
Thanks to Asa Whillock of Adobe for input and validation on this, as well as fellow Adobe Community Experts Fabio Sonnati  and Stefan Richter  and his invaluable FLASHMEDIA  mailing list and to Burak Kalayci  and Fernando Florez  for their input and thoughts. Thanks guys!
UPDATE: 09/02/08 – I found another nice FLV metadata injector: YAMDI – http://yamdi.sourceforge.net/  but it also appears to suffer from the same bug.
Its been several days and I still have yet to hear back from Bitgravity about their FLVMDU tool that their CTO Barrett Lyon posted about in the comments. I emailed him directly right after the comment was posted, as well as through support as he noted and got a ticket #1678, but have yet to receive a response from Barrett or their support staff. Chalking it up to the holiday weekend.
UPDATE: 09/03/08 –I spent some extra time tonight trying to locate a copy of the Bitgravity FLVMDU tool and with a little careful url guessing, was successful and found this link to the tool  – it also includes the source under a GNU license which is nice. This version is dated 06-18-2008 as version 1.0.0. Unfortunately after running it through the same series of tests on a video with a duration greater than 4 hours 39 minutes and 37 seconds, it also fails to write the proper duration on such a long video. So it appears that bitgravity needs to also update their utilities to support the “TimeStampExtended” tag. There was a note to contact a “pclarke” at bitgravity in regards to bugs – so I’ve dropped them a note and pointed them at this article. Hopefully they will be able to fix things as of right now every FLV metadata injector tool I’ve tested suffers the same problem.
UPDATE: 09/03/08 12:37AM – I found one more nice flv metadata injector and dumper called flvmeta available here http://code.google.com/p/flvmeta/ . The source, and pre-made binaries for windows and Mac OS X are available, but it too appears to suffer from the bug I’ve been exploring since it doesn’t appear to support the “TimeStampExtended” tag either. Looks like everyone completely missed this in the spec, or just didn’t implement it for some reason.
UPDATE: 09/03/08 12:24PM – I heard back from Perry Clarke at Bitgravity in response to my email to him about the bug/lack of support for “TimeStampExtended” in their FLVMDU tool. Perry noted, “I haven’t reproduced the issue you report though I can believe it’s a problem. I’ll look into it when I have time.” So if you rely on FLVMDU when working with bitgravity, you’ll probably need to pester Perry or their support team to implement proper support in FLVMDU if your video is longer than 4 hours 39 minutes 37 seconds, especially if you are using their advanced progressive http delivery for videos – as that service requires the keyframe/metadata hinting and proper metadata duration tag otherwise it wont work properly. If they don’t update the tool, you’ll need to deliver your video in smaller chunks (less than 4 hours 39 minutes 37 seconds). I’d recommend smaller chunks anyway given the memory usage.
UPDATE: 09/08/08 7:40PM – Last week I heard back from Dan Weatherford of Facebook and the primary author of flvtool++ He was very responsive in working with me to get in the proper support for the “TimeStampExtended” tag for proper durations on long videos. We made a number of test files from a variety of all the popular FLV exporters and transcoders and Dan was able to implement the full spec in the latest version of flvtool++ 1.1.2 available here: http://mirror.facebook.com/facebook/flvtool++/  The funny thing was that we found was that not a single tool, none of the flv metadata injectors out there, nor any of the FLV encoders we tested put in the proper duration in “TimeStampeExtended” format. Not ffmpeg, not Squeeze 5, not On2 Flix, not even Adobe Flash CS3 Video Encoder (standalone or Quicktime Exporter) and even a few upcoming apps currently in beta that I have access too – none of them inserted the proper duration in “TimeStampExtended” format for videos over 4 hours 39 minutes and 37 seconds. I thought this was especially odd for the Adobe apps – so it just looks like everyone totally overlooked this. Thanks so much to Dan Weatherford for his time in implementing proper support into flvtool++. Its currently the only tool I know of that properly supports “TimeStampExtended”