如何在Delphi中连续播放视频文件?

7

我正在使用Delphi 5。

我想知道如何使用'TFilterGraph'判断avi文件是否播放完成。我想要自动地一个接着一个地运行多个avi文件。因此,我下载了DSPack并使用了'TFilterGraph'和'TVideoWindow'组件,avi文件的视频正常显示。

我该如何知道avi视频或任何视频是否播放完毕,以便我可以选择下一个avi文件或任何其他视频文件进行播放?

procedure TForm1.Button2Click(Sender: TObject);
begin
  videowindow1.FilterGraph:=filtergraph1; //query interfaces to video window
  filtergraph1.Active:=true;
  filtergraph1.RenderFile('I:\Project Part 1\Clips\More Clips\D.avi');
  filtergraph1.Play;
end;

1
TFilterGraph类有OnGraphComplete事件来实现此功能。 - TLama
在这种情况下,“procedure FilterGraph1GraphComplete(sender:TObject; Result: HRESULT; Renderer: IBaseFilter);”我收到“未声明标识符'IBaseFilter'”的错误。我不知道如何克服这个错误。 - Vishal Tiwari
1
DirectShow9 添加到你的 uses 子句中。 - TLama
是的,那帮了我很多。非常感谢TLama,你真是太棒了。现在我将提供完整的代码,以便连续一次运行视频列表中的所有视频。给我一些时间... - Vishal Tiwari
1
当然,TLama,我会为你做这件事...再次感谢你无限的帮助。 - Vishal Tiwari
显示剩余9条评论
1个回答

1
我已经用另一种方式克服了视频完成时间。
在这里,我提供了.pas文件和.dfm文件的代码。
当然,DSPack应该已经安装好了。我已经从您上面提供的链接下载了。非常感谢。
一切都正常工作,只需要在“ListFileDir”过程中更改文件类型和文件路径。其他工作都很好。
只需将.PAS文件保存为“NewPlayerSource”名称,否则在编译项目时会出现错误。
.PAS文件代码:
unit NewPlayerSource;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, MPlayer, StdCtrls, Buttons, FileCtrl, ComCtrls, DSPack,
  DirectShow9;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    MediaPlayer1: TMediaPlayer;
    Panel1: TPanel;
    FileListBox1: TFileListBox;
    ListBox1: TListBox;
    Button1: TButton;
    Animate1: TAnimate;
    VideoWindow1: TVideoWindow;
    FilterGraph1: TFilterGraph;
    Label1: TLabel;
    Label2: TLabel;
    ProgressBar1: TProgressBar;
    Label3: TLabel;
    btnPlaySelectedFile: TButton;
    btnPause: TButton;
    btnResume: TButton;
    procedure FormShow(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);                            
    procedure Button1Click(Sender: TObject);
    procedure ListFileDir(Path: string; var FileList: TListBox);
    procedure FilterGraph1GraphComplete(sender: TObject; Result: HRESULT;
      Renderer: IBaseFilter);
    procedure btnPlaySelectedFileClick(Sender: TObject);
    procedure btnPauseClick(Sender: TObject);
    procedure btnResumeClick(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }

    bVideoCompleted, bPlaySelectedVideo, bPuseButtonPressed : Boolean;

    procedure PlayVideo;
    procedure SetupProgressBar;
    function SecToTime(Sec: Integer): string;
  end;

var
  Form1: TForm1;
  iCount, iSeconds: Integer;

implementation

{$R *.dfm}
procedure TForm1.ListFileDir(Path: string; var FileList: TListBox);
var
  SR: TSearchRec;
