I am doing a lot of work with Flash MX and video (flv) and I recently needed to get the duration off of a bunch of FLV files. Sorensen now correctly adds the duration, width, height, framerate, creation date, and the audio and video data rates. I wrote some C# code to read and parse this information off the file.

using System.IO;
namespace Refresh.FlashTools
{
    /// <summary>
    /// Reads the meta information embedded in an FLV file
    /// </summary>
    public class FlvMetaDataReader
    {
        /// <summary>
        /// Reads the meta information (if present) in an FLV
        /// </summary>
        /// <param name="path">The path to the FLV file</returns>
        public static FlvMetaInfo GetFlvMetaInfo(string path)
        {
            if (!File.Exists(path))
            {
                throw new Exception(String.Format("File '{0}' doesn't exist for FlvMetaDataReader.GetFlvMetaInfo(path)", path));
            }
            bool hasMetaData = false;
            double duration = 0;
            double width = 0;
            double height = 0;
            double videoDataRate = 0;
            double audioDataRate = 0;
            Double frameRate = 0;
            DateTime creationDate = DateTime.MinValue;
            // open file
            FileStream fileStream = new FileStream(path, FileMode.Open);
            try
            {
                // read where "onMetaData"
                byte[] bytes = new byte[10];
                fileStream.Seek(27, SeekOrigin.Begin);
                int result = fileStream.Read(bytes, 0, 10);
                // if "onMetaData" exists then proceed to read the attributes
                string onMetaData = ByteArrayToString(bytes);
                if (onMetaData == "onMetaData")
                {
                    hasMetaData = true;
                    // 16 bytes past "onMetaData" is the data for "duration"
                    duration = GetNextDouble(fileStream, 16, 8);
                    // 8 bytes past "duration" is the data for "width"
                    width = GetNextDouble(fileStream, 8, 8);
                    // 9 bytes past "width" is the data for "height"
                    height = GetNextDouble(fileStream, 9, 8);
                    // 16 bytes past "height" is the data for "videoDataRate"
                    videoDataRate = GetNextDouble(fileStream, 16, 8);
                    // 16 bytes past "videoDataRate" is the data for "audioDataRate"
                    audioDataRate = GetNextDouble(fileStream, 16, 8);
                    // 12 bytes past "audioDataRate" is the data for "frameRate"
                    frameRate = GetNextDouble(fileStream, 12, 8);
                    // read in bytes for creationDate manually
                    fileStream.Seek(17, SeekOrigin.Current);
                    byte[] seekBytes = new byte[24];
                    result = fileStream.Read(seekBytes, 0, 24);
                    string dateString = ByteArrayToString(seekBytes);
                    // create .NET readable date string
                    // cut off Day of Week
                    dateString = dateString.Substring(4);
                    // grab 1) month and day, 2) year, 3) time
                    dateString = dateString.Substring(0, 6) + " " + dateString.Substring(16, 4) + " " + dateString.Substring(7, 8);
                    // .NET 2.0 has DateTime.TryParse
                    try
                    {
                        creationDate = Convert.ToDateTime(dateString);
                    }
                    catch { }
                }
            }
            catch (Exception e)
            {
                // no error handling
            }
            finally
            {
                fileStream.Close();
            }
            return new FlvMetaInfo(hasMetaData, duration, width, height, videoDataRate, audioDataRate, frameRate, creationDate);
        }
        private static Double GetNextDouble(FileStream fileStream, int offset, int length)
        {
            // move the desired number of places in the array
            fileStream.Seek(offset, SeekOrigin.Current);
            // create byte array
            byte[] bytes = new byte[length];
            // read bytes
            int result = fileStream.Read(bytes, 0, length);
            // convert to double (all flass values are written in reverse order)
            return ByteArrayToDouble(bytes, true);
        }
        private static string ByteArrayToString(byte[] bytes)
        {
            string byteString = string.Empty;
            foreach (byte b in bytes)
            {
                byteString += Convert.ToChar(b).ToString();
            }
            return byteString;
        }
        private static Double ByteArrayToDouble(byte[] bytes, bool readInReverse)
        {
            if (bytes.Length != 8)
                throw new Exception("bytes must be exactly 8 in Length");
            if (readInReverse)
                Array.Reverse(bytes);
            return BitConverter.ToDouble(bytes, 0);
        }
    }
    /// <summary>
    /// Read only container holding meta data embedded in FLV files
    /// </summary>
    public class FlvMetaInfo
    {
        private Double _duration;
        private Double _width;
        private Double _height;
        private Double _frameRate;
        private Double _videoDataRate;
        private Double _audioDataRate;
        private DateTime _creationDate;
        private bool _hasMetaData;
        /// <summary>
        /// The duration in seconds of the video
        /// </summary>
        public Double Duration
        {
            get { return _duration; }
            //set { _duration = value; }
        }
        /// <summary>
        /// The width in pixels of the video
        /// </summary>
        public Double Width
        {
            get { return _width; }
            //set { _width = value; }
        }
        /// <summary>
        /// The height in pixels of the video
        /// </summary>
        public Double Height
        {
            get { return _height; }
            //set { _height = value; }
        }
        /// <summary>
        /// The data rate in KB/sec of the video
        /// </summary>
        public Double VideoDataRate
        {
            get { return _videoDataRate; }
            //set { _videoDataRate = value; }
        }
        /// <summary>
        /// The data rate in KB/sec of the video's audio track
        /// </summary>
        public Double AudioDataRate
        {
            get { return _audioDataRate; }
            //set { _audioDataRate = value; }
        }
        /// <summary>
        /// The frame rate of the video
        /// </summary>
        public Double FrameRate
        {
            get { return _frameRate; }
            //set { _frameRate = value; }
        }
        /// <summary>
        /// The creation date of the video
        /// </summary>
        public DateTime CreationDate
        {
            get { return _creationDate; }
            //set { _creationDate = value; }
        }
        /// <summary>
        /// Whether or not the FLV has meta data
        /// </summary>
        public bool HasMetaData
        {
            get { return _hasMetaData; }
            //set { _hasMetaData = value; }
        }
        internal FlvMetaInfo(bool hasMetaData, Double duration, Double width, Double height, Double videoDataRate, Double audioDataRate, Double frameRate, DateTime creationDate)
        {
            _hasMetaData = hasMetaData;
            _duration = duration;
            _width = width;
            _height = height;
            _videoDataRate = videoDataRate;
            _audioDataRate = audioDataRate;
            _frameRate = frameRate;
            _creationDate = creationDate;
        }
    }
}

