How to read FLV video files?

Source: Internet
Author: User
Tags flv file

The time length of FLV needs to be fed back during the search of the mobicast flash stream. However, if flvmdi is used to inject each file into metadata and then read and retrieve the time, so the lyrics of Eason Chan "next year today" are quite suitable for my software.
The length of time for the program to read FLV.
There are few such articles in online search. Most of them teach you how to use as to read metadata. However, if metadata is not injected, there is no way.
The following tutorial is applicable to most programming languages that can read and write files. Readers must have basic knowledge of reading and writing files. In fact, if you are not lazy and can still access the English language, you can directly look at the FLV documentation. It is natural that you are clear about what to do and you don't need to listen to me, haha.
What are the Chinese tutorials? Good, follow me!
I. header files
The FLV header file format is simple and consists of nine bytes.

The first three bytes are the file format identifier 0x464c56.
The 4th bytes are also the version 0x01 of the identification file.
5th bytes 0x05
The first five bits of this byte are reserved and must be 0.
6th bit audio type tags (typeflagsaudio)
7th bits are also reserved and must be 0
8th bit video types (typeflagsvideo)
The four bytes are retained for the upgrade of the FLV version 0x00000009.

Ii. File tag and content
The FLV file removes the header file and consists of N tags and content.
Tag1 content 1, tag2 content 2... tagn content n
The information we want to read, such as the time, is in the tag. Next I will analyze the tag.
The tag format is as follows:
1-byte type. There are currently three types of tags: audio tag (0x08), video tag (0x09), and script tag (0x12 ). (0x12 in the legend)
3 bytes of data, that is, the size of the content mentioned above is 0x000920
The timestamp of the Three-byte timestamp data (unit: millisecond, if you want to convert to second, divide by 1000) 0x000000
The timestamp of 1 byte is expanded to 0x00.
3-byte streamid, which is currently 0 0x000000
Later, 0x02 begins with the data content, such as the script data content metadata, audio data content, and video data content.
Do you still notice that there are four bytes before the 0x12 tag type: 0x00000000, which indicates the size of the previous tag. Because this is the first tag, the size of the front tag is 0.
Knowing the FLV file format, it is easy to read the time.
What? Will not read bytes? Khan. Open the search engine and enter "XX language to read bytes ".

The program is given below:

FLV. aspx

<% @ Page Language = "C #" autoeventwireup = "true" codefile = "FLV. aspx. cs" inherits = "FLV" %>

<! Doctype HTML public "-// W3C // dtd xhtml 1.0 transitional // en" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<HTML xmlns = "http://www.w3.org/1999/xhtml">
<Head runat = "server">
<Title> flvinfo </title>
<Style type = "text/CSS">
Body {font-size: 12px ;}
TD {Height: 20px; font-size: 12px; padding: 3px ;}
</Style>
</Head>
<Body>
<Form ID = "form1" runat = "server">
<Div style = "Background: # cccccc; padding-left: 20px;">
<Br/>
<Div style = "Background: # cccccc; text-align: Left; padding: 3px;">
<Strong> FLV file structure: </strong> <br/>
<Table border = "1" bordercolor = "#000000" cellpadding = "0" cellspacing = "0" style = "border-collapse: collapse;">
<Tr>
<TD style = "height: 20px" colspan = "9"> & nbsp; FLV header file format is relatively simple and consists of 9 bytes. & nbsp; </TD>
<TD style = "height: 20px" colspan = "4"> & nbsp; tag1 </TD>
<TD style = "height: 20px"> & nbsp; tag2 </TD>
<TD style = "height: 20px" colspan = "3"> & nbsp; tag3 </TD>
<TD style = "height: 20px" colspan = "3"> & nbsp; tag4 </TD>
<TD style = "height: 20px"> & nbsp; tag5 </TD>
<TD style = "height: 20px" colspan = "3"> & nbsp; tag6 </TD>
<TD style = "height: 20px;"> </TD>
</Tr>
<Tr>
<TD> 1 </TD> <TD> 2 </TD> <TD> 3 </TD> <TD> 4 </TD> <TD> 5 </TD> <TD> 6 </TD> <TD> 7 </TD> <TD> 8 </TD> <TD> 9 </TD> <TD> 10 </TD> <TD> 11 </TD> <TD> 12 </TD> <TD> 13 </TD>
<TD> 14 </TD> <TD> 15 </TD> <TD> 16 </TD> <TD> 17 </TD> <TD> 18 </TD> <TD> 19 </TD> <TD> 20 </TD> <TD> 21 </TD> <TD> 22 </TD> <TD> 23 </TD> <TD> 24 </TD> <TD> 25... </TD>
</Tr>
<Tr>
<TD style = "background-color: # ffff66; Height: 20px;"> 46 </TD> <TD style = "background-color: # ffff66; Height: 20px; "> 4C </TD>
<TD style = "background-color: # ffff66; Height: 20px;"> 56 </TD> <TD style = "background-color: # ffff66; Height: 20px; "> 01 </TD>
<TD style = "background-color: # ffff66; Height: 20px;"> 05 </TD> <TD style = "background-color: # ffff66; Height: 20px; "> 00 </TD>
<TD style = "background-color: # ffff66; Height: 20px;"> 00 </TD> <TD style = "background-color: # ffff66; Height: 20px; "> 00 </TD>
<TD style = "background-color: # ffff66; Height: 20px;"> 09 </TD> <TD style = "background-color: #72abd8; Height: 20px; "> 00 </TD>
<TD style = "background-color: #72abd8; Height: 20px;"> 00 </TD> <TD style = "background-color: #72abd8; Height: 20px; "> 00 </TD>
<TD style = "background-color: #72abd8; Height: 20px;"> 00 </TD> <TD style = "background-color: #72abd8; Height: 20px; "> 12 </TD>
<TD style = "background-color: #72abd8; Height: 20px;"> 00 </TD> <TD style = "background-color: #72abd8; Height: 20px; "> 09 </TD>
<TD style = "background-color: #72abd8; Height: 20px;"> 20 </TD> <TD style = "background-color: #72abd8; Height: 20px; "> 00 </TD>
<TD style = "background-color: #72abd8; Height: 20px;"> 00 </TD> <TD style = "background-color: #72abd8; Height: 20px; "> 00 </TD>
<TD style = "background-color: #72abd8; Height: 20px;"> 00 </TD> <TD style = "background-color: #72abd8; Height: 20px; "> 00 </TD>
<TD style = "background-color: #72abd8; Height: 20px;"> 00 </TD> <TD style = "background-color: #72abd8; Height: 20px; "> 00 </TD>
<TD style = "height: 20px;"> 02... </TD>
</Tr>
<Tr>
<TD style = "height: 20px; text-align: Left;" colspan = "3"> Format id </TD>
<TD style = "height: 20px; text-align: Left;"> version </TD>
<TD style = "height: 20px; text-align: Left;">
The first five bits of this byte are reserved and must be 0 <br/>
6th bit audio type tags (typeflagsaudio) <br/>
The value of 7th bits must be 0. <br/>
8th bit video types (typeflagsvideo) </TD>
<TD style = "height: 20px; text-align: Left;" colspan = "4"> reserved bytes for future <br/> FLV version upgrade </TD>
<TD style = "height: 20px; text-align: Left;" colspan = "4">
Size of the previous tag <br/>
Because this is the first <br/>
One tag, so none <br/>
The preceding tag <br/>
The size is 0. </TD>
<TD style = "height: 20px; text-align: Left;"> script tag (0x12) <br/> audio tag (0x08) <br/> video tag (0x09) </TD>
<TD style = "height: 20px; text-align: Left;" colspan = "3"> data size <br/> content size </TD>
<TD style = "height: 20px; text-align: Left;" colspan = "3"> timestamp <br/> in milliseconds, <br/> to convert to <br/> the second must be divided by 1000 </TD>
<TD style = "height: 20px; text-align: Left;"> time stamp extension </TD>
<TD style = "height: 20px; text-align: left; "colspan =" 3 "> streamid <br/> currently all are 0 <br/> 0x000000 </TD>
<TD style = "height: 20px; text-align: Left;">
Metadata <br/>
Data content <br/>
Script data content <br/>
Audio data content <br/>
Video data content </TD>
</Tr>
</Table>
</Div>
<Div style = "Background: # cccccc; text-align: Left; padding: 3px;">
<Asp: Label id = "flvinfo" runat = "server" text = "No information"> </ASP: Label>
</Div>
<Div style = "Background: # cccccc; text-align: Left; padding: 3px;">
<Asp: button id = "button1" runat = "server" text = "RENAME" backcolor = "darkgray" bordercolor = "#000000" borderstyle = "solid" borderwidth = "1px" onclick =" button#click "/>
</Div>
</Div>
</Form>
</Body>
</Html>

FLV. aspx. CS:

Using system;
Using system. IO;
Using system. text;

