По кнопке открыть мы будем загружать файл видео и файл субтитров и далее формировать граф для воспроизведения и выводить видео с субтитрами на панель.
Ниже привожу полный код проекта с подробными комментариями.Не забывайте добавить в
Uses модули
directshow9, ActiveX, VSFilter.
Скачать заголовочные файлы DirectShow можно здесь.unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, directshow9, ActiveX, VSFilter;
type
TForm1 = class(TForm)
Button1: TButton;
OpenDialog1: TOpenDialog;
Panel1: TPanel;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
const
//значение CLSID для фильтров можно посмотреть с помощью программы Graphedit или GraphstudioCLSID_DirectVobSub : TGUID = '{93A22E7A-5091-45EF-BA61-6DA26156A5D0}';
var
Form1: TForm1;
FGraphBuilder: IGraphBuilder = Nil;
FCaptureGraphBuilder: ICaptureGraphBuilder2 = nil;
FMediaControl: IMediaControl = Nil;
FVideoWindow: IVideoWindow = Nil;
FDirectVobSub : IBaseFilter = nil;
FAudioRender : IBaseFilter = nil;
FVideoRender : IBaseFilter = nil;
fl_SrcFile : IBaseFilter = nil;
//интерфейс фильтра DirectVobSub DirectVobSub: IDirectVobSub = nil;
//имя файла для воспроизведения FileNameVideo:String;
//имя фйла субтитров FileNameText:String;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
//освобождаем подключенные интерфейсы if Assigned(FMediaControl) then FMediaControl:= NIL;
if Assigned(FVideoWindow) then FVideoWindow := NIL;
if Assigned(FAudioRender) then FAudioRender := nil;
if Assigned(FVideoRender) then FVideoRender:= nil;
if Assigned(FDirectVobSub) then FDirectVobSub:= nil;
if Assigned(FCaptureGraphBuilder) then FCaptureGraphBuilder := NIL;
if Assigned(FGraphBuilder) then FGraphBuilder:= NIL;
//создаем обЪект для графа фильтровCoCreateInstance(CLSID_FilterGraph, nil, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, FGraphBuilder);
//создаем вспомагательный объект графа захватаCoCreateInstance(CLSID_CaptureGraphBuilder2, NIL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, FCaptureGraphBuilder);
//указываем ему граф фильтровFCaptureGraphBuilder.SetFiltergraph(FGraphBuilder);
//вызываем диалог открытия файла видеоOpenDialog1.Title:='Выберите видео файл';
if OpenDialog1.Execute then FileNameVideo:=OpenDialog1.FileName;
//создаем и добавляем в граф фильтр источник и загружаем в него наш видео файлFGraphBuilder.AddSourceFilter(StringToOleStr(FileNameVideo),'',fl_SrcFile);
//создаем обьект фильтра DirectVobSubCoCreateInstance(CLSID_DirectVobSub, nil, CLSCTX_INPROC, IID_IBaseFilter, FDirectVobSub);
//добавляем его в графFGraphBuilder.AddFilter(FDirectVobSub, 'DirectVobSub');
//вызываем диалог открытия файла субтитровOpenDialog1.Title:='Выберите файл субтитров';
if OpenDialog1.Execute then FileNameText:=OpenDialog1.FileName;
//подключаем файл к субтитров к фильтру(FDirectVobSub as IDirectVobSub).put_FileName(StringToOleStr(FileNameText));
//создаем и добавляем объект фильтра вывода звукаCoCreateInstance(CLSID_AudioRender, nil, CLSCTX_INPROC, IID_IBaseFilter, FAudioRender);
FGraphBuilder.AddFilter(FAudioRender, 'DirectSound Audio Renderer');
//создаем и добавляем объект фильтра вывода видеоCoCreateInstance(CLSID_VideoMixingRenderer, nil, CLSCTX_INPROC, IID_IBaseFilter, FVideoRender);
FGraphBuilder.AddFilter(FVideoRender, 'Video Renderer');
//строим граф в зависимости от расширения файлаwith FCaptureGraphBuilder do
begin
//если расширение wmvif lowercase(ExtractFileExt(FileNameVideo))='.wmv' then begin
//строим участок графа от фильтра источника fl_SrcFile до фильтра FDirectVobSub if FAILED(RenderStream(nil, @MEDIATYPE_Video, fl_SrcFile, nil , FDirectVobSub)) then
Begin
ShowMessage('Внимание! Произошла ошибка на участке от фильтра источника fl_SrcFile до фильтра FDirectVobSub');
Exit;
End;
//если другое расширениеend else begin
//строим участок графа от фильтра источника fl_SrcFile до фильтра FDirectVobSub if FAILED(RenderStream(nil, @MEDIATYPE_Stream, fl_SrcFile, nil ,FDirectVobSub)) then
Begin
ShowMessage('Внимание! Произошла ошибка на участке от фильтра источника fl_SrcFile до фильтра FDirectVobSub');
Exit;
End;
end;
//строим ветвь графа для звука if FAILED(RenderStream(nil, nil, fl_SrcFile, nil, FAudioRender)) then
Begin
ShowMessage('Внимание! Произошла ошибка на участке вывода звука');
Exit;
End;
//строим оставшуюся ветвь для вывода видео от фильтра FDirectVobSub до фильтра FVideoRender if FAILED(RenderStream(nil, @MEDIATYPE_Video, FDirectVobSub, nil, FVideoRender)) then
Begin
ShowMessage('Внимание! Произошла ошибка на участке от фильтра FDirectVobSub до фильтра FVideoRender');
Exit;
End;
end;
//получаем интерфейс ImediaControlFGraphBuilder.QueryInterface(IID_IMediaControl, FMediaControl);
//получаем интерфейс IVideoWindowFGraphBuilder.QueryInterface(IID_IVideoWindow, FVideoWindow);
//распологаем окно вывода на Panel1 FVideoWindow.put_Owner(Panel1.Handle);
FVideoWindow.put_WindowStyle(WS_CHILD or WS_CLIPSIBLINGS);
FVideoWindow.put_MessageDrain(Panel1.Handle);
FVideoWindow.SetWindowPosition(0, 0, Panel1.ClientRect.Right,Panel1.ClientRect.Bottom);
//запускаем на воспроизведение FMediaControl.Run;
end;
//процедура закрытия формыprocedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//деинициализация интерфейсов и comFMediaControl:= NIL;
FVideoWindow := NIL;
FAudioRender := nil;
FVideoRender:= nil;
FDirectVobSub:= nil;
FCaptureGraphBuilder := NIL;
FGraphBuilder:= NIL;
CoUninitialize;
end;
//процедура создания формыprocedure TForm1.FormCreate(Sender: TObject);
begin
//инициализация comCoInitialize(nil);
end;
end.
Сохраняем и тестируем проект. В исходниках лежит пример файла субтитров
text.srt.
Скачать исходники можно
здесь.
Автор статьи
xaramamburu, сайт автора
http://basicsprog.ucoz.ru .