Update: Dave Daku converted this to VB:

Imports System.IO
Namespace Refresh.FlashTools
  '
  ' Returns the meta information embedded in an FLV file
  ' Written in C# by John Dyer: http://johndyer.name/post/2005/08/Flash-FLV-meta-reader-in-NET-(C).aspx
  ' Conversion to VB.net by Dave Daku (11/29/2007)
  '
  Public Class flvMetaDataReader
     Public Shared Function getFlvMetaInfo(ByRef path As String) As flvMetaInfo
        If (Not File.Exists(path)) Then
           Throw New Exception(String.Format("File '{0}' doesn't exist for flvMetaDataReader.getFlvMetaInfo(path)", path))
        End If
        Dim hasMetaData As Boolean = False
        Dim duration As Double = 0
        Dim width As Double = 0
        Dim height As Double = 0
        Dim videoDataRate As Double = 0
        Dim audioDataRate As Double = 0
        Dim frameRate As Double = 0
        Dim creationDate As DateTime = DateTime.MinValue
        ' open the file
        Dim fileStream As FileStream = New FileStream(path, FileMode.Open)
        Try
           ' read where "onMetaData"
           Dim bytes As Byte() = New Byte(10) {}
           fileStream.Seek(27, SeekOrigin.Begin)
           Dim result As Integer = fileStream.Read(bytes, 0, 10)
           ' if "onMetaData" exists then proceed to read the attributes
           Dim onMetaData As String = byteArrayToString(bytes)
           If (onMetaData = "onMetaData") Then
              hasMetaData = True
              ' 16 bytes past "onMetaData" is the data for "duration"
              duration = getNextDouble(fileStream, 16, 8)
              ' 8 bytes past "duration" is the data for "width"
              width = getNextDouble(fileStream, 8, 8)
              ' 9 bytes past "width" is the data for "height"
              height = getNextDouble(fileStream, 9, 8)
              ' 16 bytes past "height" is the data for "videoDataRate"
              videoDataRate = getNextDouble(fileStream, 16, 8)
              ' 16 bytes past "videoDataRate" is the data for "audioDataRate"
              audioDataRate = getNextDouble(fileStream, 16, 8)
              ' 12 bytes past "audioDataRate" is the data for "frameRate"
              frameRate = getNextDouble(fileStream, 12, 8)
              ' read in bytes for creationDate manually
              fileStream.Seek(17, SeekOrigin.Current)
              Dim seekBytes As Byte() = New Byte(24) {}
              result = fileStream.Read(seekBytes, 0, 24)
              Dim dateString As String = byteArrayToString(seekBytes)
              ' create .NET readable date string
              ' cut off Day of Week
              dateString = dateString.Substring(4)
              ' grab 1) month and day, 2) year, 3) time
              dateString = dateString.Substring(0, 6) + " " + dateString.Substring(16, 4) + " " + dateString.Substring(7, 8)
              ' .NET 2.0 has dateTime.tryParse
              Try
                 Date.TryParse(dateString, creationDate)
              Catch ex As Exception
                 Try
                    creationDate = CDate(dateString)
                 Catch ex2 As Exception
                 End Try
              End Try
           End If
        Catch ex As Exception
           ' no error handling
        Finally
           fileStream.Close()
        End Try
        Return New flvMetaInfo(hasMetaData, duration, width, height, videoDataRate, audioDataRate, frameRate, creationDate)
     End Function
     Private Shared Function getNextDouble(ByVal fileStream As
FileStream, ByVal offset As Integer, ByVal length As Integer) As Double
        ' move the desired number of places in the array
        fileStream.Seek(offset, SeekOrigin.Current)
        ' create byte array
        Dim bytes As Byte() = New Byte(length) {}
        ' read bytes
        Dim result As Integer = fileStream.Read(bytes, 0, length)
        ' convert to double (all flash values are written in reverse orer)
        Return byteArrayToDouble(bytes, True)
     End Function
     Private Shared Function byteArrayToString(ByRef bytes() As Byte) As String
        Dim byteString As String = String.Empty
        For Each b As Byte In bytes
           byteString += Convert.ToChar(b).ToString()
        Next
        Return byteString
     End Function
     Private Shared Function byteArrayToDouble(ByRef bytes As Byte(), ByVal readInReverse As Boolean) As Double
        If (bytes.Length <> 8) Then
           Throw New Exception("Bytes must be exactly 8 in length")
        End If
        If (readInReverse) Then
           Array.Reverse(bytes)
        End If
        Return BitConverter.ToDouble(bytes, 0)
     End Function
  End Class
  ' Read-only container for holding meta data embedded in FLV files
  Public Class flvMetaInfo
     Private _duration As Double
     Private _width As Double
     Private _height As Double
     Private _frameRate As Double
     Private _videoDataRate As Double
     Private _audioDataRate As Double
     Private _creationDate As DateTime
     Private _hasMetaData As Boolean
     ' The duration in seconds of the video
     Public ReadOnly Property duration() As Double
        Get
           Return _duration
        End Get
     End Property
     ' The width in pixels of the video
     Public ReadOnly Property width() As Double
        Get
           Return _width
        End Get
     End Property
     ' The height in pixels of the video
     Public ReadOnly Property height() As Double
        Get
           Return _height
        End Get
     End Property
     ' the data rate in KB/sec of the video
     Public ReadOnly Property videoDataRate() As Double
        Get
           Return _videoDataRate
        End Get
     End Property
     ' the data rate in KB/sec of the video's audio track
     Public ReadOnly Property audioDataRate() As Double
        Get
           Return _audioDataRate
        End Get
     End Property
     ' the frame rate of the video
     Public ReadOnly Property frameRate() As Double
        Get
           Return _frameRate
        End Get
     End Property
     ' the creation date of the video
     Public ReadOnly Property creationDate() As DateTime
        Get
           Return _creationDate
        End Get
     End Property
     ' the frame rate of the video
     Public ReadOnly Property hasMetaData() As Boolean
        Get
           Return _hasMetaData
        End Get
     End Property
     Public Sub New(ByVal hasMetaData As Boolean, ByVal duration As
Double, ByVal width As Double, ByVal height As Double, ByVal
videoDataRate As Double, ByVal audioDataRate As Double, ByVal frameRate
As Double, ByVal creationDate As DateTime)
        _hasMetaData = hasMetaData
        _duration = duration
        _width = width
        _height = height
        _videoDataRate = videoDataRate
        _audioDataRate = audioDataRate
        _frameRate = frameRate
        _creationDate = creationDate
     End Sub
  End Class
End Namespace

I’d like to also be able to get the duration off the FLV if the meta data did not get inserted, but the best solution I found () is not open source.