begin
  if FindFirst(Path + '*.avi', faAnyFile, SR) = 0 then
  begin
    repeat
      if (SR.Attr <> faDirectory) then
      begin
        FileList.Items.Add(Path + SR.Name);
      end;
    until FindNext(SR) <> 0;

    FindClose(SR);
  end;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  bVideoCompleted := False;
  bPlaySelectedVideo := False;
  bPuseButtonPressed := False;

  ListBox1.Items.Clear;
  Label1.Caption := EmptyStr;
  Label2.Caption := EmptyStr;

  ListFileDir('I:\Project Part 1\Clips\More Clips\', ListBox1);

  btnResume.Enabled := False;

  if ListBox1.Items.Count = 0 then
  begin
    btnPlaySelectedFile.Enabled := False;
    btnPause.Enabled := False;
    ShowMessage('No files to play');
    Exit;
  end;

  iCount := 0;
  ListBox1.ItemIndex := iCount;

  PlayVideo;

  {with MediaPlayer1 do
    begin
      Close;
       //DeviceType := dtAVIVideo;
        DeviceType := dtAutoSelect;
        FileName := ListBox1.Items.Strings[iCount];
        ListBox1.ItemIndex := iCount;
        iCount := iCount + 1;
        Open;
        //DisplayRect := Rect(0, 0, Panel1.Width, Panel1.Height);
        Play;
    end;
  }
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if ListBox1.Items.Count = 0 then
    Exit;

  if bPuseButtonPressed = True then
    Exit;

  if bVideoCompleted = True then
  begin
    bVideoCompleted := False;

    if iCount >= ListBox1.Items.Count then
      iCount := 0;

    PlayVideo;
  end;

  Label2.Caption := FormatDateTime('hh:nn:ss', iSeconds / SecsPerDay);
  ProgressBar1.Position := ProgressBar1.Position + 1;

  iSeconds := iSeconds + 1;

  {if MediaPlayer1.Position = MediaPlayer1.Length then
  begin
    if iCount = ListBox1.Items.Count then
      iCount := 0;

    with MediaPlayer1 do
    begin
      Close;
      FileName := ListBox1.Items.Strings[iCount];
      ListBox1.ItemIndex := iCount;
      iCount := iCount + 1;
      Open;
      Play;
    end;
  end;
  }
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Close;
end;

procedure TForm1.FilterGraph1GraphComplete(sender: TObject;
  Result: HRESULT; Renderer: IBaseFilter);
begin
  bVideoCompleted := True;
end;

procedure TForm1.PlayVideo;
begin
  iSeconds := 0;

  SetupProgressBar;

  filtergraph1.Stop;
  filtergraph1.ClearGraph;
  videowindow1.FilterGraph:=filtergraph1;
  filtergraph1.Active:=true;

  if bPlaySelectedVideo = True then
    filtergraph1.RenderFile(ListBox1.Items.Strings[ListBox1.ItemIndex])
  else
    filtergraph1.RenderFile(ListBox1.Items.Strings[iCount]);
  filtergraph1.Play;

  bPlaySelectedVideo := False;

  Label1.Caption :=  FormatDateTime('hh:nn:ss', (filtergraph1.Duration/1000) / SecsPerDay);
  Label2.Caption := FormatDateTime('hh:nn:ss', iSeconds / SecsPerDay);

  ListBox1.ItemIndex := iCount;
  iCount := iCount + 1;

  SetupProgressBar;
end;

procedure TForm1.SetupProgressBar;
begin
  ProgressBar1.Position := 0;
  ProgressBar1.Step := 1;
  ProgressBar1.Min := 0;
  ProgressBar1.Max := StrToInt(FloatToStr(filtergraph1.Duration div 1000)) + 1;
end;

function TForm1.SecToTime(Sec: Integer): string;
var
   H, M, S: string;
   ZH, ZM, ZS: Integer;
begin
   Sec := Sec div 1000;
   ZH := Sec div 3600;
   ZM := Sec div 60 - ZH * 60;
   ZS := Sec - (ZH * 3600 + ZM * 60) ;
   H := IntToStr(ZH) ;
   M := IntToStr(ZM) ;
   S := IntToStr(ZS) ;
   Result := H + ':' + M + ':' + S;
end;

procedure TForm1.btnPlaySelectedFileClick(Sender: TObject);
begin
  bPlaySelectedVideo := True;
  bPuseButtonPressed := False;

  btnPause.Enabled := True;
  btnResume.Enabled := False;

  iCount := ListBox1.ItemIndex;

  PlayVideo;
end;

procedure TForm1.btnPauseClick(Sender: TObject);
begin
  filtergraph1.Pause;

  bPuseButtonPressed := True;

  btnPause.Enabled := False;
  btnResume.Enabled := True;
end;

procedure TForm1.btnResumeClick(Sender: TObject);
begin
  filtergraph1.Play;

  bPuseButtonPressed := False;

  btnResume.Enabled := False;
  btnPause.Enabled := True;
end;

end.

.DFM文件代码:

object Form1: TForm1
  Left = 305
  Top = 149
  BorderStyle = bsSingle
  Caption = 'overflow'
  ClientHeight = 589
  ClientWidth = 941
  Color = clBtnFace
  Font.Charset = ANSI_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  Position = poDesktopCenter
  OnShow = FormShow
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 897
    Top = 568
    Width = 32
    Height = 13
    Alignment = taRightJustify
    Caption = 'Label1'
    Font.Charset = ANSI_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentFont = False
  end
  object Label2: TLabel
    Left = 256
    Top = 568
    Width = 32
    Height = 13
    Caption = 'Label2'
    Font.Charset = ANSI_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentFont = False
  end
  object Label3: TLabel
    Left = 10
    Top = 16
    Width = 73
    Height = 13
    Caption = 'List of files path'
    Font.Charset = ANSI_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    ParentFont = False
  end
  object MediaPlayer1: TMediaPlayer
    Left = 300
    Top = 132
    Width = 113
    Height = 23
    EnabledButtons = [btPlay, btPause, btStop, btNext]
    VisibleButtons = [btPlay, btPause, btStop, btNext]
    AutoOpen = True
    DeviceType = dtAVIVideo
    Display = Panel1
    TabOrder = 0
  end
  object Panel1: TPanel
    Left = 504
    Top = 18
    Width = 139
    Height = 109
    Caption = 'Panel1'
    TabOrder = 1
  end
  object FileListBox1: TFileListBox
    Left = 504
    Top = 198
    Width = 139
    Height = 73
    ItemHeight = 13
    TabOrder = 2
  end
  object ListBox1: TListBox
    Left = 10
    Top = 32
    Width = 231
    Height = 163
    ItemHeight = 13
    TabOrder = 3
  end
  object Button1: TButton
    Left = 312
    Top = 276
    Width = 56
    Height = 19
    Caption = 'CLOSE'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -13
    Font.Name = 'Tahoma'
    Font.Style = [fsBold]
    ParentFont = False
    TabOrder = 4
    OnClick = Button1Click
  end
  object Animate1: TAnimate
    Left = 664
    Top = 48
    Width = 209
    Height = 185
    Active = False
  end
  object VideoWindow1: TVideoWindow
    Left = 256
    Top = 16
    Width = 673
    Height = 521
    FilterGraph = FilterGraph1
    VMROptions.Mode = vmrWindowed
    Color = clBlack
  end
  object ProgressBar1: TProgressBar
    Left = 256
    Top = 544
    Width = 673
    Height = 17
    Min = 0
    Max = 100
    Smooth = True
    Step = 1
    TabOrder = 7
  end
  object btnPlaySelectedFile: TButton
    Left = 8
    Top = 208
    Width = 234
    Height = 25
    Caption = '&Play selected file'
    TabOrder = 8
    OnClick = btnPlaySelectedFileClick
  end
  object btnPause: TButton
    Left = 8
    Top = 240
    Width = 117
    Height = 25
    Caption = 'Pa&use'
    TabOrder = 9
    OnClick = btnPauseClick
  end
  object btnResume: TButton
    Left = 128
    Top = 240
    Width = 117
    Height = 25
    Caption = '&Resume'
    TabOrder = 10
    OnClick = btnResumeClick
  end
  object Timer1: TTimer
    OnTimer = Timer1Timer
    Left = 56
    Top = 352
  end
  object FilterGraph1: TFilterGraph
    GraphEdit = False
    LinearVolume = True
    OnGraphComplete = FilterGraph1GraphComplete
    Left = 128
    Top = 352
  end
end

再次感谢您,TLama,为所有的帮助。

如果有遗漏或需要改进的地方,请告诉我。


嗨,TLama,我把上面的代码和过程给了另一个使用Windows Vista操作系统的人,他说代码正在编译。当他运行项目时,所有文件路径都显示在列表框中,但没有文件显示视频,也没有声音... 有什么猜测吗?需要安装任何编解码器吗? - Vishal Tiwari
嗨,TLama,问题已经解决了,我让他将'TVideoWindow'组件的'Mode'属性设置为'vmVMR',现在应用程序显示视频效果更好了。 - Vishal Tiwari
还有一个观察结果,我安装了“klmcodec140”编解码器,并将“TVideoWindow”组件的“Mode”属性保持为“vmNormal”,然后它可以播放视频、mp3和所有其他文件,但当我将“Mode”属性设置为“vmVMR”时,只有声音没有视频显示,下一个视频会出现错误。因此,当我们没有安装任何编解码器或支持软件时,我们需要将“Mode”属性设置为“vmVMR”,否则我们必须将“TVideoWindow”组件的“Mode”属性设置为“vmNormal”。这就是我的观察结果。 - Vishal Tiwari
我有Windows8.1 64位操作系统。我已经安装了Delphi 5,并通过Delphi 5安装了DS Pack的最新版本。当我尝试运行任何.MP4文件时,会出现错误,如“无法执行操作,因为未连接引脚。 ($80040209)”。我已经通过此链接“http://sh.st/bf0u3”安装了DirectX11.2,但仍然出现相同的错误。顺便说一句,在安装DirectX之后,版本显示为“DirectX 11”,而不是“DirectX 11.2”。有什么建议吗? - Vishal Tiwari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接