This time, we will talk about spliting audio - video data from MPEG file. This article continues previous article, DirectShow Tips: Splitting Audio - Video Data from Movie File (AVI). If you haven't read it yet, I suggest you to read it first because we will use audio - video extractor framework we have built in that article.
You need following softwares:
To split audio and video data from MPEG file, we need filter graph construction as shown in image below:

Fig.1 Filter graph of MPEG audio video extractor.
We will store audio data as MP3 file and video data as AVI file. To reduce size of AVI, we compress it with Indeo 5.10 codec.
We will create new class called TMPEGAudioVideoExtractor that will be derived from TBasicAudioVideoExtractor. BuildFilterGraph methode is overriden and flesh out with code to construct filter graph as shown in image Fig.1 above.
TMPEGAudioVideoExtractor=class(TBasicAudioVideoExtractor)
public
procedure BuildFilterGraph;override;
end;
Implementation part is as follow:
procedure TMPEGAudioVideoExtractor.BuildFilterGraph;
var pMP3FileSink,pAVIFileSink:IFileSinkFilter;
pFileSource:IFileSourceFilter;
afileReader,aMPEGSplitter,aWaveDest,
aMPEGLayer3,
aMP3FileWriter,
aAVIFileWriter,
aAVIMux,
aMPEGAudioDecompressor,
aMPEGVideoDecompressor,
aIndeoCompressor:IBaseFilter;
aSrcFilename,aDestFilename:widestring;
hr:HResult;
begin
if (FFilterGraph<>nil) then
begin
//add file reader filter
afileReader:=AddFilterByCLSID(CLSID_AsyncReader,'File Reader');
//add AVI splitter filter
aMPEGSplitter:=AddFilterByCLSID(CLSID_MPEG1Splitter,'MPEG-1 Splitter');
//Add MPEG Layer 3 Encoder
aMPEGLayer3:=FindFilterByFriendlyName(CLSID_AudioCompressorCategory,
'MPEG Layer-3');
FFilterGraph.AddFilter(aMPEGLayer3,'MPEG Layer-3');
//add Wave Dest filter
awaveDest:=AddFilterByCLSID(CLSID_WaveDest,'Wave Dest');
//add MP3 file writer filter
aMP3FileWriter:=AddFilterByCLSID(CLSID_FileWriter,'MP3 File Writer');
//add AVI file writer filter
aAVIFileWriter:=AddFilterByCLSID(CLSID_FileWriter,'AVI File Writer');
//add AVI Mux filter
aAVIMux:=AddFilterByCLSID(CLSID_AVIDest,'AVI Mux');
//add MPEG-1 Video Decompressor filter
aMPEGVideoDecompressor:=AddFilterByCLSID(CLSID_CMPEGVideoCodec,'MPEG-1 Video Decompressor');
//add MPEG-1 Audio Decompressor filter
aMPEGAudioDecompressor:=AddFilterByCLSID(CLSID_CMPEGAudioCodec,'MPEG-1 Audio Decompressor');
//Add Indeo video 5.10 Encoder
aIndeoCompressor:=FindFilterByFriendlyName(CLSID_VideoCompressorCategory,
'Indeo® video 5.10');
FFilterGraph.AddFilter(aIndeoCompressor,'Indeo video 5.10');
if (afileReader<>nil) and
(aMPEGSplitter<>nil) and
(aMPEGAudioDecompressor<>nil) and
(aMPEGVideoDecompressor<>nil) and
(aMPEGLayer3<>nil) and
(aWaveDest<>nil) and
(aMP3FileWriter<>nil) and
(aAVIFileWriter<>nil) and
(aAVIMux<>nil) and
(aIndeoCompressor<>nil) then
begin
//ambil instance IFileSourceFilter
afileReader.QueryInterface(IID_IFileSourceFilter,pFileSource);
if pFileSource<>nil then
begin
aSrcFilename:=FSrcFilename;
pFileSource.Load(PWideChar(aSrcFilename),nil);
end;
//connect output pin file reader ke
//input pin AVI splitter
hr:=ConnectFilter(aFileReader,aMPEGSplitter);
if hr<>S_OK then
RaiseDirectShowException(hr,'Koneksi File Reader ke MPEG-1 Splitter gagal. ');
//connect output MPEG splitter ke
//input pin MPEG Audio Decompressor
hr:=ConnectFilter(aMPEGSplitter,aMPEGAudioDecompressor,0,0);
if hr<>S_OK then
RaiseDirectShowException(hr,'Koneksi MPEG Splitter ke MPEG Audio Decompressor. ');
//connect output MPEG splitter ke
//input pin MPEG Video Decompressor
hr:=ConnectFilter(aMPEGSplitter,aMPEGVideoDecompressor,1,0);
if hr<>S_OK then
RaiseDirectShowException(hr,'Koneksi MPEG Splitter ke MPEG Video Decompressor. ');
{--------begin video extractor----------}
//connect output AVI Decompressor ke
//input pin AVI Compressor
hr:=ConnectFilter(aMPEGVideoDecompressor,aIndeoCompressor);
if hr<>S_OK then
RaiseDirectShowException(hr,'Koneksi MPEG Video Decompressor ke Indeo compressor gagal. ');
//connect output Indeo Compressor ke
//input pin AVI AVI Mux
hr:=ConnectFilter(aIndeoCompressor,aAVIMux);
if hr<>S_OK then
RaiseDirectShowException(hr,'Koneksi Indeo compressor ke AVI Mux gagal. ');
//ambil instance IFileSinkFilter
aAVIFileWriter.QueryInterface(IID_IFileSinkFilter,pAVIFileSink);
if pAVIFileSink<>nil then
begin
aDestFilename:=FVideoFilename;
pAVIFileSink.SetFileName(PWideChar(aDestFilename),nil);
end;
//connect output AVI Mux ke
//input pin AVI File Writer
hr:=ConnectFilter(aAVIMux,aAVIFileWriter);
if hr<>S_OK then
RaiseDirectShowException(hr,'Koneksi AVI Mux ke AVI FileWriter gagal. ');
{--------end video extractor----------}
{--------begin audio extractor----------}
//connect output MPEG Audio Decompressor ke
//input pin MPEG Layer 3
hr:=ConnectFilter(aMPEGAudioDecompressor,aMPEGLayer3);
if hr<>S_OK then
RaiseDirectShowException(hr,'Koneksi MPEG Audio Decompressor ke MPEG Layer 3. ');
//connect output MPEG Layer 3 ke
//input pin Wave Dest
hr:=ConnectFilter(aMPEGLayer3,aWaveDest);
if hr<>S_OK then
RaiseDirectShowException(hr,'Koneksi MPEG Layer 3 ke Wave Dest gagal. ');
//ambil instance IFileSinkFilter
aMP3fileWriter.QueryInterface(IID_IFileSinkFilter,pMP3FileSink);
if pMP3FileSink<>nil then
begin
aDestFilename:=FAudioFilename;
pMP3FileSink.SetFileName(PWideChar(aDestFilename),nil);
end;
//connect output wave Dest ke
//input pin FileWriter
hr:=ConnectFilter(aWaveDest,aMP3FileWriter);
if hr<>S_OK then
RaiseDirectShowException(hr,'Koneksi Wave Dest ke File Writer gagal. ');
{--------end audio extractor----------}
end;
end;
end;
Main application is very similar with our previous application in DirectShow Tips: Splitting Audio - Video data from Movie File (AVI). Following image is screenshot of UI design.

