如何得知一个swf文件的播放长度(秒)?(50分)

  • 主题发起人 主题发起人 iseek
  • 开始时间 开始时间
怎么,没人知道?
 
flash swf的格式是对外公布的,可以去找一找国外的网站
 
只可以取到总桢数,时间可能需要通过总桢数通过每桢时间进行计算
 
难道不能从swf中读出点什么来?
请知道的人伸出援手.
 
有一些SWF文件是可以的,而有一些暂时还不行
可以得到时间长度的SWF文件是没有经过特殊处理的,我们可以得到总帧数,帧率,那么时间长度=总帧数/帧率。关于总帧数,帧率的获取我会在下面说明。
有一些SWF文件经过特殊处理,比如Showgood的小兵,你会发现它的总帧数只有200多帧,而实际上影片时间长度远不止200多帧,它是把实际影片的内容做成一个剪辑,这样播放是正常的,但我们却没办法正常的去控制、得到实际总帧数。。。

SFW文件格式,以一个实际的SWF文件头为例:
46 57 53 05 B4 66 07 00 70 00 0F A0 00 00 BB 80
00 0C 9F 03
字节 1-3 (46 57 53): SWF文件头标志,FWS表示未压缩,CWS表示压缩的SWF文件,需要从第9个字节起用ZLib解压
字节 4 (05): Flash文件的版本,这里表明它是用Flash5生成的
字节 5-8 (B4 66 07 00):一个Integer表示文件的长度,低在前,高在后,这里是$000766B4 = 485044字节,这里应该等于未压缩的SWF文件实际大小或压缩过的SWF解压后的长度+文件头(8字节)
字节 9 - 。。。: SWF显示区域,(左上角坐标,右下角坐标),用下面的方法计算得到:
第9字节前5位(70 shr 3 = 14),以后的字节以14位进行分割,所需位数为 14*4+5 = 61,需要 8 个字节来表示,那么:
70 00 0F A0 00 00 BB 80
01110 00000000000 00001111 10100000 00000000 0000000 010111011 10000000
01110 00000000000000 01111101000000 00000000000000 01011101110000 000
14 0 8000 0 6000
因为Flash的坐标是TWIP格式的,需要除以20的,所以实际为(0,400,0,300)
接下来的两字节 (00 0C):表示帧速率,前一字节表示小数位,后一字节表示整数位,不过一般极少有小数位的帧率,所以一般我们只计整数就可以了,这里 $0C = 12,即每秒12帧
再接下来的两字节 (9F 03):表示总帧数,WORD类型,$039F=927帧,与ShockwaveFlash.TotalFrames 得到的数值是一样的。
再接下来的数据就是SWF的实体数据了,有兴趣的话可以去 openswf.org 看看、继续研究。。。
 
SWF影片是一个多分支交互式的程序,无法具体统计播放的时间,只能统计主场景的帧数。
 
对于单帧的,无法计算,对于多帧的,可以粗略计算:

总帧数/速率. 总帧数可以由控件取得,速率要读取文件的结构得得.

SWF格式已经公开.

5.0及以下的请到www.openswf.org
mx格式的,要到MM网站注册后取得.

我已经下载一个了,如有需要,我发一个经你.

我也写过一个Flash播放器,涉及很多Flash文件结构,如果需要,也可以发给你(VB,两年前写的,开源.名字叫OpenPlayer.http://www.dapha.net有下载)
 
我其实不想搞那么复杂。
我只是用TWebbrowser控件放swf文件。
我想,如果知道了swf文件的长度(秒),就可以连续地播放不同的swf文件了。

另外,如果能判断喇叭无声也行,但我不会。
再听听,明天发分。
谢谢各位,尤其是pihome。
 
我这里引用别人的一下,他这个程序符合你的要求,按总帧数一帧一帧往下播放,播完一首接着播下一首。可自动跳过鼠标点击等互动过程。URL:http://www.playicq.com/dispdocnew.php?id=1486
源码如下:
 unit main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Buttons, Menus, StdCtrls,shellapi, ComCtrls, ShlObj,ExtCtrls;

const my_msg=Wm_user+100;
type
Tfrmlist = class(TForm)
GroupBox1: TGroupBox;
ListBox1: TListBox;
popm: TPopupMenu;
F1: TMenuItem;
D1: TMenuItem;
N1: TMenuItem;
D2: TMenuItem;
N2: TMenuItem;
P1: TMenuItem;
S1: TMenuItem;
U1: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
GroupBox2: TGroupBox;
btnnext: TSpeedButton;
btnprior: TSpeedButton;
btnstop: TSpeedButton;
btnplay: TSpeedButton;
opendlg: TOpenDialog;
Savedlg: TSaveDialog;
L1: TMenuItem;
C1: TMenuItem;
N3: TMenuItem;
N6: TMenuItem;
Timer1: TTimer;
btndir: TSpeedButton;
btnfile: TSpeedButton;
btnsave: TSpeedButton;
btnclear: TSpeedButton;
btnlist: TSpeedButton;
opendlg1: TOpenDialog;
N7: TMenuItem;
TrackBar1: TTrackBar;
t1: TMenuItem;
btnpic: TSpeedButton;
procedure F1Click(Sender: TObject);
procedure btnplayClick(Sender: TObject);
procedure btnstopClick(Sender: TObject);
procedure ListBox1Click(Sender: TObject);
procedure ListBox1KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure btnpriorClick(Sender: TObject);
procedure btnnextClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure btnclearClick(Sender: TObject);
procedure btndirClick(Sender: TObject);
procedure btnsaveClick(Sender: TObject);
procedure btnlistClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure D2Click(Sender: TObject);
procedure N6Click(Sender: TObject);
procedure ListBox1DblClick(Sender: TObject);
procedure N7Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure TrackBar1Exit(Sender: TObject);
procedure TrackBar1Enter(Sender: TObject);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure t1Click(Sender: TObject);
procedure btnpicClick(Sender: TObject);
private
{ Private declarations }

public
{ Public declarations }

function SearchFile(mainpath:string;filename:string;var foundresult:TStrings):Boolean;
function closerunexe(runexename:string):boolean;
end;



var
frmlist: Tfrmlist;
curindex:integer=-1;
count:integer=0;
c2:integer=0;
implementation

uses falsh;

{$R *.DFM}

procedure Tfrmlist.F1Click(Sender: TObject);
begin
if opendlg.Execute then
begin
listbox1.Items.AddStrings(opendlg.Files );
end;
end;

procedure Tfrmlist.btnplayClick(Sender: TObject);
begin
if listbox1.Items.Count<1 then exit;
if n7.Checked then
begin
closerunexe('Macromedia Flash Player 6');
ShellExecute(handle,nil,pchar(listbox1.Items[listbox1.itemindex]),nil,nil,sw_shownormal);
Timer1.Enabled:=false;
exit;
end;
count:=0;
if frmflash=nil then
begin
frmflash:=Tfrmflash.Create(application);
frmflash.fplayer.Movie:=listbox1.Items[listbox1.itemindex];
//frmflash.Show;
frmflash.Visible:=not t1.Checked;
trackbar1.Max :=frmflash.fplayer.TotalFrames;
frmflash.fplayer.Play;
end
else
begin
frmflash.fplayer.Stop;
frmflash.fplayer.Movie:=listbox1.Items[listbox1.itemindex];
trackbar1.Max :=frmflash.fplayer.TotalFrames;
//frmflash.Show;
frmflash.Visible:=not t1.Checked;
frmflash.fplayer.Play;
end;
Timer1.Enabled:=true;

end;

procedure Tfrmlist.btnstopClick(Sender: TObject);
begin
frmflash.fplayer.Stop;
timer1.Enabled:=false;
frmlist.Caption:='Flash 播放器';
end;

procedure Tfrmlist.ListBox1Click(Sender: TObject);
begin
curindex:=listbox1.ItemIndex;
end;

procedure Tfrmlist.ListBox1KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
curindex:=listbox1.ItemIndex;
end;

procedure Tfrmlist.btnpriorClick(Sender: TObject);
begin
if curindex<1 then
listbox1.ItemIndex:=listbox1.Items.Count-1
else
listbox1.ItemIndex:=listbox1.ItemIndex-1;
curindex:=listbox1.ItemIndex;
//listbox1.Selected[curindex-1]:=true;
btnplayClick(nil);
end;

procedure Tfrmlist.btnnextClick(Sender: TObject);
begin
if listbox1.Items.Count <1 then exit;

if curindex=listbox1.Items.Count-1 then
listbox1.ItemIndex:=0
else
listbox1.ItemIndex:=listbox1.ItemIndex+1;
curindex:=listbox1.ItemIndex;
// listbox1.Selected[curindex-1]:=true;
btnplayClick(nil);
end;

procedure Tfrmlist.Timer1Timer(Sender: TObject);
begin

if frmflash=nil then exit;
//if not frmflash.fplayer.Playing then exit;


trackbar1.Max :=frmflash.fplayer.TotalFrames;
TrackBar1.Position:=frmflash.fplayer.FrameNum;;
frmlist.Caption:='正在播放: '+inttostr(frmflash.fplayer.FrameNum)+'/'+
inttostr(frmflash.fplayer.TotalFrames)+'帧';
application.Title:=inttostr(frmflash.fplayer.FrameNum)+'/'+
inttostr(frmflash.fplayer.TotalFrames)+' '+extractfilename(frmflash.fplayer.Movie );

if TrackBar1.Position-count=0 then
begin
if frmflash.fplayer.TotalFrames-frmflash.fplayer.FrameNum<100 then
begin
count:=0;
btnnextClick(nil);

end
else
begin
count:=count+5;
frmflash.fplayer.GotoFrame(count);
frmflash.fplayer.Play;
end;
end
else
begin
if TrackBar1.Position<count then
begin
if frmflash.fplayer.TotalFrames-count<12 then
btnnextClick(nil)
else
begin
count:=count+5;
frmflash.fplayer.GotoFrame(count);
frmflash.fplayer.Play;
end;

end
else
count:=TrackBar1.Position;

end;

end;

procedure Tfrmlist.btnclearClick(Sender: TObject);
begin
if messagebox(handle,'确定要清空播放列表吗?','确认',MB_OKCANCEL+MB_ICONQUESTION )<>IDOK then exit;
listbox1.Clear;
curindex:=-1;
end;

procedure Tfrmlist.btndirClick(Sender: TObject);
var
Info: TBrowseInfo;
Dir: array[0..260] of char;
ItemId: PItemIDList;
tmpstrings:Tstrings;
begin
with Info do
begin
hwndOwner := self.Handle;
pidlRoot := nil;
pszDisplayName := nil;
lpszTitle := '请选择文件夹';
ulFlags := 0;
lpfn := nil;
lParam := 0;
iImage := 0;
end;
ItemId := SHBrowseForFolder(Info);
if ItemId <> nil then
begin
SHGetPathFromIDList(ItemId, @Dir);
//edtdir1.Text := string(Dir);
//showmessage( string(Dir));
tmpstrings:=Tstringlist.Create;
try
if length(string(Dir))=3 then
SearchFile(string(Dir), '*.swf',tmpstrings)
else
SearchFile(string(Dir)+'/', '*.swf',tmpstrings);
finally
tmpstrings.Free;
end;


end;


end;
function IsValidDir(SearchRec:TSearchRec):Boolean;
begin
if (SearchRec.Attr=16) and
(SearchRec.Name<>'.') and
(SearchRec.Name<>'..') then
Result:=True
else
Result:=False;
end;
function Tfrmlist.SearchFile(mainpath, filename: string;
var foundresult: TStrings): Boolean;
var
i:integer;
Found:Boolean;
subdir1:TStrings;
searchRec:TsearchRec;
begin
found:=false;
if Trim(filename)<>'' then
begin
subdir1:=TStringList.Create;//字符串列表必须动态生成
//找出所有下级子目录。
if (FindFirst(mainpath+'*.*', faDirectory, SearchRec)=0) then
begin
if IsValidDir(SearchRec) then
subdir1.Add(SearchRec.Name);

while (FindNext(SearchRec) = 0) do
begin //查找当前目录。
if IsValidDir(SearchRec) then
subdir1.Add(SearchRec.Name)
else
begin
if FileExists(mainpath+filename) then
begin
foundresult.Add(mainpath+SearchRec.Name);
if SearchRec.Name<>'..' then
begin
if uppercase(ExtractFileExt(SearchRec.Name))=uppercase(ExtractFileExt(filename)) then
listbox1.Items.Add(mainpath+SearchRec.Name);
end;
end;
end;
end;
end;
FindClose(SearchRec);
found:=true;
//这是递归部分,查找各子目录。

for i:=0 to subdir1.Count-1 do
found:=Searchfile(mainpath+subdir1.Strings+
'/',Filename,foundresult)or found;
//资源释放并返回结果。
subdir1.Free;
end;
result:=found;
end;




procedure Tfrmlist.btnsaveClick(Sender: TObject);
begin
savedlg.InitialDir:=extractfilepath(application.exename);
if savedlg.Execute then
listbox1.Items.SaveToFile(savedlg.FileName);
end;

procedure Tfrmlist.btnlistClick(Sender: TObject);
begin
opendlg1.InitialDir:=extractfilepath(application.exename);
if opendlg1.Execute then
listbox1.Items.LoadFromFile(opendlg1.FileName);
end;

procedure Tfrmlist.FormCreate(Sender: TObject);
begin
if fileexists(extractfilepath(application.exename)+'1.lst') then
listbox1.Items.LoadFromFile( extractfilepath(application.exename)+'1.lst');
end;

procedure Tfrmlist.D2Click(Sender: TObject);
begin
listbox1.Items.Delete(listbox1.ItemIndex);
end;

procedure Tfrmlist.N6Click(Sender: TObject);
begin

n6.Checked:=not n6.Checked;
if n6.Checked then
frmlist.FormStyle:=fsStayOnTop
else
frmlist.FormStyle:=fsNormal;

end;

procedure Tfrmlist.ListBox1DblClick(Sender: TObject);
begin
btnplayClick(nil);
end;

procedure Tfrmlist.N7Click(Sender: TObject);
begin
n7.Checked:=not n7.Checked;
end;

function Tfrmlist.closerunexe(runexename: string): boolean;
var
hCurrentWindow,RvHandle: HWnd;
szText: array[0..254] of char;
curexename:string;
begin
result:=false;
{
hCurrentWindow := GetWindow(Handle, GW_HWNDFIRST);
while hCurrentWindow <> 0 do
begin
if GetWindowText(hCurrentWindow, @szText, 255) > 0 then
begin
curexename:=StrPas(@szText);
if (pos(runexename,curexename)<>0)then
begin
RvHandle := FindWindow(nil,pchar(curexename));
if RvHandle > 0 then
begin
SendMessage(RvHandle, wm_close,0,0);
result:=true;
end;
end;
end;
end; //while
}
RvHandle := FindWindow(nil,pchar(runexename));
if RvHandle > 0 then
begin
SendMessage(RvHandle, wm_close,0,0);
result:=true;
end;
end;

procedure Tfrmlist.FormClose(Sender: TObject; var Action: TCloseAction);
begin
closerunexe('Macromedia Flash Player 6');
end;

procedure Tfrmlist.TrackBar1Exit(Sender: TObject);
begin
if not frmflash.fplayer.Playing then
frmflash.fplayer.GotoFrame(trackbar1.position);
count:=trackbar1.position;
frmflash.fplayer.Play;
timer1.Enabled:=true;
end;

procedure Tfrmlist.TrackBar1Enter(Sender: TObject);
begin
frmflash.fplayer.Stop;
timer1.Enabled:=false;
end;

procedure Tfrmlist.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
//listbox1.SetFocus;

end;



procedure Tfrmlist.t1Click(Sender: TObject);
begin
t1.Checked:=not t1.Checked;
frmflash.Visible:=not t1.Checked;
btnpic.Down:=not t1.Checked;


end;

procedure Tfrmlist.btnpicClick(Sender: TObject);
begin

t1Click (nil);
//btnpic.Down:=not t1.Checked;

end;

end.


 
谢谢各位.
分数太少,不好意思
wudaqi 25
pihome 15
iamfish 10
 
多人接受答案了。
 

Similar threads

后退
顶部