Public partial class FLV: system. Web. UI. Page
{
Protected void page_load (Object sender, eventargs E)
{
//
}

Public struct flvinfo
{
// Header file
Public String expand; // The format of the three bytes (the first three bytes are identified in the format .)
Public String version; // 1 byte, version, (4th bytes are also the version number of the identification file)
Public String flags; // one byte, flag. (the first five bits of this Byte must be 0 and the first 6th bits of the audio type are reserved (typeflagsaudio, 7th bits must also be retained 0 and 8th bits (typeflagsvideo ))
Public String verupgrade; // 4 bytes, upgrade, (the four bytes in the range of 6-9 are retained for the upgrade of FLV version 0x00000009 .)
// Tag
Public String fronttagsize; // 4 bytes, the size of the previous tag
Public String tagclass; // one byte. There are currently three tag types: audio tag (0x08) and video tag (0x09 ), script tag (0x12 ).
Public String contentsize; // 3 bytes, data size, that is, the size of the content mentioned above
Public String alltime; // three bytes, timestamp, and data timestamp (unit: milliseconds. If you want to convert it to seconds, divide it by 1000)
Public String timeexpand; // 1 byte, time stamp Extension
Public String streamid; // three bytes, streamid, all 0 0x000000
}

/// <Summary>
/// Obtain the starting 24 bytes of the FLV File
/// </Summary>
/// <Param name = "FILENAME"> file name </param>
/// <Returns> Returns a byte array </returns>
Private byte [] getbegin24 (string filename)
{
Filestream FS = new filestream (filename, filemode. Open, fileaccess. Read );
Stream stream = FS;
Stream. Seek (0, seekorigin. Begin );
Const int seekpos = 64;
Int RL = 0;
Byte [] info = new byte [seekpos];
RL = stream. Read (Info, 0, seekpos );
FS. Close ();
Stream. Close ();
Return Info;
}

/// <Summary>
/// Obtain FLV-related information, segment the byte array returned above, and save it to the flvinfo structure for return.
/// </Summary>
/// <Param name = "info"> binary information captured from the FLV file </param>
/// <Returns> Returns a flvinfo structure </returns>
Private flvinfo getflvinfo (byte [] info)
{
Flvinfo = new flvinfo ();
Int I;
Int J;
Int position = 0; // The starting value of the loop
Int currentindex = 0; // The current index value of info

//// Obtain the format
J = 0;
Byte [] bytexpand = new byte [3]; // read the format part to a separate array.
For (I = currentindex; I <currentindex + 3; I ++)
{
Bytexpand [J] = info [I];
Position ++;
J ++;
}
Currentindex = position;
Flvinfo. Expand = This. bytetostring (bytexpand );

// Obtain the version
J = 0;
Byte [] bytversion = new byte [1]; // read the version part to a separate array.
For (I = currentindex; I <currentindex + 1; I ++)
{
Bytversion [J] = info [I];
Position ++;
J ++;
}
Currentindex = position;
Flvinfo. Version = This. bytetostring (bytversion );

// Obtain flags
J = 0;
Byte [] bytflags = new byte [1]; // read the flags part into a separate array.
For (I = currentindex; I <currentindex + 1; I ++)
{
Bytflags [J] = info [I];
Position ++;
J ++;
}
Currentindex = position;
Flvinfo. Flags = This. bytetostring (bytflags );

// Obtain verupgrade
J = 0;
Byte [] bytverupgrade = new byte [4]; // read verupgrade into a separate array.
For (I = currentindex; I <currentindex + 4; I ++)
{
Bytverupgrade [J] = info [I];
Position ++;
J ++;
}
Currentindex = position;
Flvinfo. verupgrade = This. bytetostring (bytverupgrade );

// Obtain fronttagsize
J = 0;
Byte [] bytfronttagsize = new byte [4]; // read the fronttagsize part into a separate array.
For (I = currentindex; I <currentindex + 4; I ++)
{
Bytfronttagsize [J] = info [I];
Position ++;
J ++;
}
Currentindex = position;
Flvinfo. fronttagsize = This. bytetostring (bytfronttagsize );

// Tagclass
J = 0;
Byte [] byttagclass = new byte [1]; // read the fronttagsize part into a separate array.
For (I = currentindex; I <currentindex + 1; I ++)
{
Byttagclass [J] = info [I];
Position ++;
J ++;
}
Currentindex = position;
Flvinfo. tagclass = This. bytetostring (byttagclass );

// Contentsize
J = 0;
Byte [] bytcontentsize = new byte [3]; // read the contentsize part to a separate Array
For (I = currentindex; I <currentindex + 3; I ++)
{
Bytcontentsize [J] = info [I];
Position ++;
J ++;
}
Currentindex = position;
Flvinfo. contentsize = This. bytetostring (bytcontentsize );

// Alltime
J = 0;
Byte [] bytalltime = new byte [3]; // read the alltime part into a separate array.
For (I = currentindex; I <currentindex + 3; I ++)
{
Bytalltime [J] = info [I];
Position ++;
J ++;
}
Currentindex = position;
Flvinfo. alltime = This. bytetostring (bytalltime );

// Timeexpand
J = 0;
Byte [] byttimeexpand = new byte [1]; // read the timeexpand part into a separate array.
For (I = currentindex; I <currentindex + 1; I ++)
{
Byttimeexpand [J] = info [I];
Position ++;
J ++;
}
Currentindex = position;
Flvinfo. timeexpand = This. bytetostring (byttimeexpand );

// Streamid
J = 0;
Byte [] bytstreamid = new byte [3]; // read the streamid part to a separate array.
For (I = currentindex; I <currentindex + 3; I ++)
{
Bytstreamid [J] = info [I];
Position ++;
J ++;
}
Currentindex = position;
Flvinfo. streamid = This. bytetostring (bytstreamid );

Return flvinfo;
}

/// <Summary>
/// Convert the byte array into a string. the method used by the above program.
/// </Summary>
/// <Param name = "B"> byte array </param>
/// <Returns> returns the converted string </returns>
Private string bytetostring (byte [] B)
{
Encoding ENC = encoding. getencoding ("gb2312 ");
String STR = enc. getstring (B );
STR = Str. substring (0, str. indexof ('/0')> = 0? Str. indexof ('/0'): Str. Length); // Remove useless characters
Return STR;
}

/// <Summary>
/// Change the file name
/// </Summary>
/// <Param name = "filepath"> file name </param>
/// <Returns> </returns>
Private bool Rename (string filepath)
{
If (file. exists (filepath ))
{
Flvinfo = new flvinfo ();
Flvinfo = This. getflvinfo (this. getbegin24 (filepath); // read the file information

If (flvinfo. Expand. Trim (). Length = 0)
{
Flvinfo. Expand = "unknown format ";
}
If (flvinfo. alltime. Trim (). Length = 0)
{
Flvinfo. alltime = "unknown time ";
}
Try
{
/// Rename
// File. move (filepath, filepath. substring (0, filepath. tolower (). lastindexof ("//")). trim () + "//" + "(" + flvinfo. expand. trim () + ")" + flvinfo. alltime. trim () + ". FLV ");
// Response. Write ("<SCRIPT> alert ('flv renamed successfully! '); </SCRIPT> ");
String B = "<Table border = '1' bordercolor = '#000000 'cellpadding = '0' cellspacing = '0' style = 'border-collapse: collapse;'>"
+ "<Tr>"
+ "<TD> Format id </TD> <TD> Version Number </TD> <TD> first five BITs </TD> <TD> retain byte </TD> <TD> the size of the previous tag </TD>"
+ "<TD> script tag </TD> <TD> data size </TD> <TD> timestamp </TD> <TD> time extension </TD> <TD> streamid </TD>"
+ "</Tr>"
+ "<Tr>"
+ "<TD>" + flvinfo. Expand + "</TD>"
+ "<TD>" + flvinfo. Version + "</TD>"
+ "<TD>" + flvinfo. Flags + "</TD>"
+ "<TD>" + flvinfo. verupgrade + "</TD>"
+ "<TD>" + flvinfo. fronttagsize + "</TD>"
+ "<TD>" + flvinfo. fronttagsize + "</TD>"
+ "<TD>" + flvinfo. contentsize + "</TD>"
+ "<TD>" + flvinfo. alltime + "</TD>"
+ "<TD>" + flvinfo. timeexpand + "</TD>"
+ "<TD>" + flvinfo. streamid + "</TD>"
+ "</Tr>"
+ "</Table> ";
// Response. Write (B );
This. flvinfo. Text = B;
Return true;

}
Catch (exception E)
{
Response. Write (E. tostring ());
Return false;
}
}
Else
{
Response. Write ("<SCRIPT> alert ('flv file does not exist! '); </SCRIPT> ");
Return false;
}
}
Protected void button#click (Object sender, eventargs E)
{
Rename (@ "D:/FFMPEG/ps1.flv ");
}
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.