Fig.2 User interface of MPEG audio - video extractor.
We are going to add new item in Filter property of OpenDialog1. Here we add entry for MPEG file, i.e, MPEG files (*.mpg) | *.mpg.
We also modify code of main application. We add two new variables in TfrmMain, i.e, AVIExtractor of type of TAVIAudioVideoExtractor and MPEGExtractor of type of TMPEGAudioVideoExctractor. We change Extractor type from type of TAVIAudioVideoExtractor to TBasicAudioVideoExtractor.
When OpenDialog1 is executed, we check whether file currenly open is AVI or MPEG (by checking FilterIndex property of OpenDialog1). If file is AVI, We set Extractor as AVIExtractor, if MPEG, we set it as MPEGExtractor.
Next is full implementation of main application.
unit ufrmMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,DirectShow,uDirectShowPlayer, ComCtrls, ExtCtrls;
type
TfrmMain = class(TForm)
grpbxSource: TGroupBox;
lblFilename: TLabel;
edSourceFilename: TEdit;
grpbxDestination: TGroupBox;
edAudioFile: TEdit;
edVideoFile: TEdit;
lblAudioFile: TLabel;
lblVideoFile: TLabel;
btnBrowse: TButton;
btnBrowseAudio: TButton;
btnBrowseVideo: TButton;
btnExtract: TButton;
btnClose: TButton;
OpenDialog1: TOpenDialog;
SaveVideoDialog: TSaveDialog;
SaveAudioDialog: TSaveDialog;
ProgressBar1: TProgressBar;
progressTime: TTimer;
procedure btnExtractClick(Sender: TObject);
procedure btnBrowseClick(Sender: TObject);
procedure btnBrowseAudioClick(Sender: TObject);
procedure btnBrowseVideoClick(Sender: TObject);
procedure btnCloseClick(Sender: TObject);
procedure progressTimeTimer(Sender: TObject);
private
AVIExtractor:TAVIAudioVideoExtractor;
MPEGExtractor:TMPEGAudioVideoExtractor;
extractor:TBasicAudioVideoExtractor;
{ Private declarations }
procedure WM_MMNotify(var msg: TMessage);message WM_MMNOTIFY;
public
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
{ TForm1 }
constructor TfrmMain.Create(AOwner: TComponent);
begin
inherited;
AVIExtractor:=TAVIAudioVideoExtractor.Create;
AVIExtractor.Handle:=Handle;
MPEGExtractor:=TMPEGAudioVideoExtractor.Create;
MPEGExtractor.Handle:=Handle;
extractor:=AVIExtractor;
end;
destructor TfrmMain.Destroy;
begin
AVIExtractor.Free;
MPEGExtractor.Free;
inherited;
end;
procedure TfrmMain.WM_MMNotify(var msg: TMessage);
var aplayer:TBasicPlayer;
evCode,param1,param2:integer;
begin
aplayer:=TBasicPlayer(msg.LParam);
aplayer.EventObj.GetEvent(evCode,param1,param2,0);
case evCode of
EC_COMPLETE:begin
aplayer.RemoveAllFilters;
btnExtract.Enabled:=true;
progressbar1.Position:=0;
progressTime.Enabled:=false;
end;
end;
aplayer.EventObj.FreeEventParams(evCode,param1,param2);
end;
procedure TfrmMain.btnExtractClick(Sender: TObject);
begin
btnExtract.Enabled:=false;
Extractor.SrcFilename:=edSourceFilename.Text;
Extractor.AudioFilename:=edAudioFile.Text;
Extractor.VideoFilename:=edVideoFile.Text;
extractor.Extract;
progressbar1.Max:=extractor.Duration;
progressbar1.Min:=0;
progressbar1.Position:=0;
progressTime.Enabled:=true;
end;
procedure TfrmMain.btnBrowseClick(Sender: TObject);
begin
if OpenDialog1.Execute then
begin
edSourceFilename.Text:=OpenDialog1.FileName;
case OpenDialog1.FilterIndex of
1:Extractor:=AVIExtractor;
2:Extractor:=MPEGExtractor;
end;
end;
end;
procedure TfrmMain.btnBrowseAudioClick(Sender: TObject);
begin
if SaveAudioDialog.Execute then
edAudioFile.Text:=SaveAudioDialog.FileName;
end;
procedure TfrmMain.btnBrowseVideoClick(Sender: TObject);
begin
if SaveVideoDialog.Execute then
edVideoFile.Text:=SaveVideoDialog.FileName;
end;
procedure TfrmMain.btnCloseClick(Sender: TObject);
begin
Close;
end;
procedure TfrmMain.progressTimeTimer(Sender: TObject);
begin
progressbar1.Position:=extractor.Position.Current;
end;
end.
Source code is available to download here.
In this article, we have discussed how to split audio - video data from MPEG file into MP3 file and AVI file using filters provided by DirectShow. We have shown how to integrate framework audio video splitter into existing application code.
Do you like this article? Help this website improve by donating. Any amounts is appreciated.
Or you can help by bookmarking this page.
Bookmark this on Delicious