Forum archive - Adding Sound to WMV




Forum Archive Home -> Programming -> Adding Sound to WMV



Adding Sound to WMV

FredAt posted 2009 Apr 14 23:39
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

:

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.




Login/Register to our forum to be able to post here.








DVDFab DVD to DVD lets you backup DVDs to DVDr, AVI or MP4 for portable devices. More info or download trial!
About   Advertise   Forum Archive   RSS Feeds   Statistics