Среда, 22.11.2017, 01:59
Приветствую Вас Гость

Не ошибается тот, кто ничего не делает.
Но и ничего не делать - ошибка.

Эмиль Кроткий

Меню сайта
Категории раздела
Работа с библиотеками BASS и DirectShow [14]
Статьи по написанию mp3 плеера, видеоплеера, работе с WEB камерой и т.д.
Форма входа

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0


















Тиц
Главная » Статьи » Мультимедиа » Работа с библиотеками BASS и DirectShow

Урок 5.2. Подключаем внешние субтитры при воспроизведении видео.

Подключаем внешние субтитры при воспроизведении видео.

        На прошлом уроке я показывал, как накладывать текст на видео в реальном режиме времени. В сегодняшнем уроке я продолжу тему работы  с текстом, используя фильтры DirectShow и покажу вам, как накладывать внешние субтитры на видео во время просмотра. Внешние - означает, что текст будет загружаться из специально созданного файла субтитров. Для работы с файлами субтитров нам понадобится DirectShow фильтр DirectVobSub но для работы с ним из Delphi придется скачать файл для поддержки его интерфейсов VSFilter.pas. Скачать его можно по адресу http://download.dsp-worx.de/?f=VSFilter.zip или вместе с исходниками к уроку. Фильтр DirectVobSub поддерживает большинство современных форматов файлов субтитров (.sub/.idx , .ssa/.ass .srt  .sub  .smi  .psb  .usf  .ssf). Готовые файлы субтитров к фильмам можно найти в интернете, там же можно найти кучу как платных так и бесплатных программ для создания файлов субтитров.  Кроме всего этого нужно установить  пакет DSPack или из него взять следующие файлы BaseClass.pas, DSUtils.pas, Jedi.inc сам пакет можно скачать здесь, файлы в нем находятся в папке src\DSPack\ их необходимо закинуть в папку с проектом.

        И так, приступим к созданию нашего проекта. Он будет очень простой и состоять из компонентов TPanel  и TButton, которые мы размещаем на форме, как показано на рисунке.


        По кнопке открыть мы будем загружать файл видео и файл субтитров и далее формировать граф для воспроизведения и выводить видео с субтитрами на панель.

Ниже привожу полный код проекта с подробными комментариями.

Не забывайте добавить в 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 или Graphstudio
CLSID_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);
//создаем обьект фильтра DirectVobSub
CoCreateInstance(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
//если расширение wmv
if 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;
 //получаем интерфейс ImediaControl
FGraphBuilder.QueryInterface(IID_IMediaControl, FMediaControl);
 //получаем интерфейс IVideoWindow
FGraphBuilder.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
//деинициализация интерфейсов и com
FMediaControl:= NIL;
FVideoWindow := NIL;
FAudioRender := nil;
FVideoRender:= nil;
FDirectVobSub:= nil;
FCaptureGraphBuilder   := NIL;
FGraphBuilder:= NIL;
CoUninitialize;
end;

//процедура создания формы
procedure TForm1.FormCreate(Sender: TObject);
begin
//инициализация com
CoInitialize(nil);
end;

end.

Сохраняем и тестируем проект. В исходниках лежит пример файла субтитров text.srt.

Скачать исходники можно здесь.

Автор статьи xaramamburu, сайт автора http://basicsprog.ucoz.ru .

Категория: Работа с библиотеками BASS и DirectShow | Добавил: xaramamburu (03.02.2012)
Просмотров: 5238 | Теги: DirectShow, DirectVobSub, субтитры | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск
Наш опрос
Оцените мой сайт
Всего ответов: 532
Уголок общения



Copyright MyCorp © 2017Конструктор сайтов - uCoz