FredAt Member
Joined: 14 Apr 2009 Location: USA
|
|
Hello All,
I am quite new to DirectShow programming so I am hoping that someone here can give me some useful tips. Briefly, here is what I need to do
a. Take a sequence of bitmaps and build a WMV file - this I have already done and understand perfectly how it works.
b. Convert a .WAV file to .WMA. This too I have been able to do with little difficulty.
c. Combine the WMV and the WMA into a single output WMV file.
Here is the Delphi code I have written to do the job
| Code: |
constructor TWMVJoiner.CreateEx(const AOut,AAudio,AVideo:WideString);
var AData,j:DWORD;
i,ALen:WORD;
AName:WideString;
AMgr2:IWMProfileManager2;
begin
Create;
CheckWMV(WMCreateSyncReader(nil,0,FAReader));
CheckWMV(WMCreateSyncReader(nil,0,FVReader));
CheckWMV(FAReader.Open(PWideChar(AAudio)));
CheckWMV(FVReader.Open(PWideChar(AVideo)));
CheckWMV(FAReader.SetReadStreamSamples(1,True));
CheckWMV(FVReader.SetReadStreamSamples(1,True));
CheckWMV(WMCreateProfileManager(FMgr));
CheckWMV(FMgr.QueryInterface(IID_IWMProfileManager2,AMgr2));
CheckWMV(AMgr2.SetSystemProfileVersion(WMT_VER_9_0));
AMgr2:=nil;
CheckWMV(FMgr.LoadProfileByID(WMProfile_V80_384Video,FProfile));
//CheckWMV(FProfile.CreateNewStream(WMMEDIATYPE_Video,FVStream));
//CheckWMV(FProfile.AddStream(FVStream));
CheckWMV(WMCreateWriter(nil,FWriter));
CheckWMV(FWriter.GetInputCount(j));
CheckWMV(FWriter.SetProfile(FProfile));
CheckWMV(FWriter.GetInputCount(j));
ShowMessage(IntToStr(j));
for i:=0 to 1 do CheckWMV(FWriter.SetInputProps(i,nil));
CheckWMV(FWriter.SetOutputFilename(PWideChar(Aout)));
CheckWMV(FWriter.GetInputCount(j));
ShowMessage(IntToStr(j));
AddCodecInfo(FAReader);
AddCodecInfo(FVReader);
DoWriting;
end;
procedure TWMVJoiner.AddCodecInfo(AReader:IWMSyncReader);
var hReader:IWMHeaderInfo2;
hWriter:IWMHeaderInfo3;
i,ACount:DWORD;
ANLen,ADLen,AILen:WORD;
AType:WMT_CODEC_INFO_TYPE;
AName,ADesc:WideString;
P:PByte;
begin
AReader.QueryInterface(IID_IWMheaderInfo2,hReader);
FWriter.QueryInterface(IID_IWMheaderInfo3,hWriter);
CheckWMV(hReader.GetCodecInfoCount(ACount));
for i:=0 to ACount - 1 do
begin
CheckWMV(hReader.GetCodecInfo(i,ANLen,nil,ADLen,nil,AType,AILen,nil));
SetLength(AName,ANLen);
SetLength(ADesc,ADLen);
P:=AllocMem(AILen);
try
CheckWMV(hReader.GetCodecInfo(i,ANLen,PWideChar(AName),
ADLen,PWideChar(ADesc),
AType,AILen,P));
CheckWMV(hWriter.AddCodecInfo(PWideChar(AName),PWideChar(ADesc),AType,AILen,P));
finally ReAllocMem(P,0) end;
end;
end;
destructor TWMVJoiner.Destroy;
begin
inherited;
end;
procedure TWMVJoiner.DoWriting;
var AAdvWriter:IWMWriterAdvanced;
ASample:INSSBuffer;
ATime,ADuration:Int64;
AFlags,ANum:DWORD;
AStream:WORD;
procedure WriteSamplesFrom(ANo:WORD;AReader:IWMSyncReader);
var i:Integer;
begin
while True do
begin
i:=AReader.GetNextSample(0,ASample,ATime,ADuration,AFlags,ANum,AStream);
if (i = NS_E_NO_MORE_SAMPLES) then break;
CheckWMV(AAdvWriter.WriteStreamSample(ANo,ATime,0,ADuration,AFlags,ASample));
end;
end;
begin
FWriter.QueryInterface(IID_IWMWriterAdvanced,AAdvWriter);
CheckWMV(FWriter.BeginWriting);
WriteSamplesFrom(1,FVReader);
WriteSamplesFrom(2,FAReader);
CheckWMV(FWriter.EndWriting);
end;
|
This produces an output .wmv and I get no unexpected errors while building it. However, the output file is surprisingly small and attempting to play it produces a black screen and static before crashing Windows Explorer altogether.
Clearly, there is more to it. I would much appreciate any advice.
|
|