DELPHI获取flash文件的影片时长,原始尺寸,帧数等信息


本文整理自网络,侵删。

 

感谢“温柔刀客”的努力,找到一篇不错的Flash编程文章,也感谢文章的作者,解决了我一个困惑了很久的问题,呵呵~~~

unit uFlash;

interface

uses
   windows, SysUtils, Classes, Zlib;

type
   TBitWidth = Integer;
   TSWFRect = packed record
     Xmin: Integer;                                           // in twips
     Xmax: Integer;                                           // in twips
     Ymin: Integer;                                           // in twips
     Ymax: Integer;                                           // in twips
   end;

   TSWFColor = packed record
     R : Byte;
     G : Byte;
     B : Byte;
     RGB : string;
   end;

   TSWFHeader = packed record
     Signature: array[0..2] of char;
     Version: byte;
     FileLength: cardinal;
     FrameSize: TSWFRect;
     FrameRate: byte;
     FrameRateRemainder: byte;
     FrameCount: cardinal;
     BkColor : TSWFColor;
   end;

   TTagHandle   = record
     ID   : Integer;
     Length   : Integer;
     HandleLength   : Integer;
   end;
  
function GetSwfFileHeader(const FileName: string; var Header: TSWFHeader): boolean;

implementation

function ReadNBits(const Buffer; Position: longint; Count: TBitWidth): longint;
var
   I, B: longint;
begin
   Result := 0;
   B := 1 shl (Count - 1);
   for I := Position to Position + Count - 1 do
   begin
     if (PByteArray(@Buffer)^[I div 8] and (128 shr (I mod 8))) <> 0 then
       Result := Result or B;
     B := B shr 1;
   end;
end;

function ReadTagHandle(const Buffer; Position : Longint): TTagHandle;
var
   v : Smallint;
begin
   v :=   PSmallint(@PByteArray(@Buffer)^[Position])^;
   Result.ID :=   v shr 6;
   v :=   v shl 10;
   Result.Length :=   v shr 10;
   if Result.Length = $FFFFFF then
   begin
     //长tag
     Result.HandleLength :=   6;
     Result.Length :=   PInteger(@PByteArray(@Buffer)^[Position + 2])^;
   end
   else
     Result.HandleLength :=   2;
end;

function GetSwfFileHeader(const FileName: string; var Header: TSWFHeader): boolean;
const
   BuffSize = 64;
var
   Buffer: PByteArray;
   NBitsField: byte;
   Poz: longword;
   FileStream: TFileStream;
   MemStream: TMemoryStream;
   ZStream: TDecompressionStream;
   Tag : TTagHandle;
begin
   Result := False;
   if not FileExists(FileName) then
     Exit;
   FileStream := TFileStream.Create(FileName, fmOpenRead);
   try
     FileStream.Position := 0;
     if FileStream.Size > 22 then
     begin
       GetMem(Buffer, BuffSize);
       try
         FileStream.Read(Header, 8);
         if (Header.Signature = 'CWS') and (Header.Version >= 6) then
         begin
           Result := True;
           MemStream := TMemoryStream.Create;
           try
             MemStream.CopyFrom(FileStream, FileStream.Size - 8);
             MemStream.Position := 0;
             ZStream := TDecompressionStream.Create(MemStream);
             try
               ZStream.Read(Buffer^, BuffSize);
             finally
               ZStream.Free;
             end;
           finally
             MemStream.Free;
           end;
         end
         else
         begin
           FileStream.Read(Buffer^, BuffSize);
           Result := Header.Signature = 'FWS';
         end;

         if Result then
           with Header do
           begin
             Poz := 0;
             NBitsField := TBitWidth(ReadNBits(Buffer^, Poz, 5));
             Inc(Poz, 5);
             FrameSize.Xmin := Integer(ReadNBits(Buffer^, Poz, NBitsField));
             Inc(Poz, NBitsField);
             FrameSize.Xmax := Integer(ReadNBits(Buffer^, Poz, NBitsField));
             Inc(Poz, NBitsField);
             FrameSize.Ymin := Integer(ReadNBits(Buffer^, Poz, NBitsField));
             Inc(Poz, NBitsField);
             FrameSize.Ymax := Integer(ReadNBits(Buffer^, Poz, NBitsField));
             Inc(Poz, NBitsField);
             NBitsField := Poz mod 8;
             Poz := Poz div 8;
             if (NBitsField > 0) then
               Inc(Poz);
             FrameRateRemainder := Buffer^[Poz];              // 8.[8]
             FrameRate := Buffer^[Poz + 1];
             FrameCount := Buffer^[Poz + 2] or (Buffer^[Poz + 3] shl 8);
             Inc(Poz, 4);
             Tag :=   ReadTagHandle(Buffer^, poz);
             while Tag.ID <> 9 do
             begin
               Inc(Poz, Tag.Length + Tag.HandleLength);
               Tag :=   ReadTagHandle(Buffer^, Poz);
             end;
             BkColor.R := Buffer^[Poz + 2];
             BkColor.G := Buffer^[Poz + 3];
             BkColor.B := Buffer^[Poz + 4];
             BkColor.RGB :=   StringReplace(
                 Format('%2x%2x%2x', [BkColor.R, BkColor.G, BkColor.B]),
                 ' ', '0', [rfReplaceAll]); 
           end;

       finally
         FreeMem(Buffer);
       end;
     end;
   finally
     FileStream.Free;
   end;
end;

end.

=====================

一个运行实例:

procedure TForm1.Button4Click(Sender: TObject);
var
    Head: TSWFHeader;
    Xmin, Ymin, XMax,YMax:integer;
begin
    M.Clear;
    if not FIleExists(Edit1.Text) then exit;
    if not GetSwfFileHeader(Edit1.Text, Head)
        then SHowmessage('读取出错');

    //注意需要 div 20 才得到真正的像素大小
    //XMin:=Head.FrameSize.Xmin div 20;
    XMax:=Head.FrameSize.Xmax div 20;
    //YMin:=Head.FrameSize.Ymin div 20;
    YMax:=Head.FrameSize.Ymax div 20;
    //M.Lines.Add(inttostr(XMin));

    M.Lines.Add('当前影片的长是:'+inttostr(XMax));
    //M.Lines.Add(inttostr(YMin));
    M.Lines.Add('当前影片的宽是:'+inttostr(YMax));
end;

相关阅读 >>

Delphi xe5发送短信以及读取短信代码

Delphi中使用tthread类实现多线程

Delphi 字符串保存utf-8过程

Delphi fmx用timage显示不同格式的图片

Delphi xe5 android获取手机联系人,并用listview显示

Delphi 中相对路径与绝对路径函数说明

Delphi通过调用com对象实现更改桌面壁纸

Delphi 在桌面上画图

Delphi 检查注册表键、键值是否存在

Delphi xe5 android平台 调用 webservice

更多相关阅读请进入《Delphi》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...