关于抽取DAT/MPEG中的视频/音频!(LeeChange请进!)(200分)

  • 主题发起人 主题发起人 lxmzm
  • 开始时间 开始时间
L

lxmzm

Unregistered / Unconfirmed
GUEST, unregistred user!
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

 
呵呵,现在的机器上没有DirectShow的开发包.只有等到回公司再看了.
而且,我没有保存代码,你把我完整的程序贴出来吧.
 
还有:如果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的文件,我想大多数的刻录软件
也有这功能,可惜都没公布,我的么,哈哈
 
用这种办法可以实现mpeg的音视频分离.
00 00 01 BA只是一个包的开始标记,至于是音频还是视频则分不出来.
一个视频序列层是用00 00 01 B7开始的.
 
TO:leeChange:
1。能否直接分离出MP2格式的音频?
2。能否在把分离出的AVI格式视频和MP2音频合并?
3。如何能把MP3转成MP2?

lxmzm,不好意思,借你的版面问问题了!如果问题有结果!我贴300分给你和回答者。
 
to 3cs:
sorry,我对MPEG2的格式一点都不知道。
 
DIRECTSHOW里面有!自己看。
 
请大家帮帮忙,我现在还不能提问题,只能跟贴问了

我装了DELPHIX控件了,可是编译这类原代码时候总出现 file not found 'DXClass.dcu'
可是这个文件明明在的啊,不知道为什么,希望有人能解答,谢谢!
 
好,我来学习
 
楼上的大虾,这个问题好不好解决?
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2246382
电影压缩成RM后声道选择麻烦,有无软件或方法把源视频文件预处理成单声道再压缩.
如把MPG,AVI文件中的外语声道除掉,只保留国语声道.
另可否用DELPHI实现这个功能,或实现声道互换(左变右,右变左).
 
lxmzm老兄:请教你个问题。
怎样从MPG文件(MPEG-1格式)里,提取出它的帧的尺寸大小(如320X240)和帧的速率(如30/S)?能不能用一般的文件操作的方法?就是不需要打开播放器直接从文件中读取?
非常谢谢!
 
呵呵,去年六月份的帖子,今年还没有结贴。
其实MPEG文件可以从PES包头中找到他视音频还是视频,如果PES头为0x000001B8那末是音频,如果是0x00000001B9则为视频。
你只有将所有视频都抽出来,才能用媒体播放器播放出来,而且如果PTS、DTS(时间戳)被修改坏了,也会播放不正常。
抽取出来的视频不是AVI格式的,而是MPEG格式,是由I Frame,B Frame,P Frame组成的一系列图片。
具体还是参考ISO/IEC 11172 MPEG-1吧,
祝成功!
 
用DXSHOW开发,或用GRAPHEDIT来拖几个FILTER就行了。
 
能给点代码提示吗?
追好是delphi de
 
后退
顶部