









Kali ini kita akan membahas cara memisahkan data audio - video file MPEG. Artikel ini menyambung artikel sebelumnya, DirectShow Tips: Memisahkan Data Audio - Video dari File Movie (AVI). Jika anda belum membacanya, saya sarankan untuk membacanya dulu, karena kita akan menggunakan framework audio - video extractor yang sudah dibangun di artikel tersebut.
Anda membutuhkan software berikut ini:
Untuk memisahkan data audio dan video dari file MPEG, kita membutuhkan konstruksi filter graph seperti yang ditunjukkan gambar dibawah ini:

Gbr.1 Filter graph MPEG audio video extractor.
Kita masih akan menyimpan data audio sebagai file MP3 dan data video sebagai file AVI. Untuk memperkecil ukuran file AVI, kita kompress menggunakan Indeo 5.10 codec.
Kita akan membuat kelas baru bernama TMPEGAudioVideoExtractor yang akan kita turunkan dari TBasicAudioVideoExtractor. Metode BuildFilterGraph kita override dan kita isi dengan kode untuk mengkonstruksi filter graph seperti yang ditunjukkan gambar Gbr.1 di atas.
TMPEGAudioVideoExtractor=class(TBasicAudioVideoExtractor)
public
procedure BuildFilterGraph;override;
end;
Bagian implementasinya sebagai berikut:
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;
Aplikasi utama hampir sama dengan aplikasi yang kita buat sebelumnya di artikel DirectShow Tips: Memisahkan Data Audio - Video dari File Movie (AVI). Berikut ini adalah screenshot desain UI.

Gbr.2 User interface MPEG audio - video extractor.
Kita akan menambahkan item baru pada property Filter milik OpenDialog1. Di sini, kita tambahkan entry untuk MPEG file yakni MPEG files (*.mpg) | *.mpg.
Kita juga akan memodifikasi isi kode program utama. Kita menambahkan dua variabel baru dalam TfrmMain yakni AVIExtractor bertipe TAVIAudioVideoExtractor dan MPEGExtractor bertipe TMPEGAudioVideoExctractor. Variabel Extractor yang semula bertipe TAVIAudioVideoExtractor kita ubah menjadi TBasicAudioVideoExtractor.
Pada saat OpenDialog1 dieksekusi, kita cek apakah file yang sedang dibaca adalah file AVI atau MPEG (dengan mengecek properti FilterIndex OpenDialog1). Jika file adalah file AVI, Extractor kita set sebagai AVIExtractor, jika MPEG, kita set sebagai MPEGExtractor.
Berikut ini adalah implementasi lengkap aplikasi utama.
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 bisa di download di sini.
Di artikel ini, kita telah mendiskusikan bagaimana memisahkan data audio - video file MPEG kedalam file audio MP3 dan file video AVI menggunakan filter-filter yang disediakan oleh DirectShow. Telah ditunjukkan pula cara mengintegrasikan framework pemisah audio video kedalam kode aplikasi yang sudah ada.
Anda suka artikel ini? Bantu website ini berkembang dengan menyumbang. Berapapun jumlahnya akan sangat dihargai.
Atau Anda dapat membantu dengan membuat bookmark.
Bookmark this on Delicious