问题: 关于抽取DAT/MPEG中的视频/音频!(LeeChange请进!) ( 积分: 200 )
分类: 多媒体
来自: lxmzm, 时间: 2003-06-06 21:30:00, ID: 1931987
LeeChange:
你好!
在论坛上,看到你提供的方法!我试了一下,从DAT文件抽取的AVI文件,用系统播放机无法播放,在抽取音频文件后,也无法播放,这是什么原因呢?
unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons;
type
TMainForm = class(TForm)
SourceEdit: TEdit;
DestEdit: TEdit;
SourceSpeedButton: TSpeedButton;
DestSpeedButton: TSpeedButton;
ActionButton: TButton;
OpenDialog: TOpenDialog;
SaveDialog: TSaveDialog;
procedure SourceSpeedButtonClick(Sender: TObject);
procedure DestSpeedButtonClick(Sender: TObject);
procedure ActionButtonClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
function SameGUID(const a, b: TGuid): Boolean;
public
{ Public declarations }
procedure RewriteVideo(const SourceFileName, DestFileName: string);
end;
var
MainForm: TMainForm;
implementation
uses
DirectShow, ActiveX;
{$R *.dfm}
procedure TMainForm.FormCreate(Sender: TObject);
begin
CoInitialize(nil)
end;
procedure TMainForm.FormDestroy(Sender: TObject);
begin
CoUninitialize
end;
procedure TMainForm.SourceSpeedButtonClick(Sender: TObject);
begin
if OpenDialog.Execute then
SourceEdit.Text:=OpenDialog.FileName
end;
procedure TMainForm.DestSpeedButtonClick(Sender: TObject);
begin
if SaveDialog.Execute then
DestEdit.Text:=SaveDialog.FileName
end;
procedure TMainForm.ActionButtonClick(Sender: TObject);
begin
RewriteVideo(SourceEdit.Text, DestEdit.Text)
end;
procedure TMainForm.RewriteVideo(const SourceFileName,
DestFileName: string);
var
Builder: ICaptureGraphBuilder2;
Graph: IGraphBuilder;
Mux: IBaseFilter;
FileWriter: IFileSinkFilter;
MediaControl: IMediaControl;
MediaEvent: IMediaEvent;
PinEnum: IEnumPins;
Pin: IPin;
PinInfo: TPin_Info;
MediaType: TAM_Media_Type;
EVCode: Integer;
FileName: array [0..255] of WideChar;
Res: HResult;
begin
CoCreateInstance(CLSID_CaptureGraphBuilder2, nil, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, Builder);
StringToWideChar(DestFileName, FileName, 256);
Builder.SetOutputFileName(MEDIASUBTYPE_Avi, FileName, Mux, FileWriter);
Builder.GetFiltergraph(Graph);
StringToWideChar(SourceFileName, FileName, 256);
Graph.RenderFile(FileName, nil);
Mux.EnumPins(PinEnum);
Res:=PinEnum.Next(1, Pin, nil);
while Res=S_OKdo
begin
Pin.QueryPinInfo(PinInfo);
if PinInfo.dir=PINDIR_INPUT then
begin
Pin.ConnectionMediaType(MediaType);
if not SameGUID(MediaType.majortype, MediaType_Video) then
Pin.Disconnect
end;
Res:=PinEnum.Next(1, Pin, nil)
end;
Graph.QueryInterface(IID_IMediaControl, MediaControl);
Graph.QueryInterface(IID_IMediaEvent, MediaEvent);
MediaControl.Run;
MediaEvent.WaitForCompletion(INFINITE, EVCode);
MediaControl.Stop
end;
function TMainForm.SameGUID(const a, b: TGuid): Boolean;
var
i: Byte;
begin
Result:=True;
if a.D1<>b.D1 then
Result:=False
else
if a.D2<>b.D2 then
Result:=False
else
if a.D3<>b.D3 then
Result:=False
else
for i:=0 to 7do
if a.D4<>b.D4 then
begin
Result:=False;
Exit
end
end;
end.
------------
提取音频是参照另一位富翁的提示!
那个是要取视频流,这个是要音频流。
将if not SameGUID(MediaType.majortype, MediaType_Video) then
改为if not SameGUID(MediaType.majortype, MediaType_Audio) then
来自: LeeChange, 时间: 2003-06-06 21:36:00, ID: 1931997
呵呵,现在的机器上没有DirectShow的开发包.只有等到回公司再看了.
而且,我没有保存代码,你把我完整的程序贴出来吧.
来自: lxmzm, 时间: 2003-06-07 10:26:00, ID: 1932622
还有:如果LeeChange的方法可行,抽取的音频是WAV格式的吧!
在VCD/MPEG的每一帧中应该含有音频(MP2格式),能否将每帧中的音频内容直接读出,合并即可得到MP2格式的音频呢?
-----------------------------------------
下面是其他富翁的提示!
当然不是,如果你仔细的话,你会发现,MPEG的文件和VCD的DAT文件中必然有一些
特定的字符,比如 00 00 01 BA 这其实叫VCD桢头,从这开始到下一个此位置,叫
一个VCD桢,在DAT文件中每桢的长度是固定的就是2352个字节,而MPEG不是,它可能
有好几个长度,如:2048。另外VCD还加了一个VCD头,它包含以下特征符:
0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00
可真要说清这里面的区别就不是三言两语就行了,如果你想做这方面的应用软件,我
可以帮你
你读出了又有什么用呢?我不知道你想做什么,如果我们说VCD有头的话,那也不
能说明任何问题,因为我觉得与BMP不一样,BMP的头中包含了很多信息,如长,宽、
颜色值……,可MPEG和VCD都不是的,它们的信息包含在每个图桢里面,比如你可以
在这两种文件中查找特征字符:0x00,0x00,0x01,0xb3,在这之后包含了很多信息,
这才是你想要的吧。如果你感兴趣,你可以去查看同期的一个标题:好象是关于VCD
播放时的问题,你可以去看一下,可能稍微详细点
另外现在外面有很多VCD2MPG的文件,我这里有MPG2VCD的文件,我想大多数的刻录软件
也有这功能,可惜都没公布,我的么,哈哈
来自: LeeChange, 时间: 2003-06-07 10:45:00, ID: 1932669
用这种办法可以实现mpeg的音视频分离.
00 00 01 BA只是一个包的开始标记,至于是音频还是视频则分不出来.
一个视频序列层是用00 00 01 B7开始的.
来自: 3cs, 时间: 2003-06-07 16:34:00, ID: 1932971
TO:leeChange:
1。能否直接分离出MP2格式的音频?
2。能否在把分离出的AVI格式视频和MP2音频合并?
3。如何能把MP3转成MP2?
lxmzm,不好意思,借你的版面问问题了!如果问题有结果!我贴300分给你和回答者。
来自: LeeChange, 时间: 2003-06-08 14:22:00, ID: 1934511
to 3cs:
sorry,我对MPEG2的格式一点都不知道。
来自: mghpl, 时间: 2003-08-22 23:35:00, ID: 2128516
DIRECTSHOW里面有!自己看。
来自: moshengren, 时间: 2003-11-06 22:57:00, ID: 2277929
请大家帮帮忙,我现在还不能提问题,只能跟贴问了
我装了DELPHIX控件了,可是编译这类原代码时候总出现 file not found 'DXClass.dcu'
可是这个文件明明在的啊,不知道为什么,希望有人能解答,谢谢!
来自: yu_ting, 时间: 2003-11-22 9:52:00, ID: 2309704
好,我来学习
来自: 天之痕, 时间: 2003-12-03 14:45:00, ID: 2331164
楼上的大虾,这个问题好不好解决?
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2246382
电影压缩成RM后声道选择麻烦,有无软件或方法把源视频文件预处理成单声道再压缩.
如把MPG,AVI文件中的外语声道除掉,只保留国语声道.
另可否用DELPHI实现这个功能,或实现声道互换(左变右,右变左).
来自: da_yu, 时间: 2003-12-05 11:48:00, ID: 2335589
lxmzm老兄:请教你个问题。
怎样从MPG文件(MPEG-1格式)里,提取出它的帧的尺寸大小(如320X240)和帧的速率(如30/S)?能不能用一般的文件操作的方法?就是不需要打开播放器直接从文件中读取?
非常谢谢!
来自: ljlljl-79, 时间: 2004-01-03 13:14:00, ID: 2390697
学习
来自: qince, 时间: 2004-01-03 14:44:00, ID: 2390867
呵呵,去年六月份的帖子,今年还没有结贴。
其实MPEG文件可以从PES包头中找到他视音频还是视频,如果PES头为0x000001B8那末是音频,如果是0x00000001B9则为视频。
你只有将所有视频都抽出来,才能用媒体播放器播放出来,而且如果PTS、DTS(时间戳)被修改坏了,也会播放不正常。
抽取出来的视频不是AVI格式的,而是MPEG格式,是由I Frame,B Frame,P Frame组成的一系列图片。
具体还是参考ISO/IEC 11172 MPEG-1吧,
祝成功!
来自: houling, 时间: 2004-03-19 21:33:25, ID: 2511769
用DXSHOW开发,或用GRAPHEDIT来拖几个FILTER就行了。
来自: lxmzm, 时间: 2004-03-31 22:41:36, ID: 2532494
能给点代码提示吗?
追好是delphi de
问题讨论没有结束 ...