如何编写流播放器? |
尚未結案
|
mysql
一般會員 ![]() ![]() 發表:7 回覆:15 積分:4 註冊:2003-12-10 發送簡訊給我 |
我最近想写一个流播放器。
流播放(streaming)一般使用的方式是:cient连接到server以后,从server上读取文件,存储到client的buffer中,然后由播放器播放。
流传输的过程可以使用indy中的tidtcpserver/client来写,但播放器我就不知道如何做?
看过realone的SDK,都是VC的,好像可以通过编写插件来实现(编写插件读取自己流服务器的内容)。看起来非常复杂。
我知道使用DSPACK编写播放器非常方便,但如果用来做流播放器,该如何写?
虚心请教各位大哥,给小弟指明一条名路。
|
mysql
一般會員 ![]() ![]() 發表:7 回覆:15 積分:4 註冊:2003-12-10 發送簡訊給我 |
我已经找到一些相关的主题:
http://delphi.ktop.com.tw/topic.php?topic_id=19430
http://delphi.ktop.com.tw/topic.php?topic_id=34286
http://delphi.ktop.com.tw/topic.php?topic_id=29260
http://delphi.ktop.com.tw/topic.php?topic_id=19558
http://delphi.ktop.com.tw/topic.php?topic_id=43399 我现在设想的关键是:
没有必要选用RTSP等传输协议,只需要把影片内容下载到缓冲区,然后播放缓冲区的内容。
如果需要快进、暂停、拖动等功能,就需要分析使用者发出的命令,重新更新缓冲区。 另外,我看见过有人使用REALONE插件的方式。但由于real提供的SDK都是VC的,我不是很熟悉。不知道那位大哥能指点一下?
|
conundrum
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:893 回覆:1272 積分:643 註冊:2004-01-06 發送簡訊給我 |
|
japhenchen
高階會員 ![]() ![]() ![]() ![]() 發表:51 回覆:444 積分:184 註冊:2003-07-23 發送簡訊給我 |
其實如果用過了dspack,會知道作者其實已經把這個流媒体播放器給解決掉了~
安裝完dspack進delphi之後,在\program files\dspack\demos\d6-d7\asf\asf capture就是一個server的demo,編譯完之後就可以直接使用(demo是抓webcam),執行這支demo,然後區域網路上的隨便一台電腦,用WindowsMediaPlayer7以上版本,在選單上打開檔案->打開URL,輸入mms://10.10.10.10(這Server的ip),就可以看到你要的東西了!這支demo里設定最大客戶端數量是8台,你可以依需要改大一點,我測試到60台都沒問題,外網只要沒有防火牆阻擋,也是橫行無阻,聲音也一塊傳送哦!比起那堆死要錢的REAL STREAM SERVER好多了~~~~DSPACK跟里面的DEMO都是完全免費 藏私の禁止
|
japhenchen
高階會員 ![]() ![]() ![]() ![]() 發表:51 回覆:444 積分:184 註冊:2003-07-23 發送簡訊給我 |
|
mysql
一般會員 ![]() ![]() 發表:7 回覆:15 積分:4 註冊:2003-12-10 發送簡訊給我 |
|
mysql
一般會員 ![]() ![]() 發表:7 回覆:15 積分:4 註冊:2003-12-10 發送簡訊給我 |
很高兴又找到了一点东西:
http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=21110
它的说明是:
A direct show source filter reading a media stream directly (not from a file). Based on DSPack
....
(源代码下载:http://delphi.ktop.com.tw/topic.php?TOPIC_ID=47454)
其中,他把PLAYWIN的程序做了一些修改:
procedure TFormPlayWin.OpenMenuClick(Sender: TObject);
begin
if OpenDialog.Execute then
begin
if not FilterGraph.Active then FilterGraph.Active := true;
FilterGraph.ClearGraph; TestCustomStream(TFileStream.Create(OpenDialog.FileName,fmOpenRead or fmShareDenyWrite), MitCompressed.Checked);
exit; FilterGraph.RenderFile(OpenDialog.FileName);
VideoWindow.PopupMenu := PopupMenu;
SoundLevel.Position := FilterGraph.Volume;
FilterGraph.Play;
end;
end; procedure TFormPlayWin.TestCustomStream(Src: TStream; Compress: boolean);
var
Z : TStream;
D : TStream;
TS : TCustomSrcFilter;
Size: Int64;
begin
Size := Src.Size;
//Size := 0;
if Compress then
begin
Z := TMemoryStream.Create;
D := TCompressionStream.Create(clDefault, Z);
D.CopyFrom(Src, 0);
D.Free;
D := TDecompressionStream.Create(Z);
D.Position := 0;
Src.Free;
end
else
D := Src;
TS := TCustomSrcFilter.Create(D, Compress, Size);
RenderFilter(TS);
end; 它里面使用到一个自定义的FILTER,README.TXT如下说:
I wanted for a long time a way to play a media stream directly (not from a file). Here it is.
It was quite challenging, but in the end you have a way to render a media stream without saving to a file; for example play a sound (any kind) or avi file directly from a resource stream.
It fully supports compressed streams! The demo is compressing a file into a ZLib stream and playing it. The component is a filter with an output pin that should be rendered. It takes care of most common formats, but it may not be all; send a feedback when something is not working. It is based on DSPack; the declaration looks like this: type
TCustomSrcFilter = class(TBCBaseFilter)
protected
public
constructor Create(AStream : TStream; FwdOnly: boolean = false; const StreamSize: Int64 = 0); overload;
constructor Create(AStream : IStream; FwdOnly: boolean = false; const StreamSize: Int64 = 0); overload;
destructor Destroy; override;
function GetPin(n: Integer): TBCBasePin; override;
function GetPinCount: Integer; override; property OutPin : IPin read GetOutPin;
function NonDelegatingRelease: Integer; override; stdcall;
end; Internally it is using IStream interface, so the TStream is used via a StreamAdapter.
FwdOnly is a flag that instructs the filter to treat the stream as forward only; it means all seek operations on a previous position will first perform a seek to the start then set the position.
This is especially for ZLib implementation of streams, so there is no workaround needed to use a compressed stream! Some filters (avi parser) require the length of the stream (uncompressed). As implemented in ZLib, one can obtain the size only by setting successive positions and actually decompressing the stream; when the end is reached an error is raised. It will not break the code, but you might be misleaded when running from the debugger. It's better to use some kind of the wrapper and return a stored size when the stream is seek at the end.
New: I already modified the component so you can pass the size of the stream in the constructor. If you don't know it, of course leave it to default and it will be determined as described.
It is also possible to pass an approximation of the stream size; usually it's better to pass a bigger size. This value is used by the parser filter and I can't say exactly how it is used. One can simply build a dll with a generic direct show filter to use in other environments by registering and/or declaring some functions that create the filter. 但由于下载的程序中没有FILTER,所以还不知道它具体如何实现。
另外,如果需要改成网络播放的话,好像还有一点困难:如何把一个文件分拆开一个一个的包(package),一段一段的播放呢? 發表人 - mysql 於 2004/04/01 13:44:37
|
debussy
一般會員 ![]() ![]() 發表:0 回覆:1 積分:0 註冊:2005-04-19 發送簡訊給我 |
|
killghost
一般會員 ![]() ![]() 發表:14 回覆:21 積分:7 註冊:2004-04-21 發送簡訊給我 |
|
killghost
一般會員 ![]() ![]() 發表:14 回覆:21 積分:7 註冊:2004-04-21 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |