0

最近,我看到一个非常好的主意,放一个视频剪辑。这是关于“像滚石一样”,我们可以在这里看到:http: //video.bobdylan.com/desktop.html

如您所见,您可以与之交互,使用向上/向下键更改频道。

我下载了所有 16 个单独的子剪辑。

现在,挑战是制作一个程序,让单个玩家做同样的事情,并且做更多的事情。

我试图在另一个论坛上获得一些帮助,但现在我被困在了编程阶段。

请看这里:

已编辑:[链接已删除] 这是 Videohelp 论坛,与此问题标题相同的主题]

我写了一个小程序来加载视频并以马赛克的形式显示它们。这是迈向“换频道”功能的第一步。我在 Delphi 7 中使用 DSPack 组件,它使用 DirectShow 和 Direct9 库。

在这里,我到目前为止得到了什么:

包含 12 个视频的马赛克

如图所示,加载了 12 个视频。

我计划关闭所有其他视频的可见属性,当按时间观看一个视频时,在实现功能“更改频道”时,以缓解系统。但是在马赛克布局中,这是不可能的。

解决此步骤时,我将使用热键实现“更改频道”功能。

问题是我对 VideoWindow 和 FilterGraph 的 Visible 和 Active 属性感到困惑,因此我没有相应地使用它们。

到目前为止,这是代码:

procedure TFormPlayWin.FormActivate(Sender: TObject);
begin
  BigScreen := true;
  SmallScreen := false;
  VideoWindow01.Width := 1425;
  VideoWindow01.Height := 761;

  VideoWindow01.Visible := true;
  VideoWindow02.Visible := false;
  VideoWindow03.Visible := false;
  VideoWindow04.Visible := false;
  VideoWindow05.Visible := false;
  VideoWindow06.Visible := false;
  VideoWindow07.Visible := false;
  VideoWindow08.Visible := false;
  VideoWindow09.Visible := false;
  VideoWindow10.Visible := false;
  VideoWindow11.Visible := false;
  VideoWindow12.Visible := false;

    if not FilterGraph01.Active then FilterGraph01.Active := true;
    if not FilterGraph02.Active then FilterGraph02.Active := true;
    if not FilterGraph03.Active then FilterGraph03.Active := true;
    if not FilterGraph04.Active then FilterGraph04.Active := true;
{
    if not FilterGraph05.Active then FilterGraph05.Active := true;
    if not FilterGraph06.Active then FilterGraph06.Active := true;
    if not FilterGraph07.Active then FilterGraph07.Active := true;
    if not FilterGraph08.Active then FilterGraph08.Active := true;
    if not FilterGraph09.Active then FilterGraph09.Active := true;
    if not FilterGraph10.Active then FilterGraph10.Active := true;
    if not FilterGraph11.Active then FilterGraph11.Active := true;
    if not FilterGraph12.Active then FilterGraph12.Active := true;
}
    FilterGraph01.ClearGraph;
    FilterGraph02.ClearGraph;
    FilterGraph03.ClearGraph;
    FilterGraph04.ClearGraph;
{
    FilterGraph05.ClearGraph;
    FilterGraph06.ClearGraph;
    FilterGraph07.ClearGraph;
    FilterGraph08.ClearGraph;
    FilterGraph09.ClearGraph;
    FilterGraph10.ClearGraph;
    FilterGraph11.ClearGraph;
    FilterGraph12.ClearGraph;
}
    FilterGraph01.RenderFile('D:\Meus documentos\Downloads\Bob Dylan\Joined01.flv');
    FilterGraph02.RenderFile('D:\Meus documentos\Downloads\Bob Dylan\Joined02.flv');
    FilterGraph03.RenderFile('D:\Meus documentos\Downloads\Bob Dylan\Joined03.flv');
    FilterGraph04.RenderFile('D:\Meus documentos\Downloads\Bob Dylan\Joined04.flv');
{
    FilterGraph05.RenderFile('D:\Meus documentos\Downloads\Bob Dylan\Joined05.flv');
    FilterGraph06.RenderFile('D:\Meus documentos\Downloads\Bob Dylan\Joined06.flv');
    FilterGraph07.RenderFile('D:\Meus documentos\Downloads\Bob Dylan\Joined07.flv');
    FilterGraph08.RenderFile('D:\Meus documentos\Downloads\Bob Dylan\Joined08.flv');
    FilterGraph09.RenderFile('D:\Meus documentos\Downloads\Bob Dylan\Joined09.flv');
    FilterGraph10.RenderFile('D:\Meus documentos\Downloads\Bob Dylan\Joined10.flv');
    FilterGraph11.RenderFile('D:\Meus documentos\Downloads\Bob Dylan\Joined11.flv');
    FilterGraph12.RenderFile('D:\Meus documentos\Downloads\Bob Dylan\Joined12.flv');
}
    VideoWindow01.PopupMenu := PopupMenu;
    SoundLevel.Position := FilterGraph01.Volume;

    FilterGraph01.Play;
    FilterGraph02.Play;
    FilterGraph03.Play;
    FilterGraph04.Play;
{
    FilterGraph05.Play;
    FilterGraph06.Play;
    FilterGraph07.Play;
    FilterGraph08.Play;
    FilterGraph09.Play;
    FilterGraph10.Play;
    FilterGraph11.Play;
    FilterGraph12.Play;

      FilterGraph02.Active := false;
      FilterGraph03.Active := false;
      FilterGraph04.Active := false;
      FilterGraph05.Active := false;
      FilterGraph06.Active := false;
      FilterGraph07.Active := false;
      FilterGraph08.Active := false;
      FilterGraph09.Active := false;
      FilterGraph10.Active := false;
      FilterGraph11.Active := false;
      FilterGraph12.Active := false;

      VideoWindow02.Visible := false;
      VideoWindow03.Visible := false;
      VideoWindow04.Visible := false;
      VideoWindow05.Visible := false;
      VideoWindow06.Visible := false;
      VideoWindow07.Visible := false;
      VideoWindow08.Visible := false;
      VideoWindow09.Visible := false;
      VideoWindow10.Visible := false;
      VideoWindow11.Visible := false;
      VideoWindow12.Visible := false;
}
end;

上面,我正在尝试制作第一个覆盖整个区域的剪辑,并让其他视频不可见。但是事情变得很糟糕,因为我可以在大的 VideoWindow1 上看到 VideoWindow 2,3 和 4。

这个想法是使用热键来切换大小屏幕,并“改变频道”。

为了保持处理和同步,我只想运行一个音轨。如何将其与 DirectShow 过滤器分离?我需要它只播放一个音频。如果我只需要其中一个,则运行所有音轨是个坏主意。我必须让其他人静音。

说了这么多,我有两个问题:

1 - 如何使上面的代码更好地同时处理太多的视频。

2 - 如何使所有其他视频中的音轨静音,但第一个保持活跃。

4

2 回答 2

0

如果您希望所有视频同步播放 - 因此,当您在相同位置的视频之间切换时,请将所有视频加载到单个过滤器图中,并将它们连接到单个渲染器,例如支持多达 16 个流的 VMR9。通过设置流的 z 顺序和相关音频渲染器的音量在视频之间切换。

这里有一些代码可以帮助你。诀窍是使用 Capture Graph 将视频和音频渲染到特定的渲染器,这样您就可以使用单个视频和多个音频渲染器。

注意:我没有提供错误处理,您需要清理分配的资源。

  GraphBuilder: IGraphBuilder;
  CaptureGraph: ICaptureGraphBuilder2;
  VMR9: IBaseFilter;
  VMRFilterConfig9: IVMRFilterConfig9;
  VMRWindowlessControl9: IVMRWindowlessControl9;
  vw_position: TRect;
  VMRMixerControl9: IVMRMixerControl9;

  // create the fitler graph
  CoCreateInstance(CLSID_FilterGraph, nil, CLSCTX_INPROC_SERVER, IID_IFilterGraph2, GraphBuilder);
  // create the capture graph
  CoCreateInstance(CLSID_CaptureGraphBuilder2, nil, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, CaptureGraph);
  CaptureGraph.SetFiltergraph(IGraphBuilder(GraphBuilder));
  // create add the video renderer filter
  CoCreateInstance(CLSID_VideoMixingRenderer9, nil, CLSCTX_INPROC, IID_IBaseFilter, VMR9);
  GraphBuilder.AddFilter(VMR9, 'Renderer');
  // assign renderer to a TPanel
  VMR9.QueryInterface(IID_IVMRFilterConfig9, VMRFilterConfig9);
  VMRFilterConfig9.SetRenderingMode(VMR9Mode_Windowless);
  VMR9.QueryInterface(IID_IVMRWindowlessControl9, VMRWindowlessControl9);
  vw_position.Left := 0;
  vw_position.Top  := 0;
  vw_position.Right  := Panel.width;
  vw_position.Bottom := Panel.height;
  VMRWindowlessControl9.SetVideoPosition(nil, @vw_position);
  VMRWindowlessControl9.SetVideoClippingWindow(Panel.handle);
  // get mixer control
  VMR9.QueryInterface(IID_IVMRMixerControl9, VMRMixerControl9);
  // to control z-order, alpha etc.. see
  // http://msdn.microsoft.com/en-us/library/windows/desktop/dd390457%28v=vs.85%29.aspx


  // encapsluate the following into a class so you can reuse for each video
  SourceFilter: IBaseFilter;
  AudioRenderer: IBaseFilter;
  // create and file source and render video
  GraphBuilder.AddSourceFilter(stringtoolestr(Filename), stringtoolestr(ExtractFileName(Filename)), FileSource);
  CaptureGraph.RenderStream(nil, nil, FileSource, nil, VMR9 as IBaseFilter);
  // create audio renderer and render audio
  CoCreateInstance(StringToGUID('{79376820-07D0-11CF-A24D-0020AFD79767}'), nil, CLSCTX_INPROC, IID_IBaseFilter, AudioRenderer);
  GraphBuilder.AddFilter(AudioRenderer, 'DirectSound Audio Renderer');
  CaptureGraph.RenderStream(nil, nil, FileSource, nil, AudioRenderer);
于 2014-02-09T12:16:40.437 回答
0

使用 OOP 似乎是一项不错的任务。但是即使没有数组,您也可以轻松做到这一点。我会告诉您一个想法。

描述/功能

12个小屏幕同时显示(一个有声音)一个大屏幕当你想要的时候(可以再次更改为12个以选择新频道)

执行:

1)加载十二个视频并打开屏幕一的声音 2)更改活动小屏幕(改变焦点和活动声音) 3)打开大屏幕与选定的电影 4)返回到 12 个小屏幕

成分:

var ActiveMiniScreen : TScreen;

minScr01 ... minScr12(像您一样的 12 个屏幕) bigScr(带有 aling allClient 的额外屏幕,visible=false 或第二种形式) backTo12Button(bigScr.onDoubleClick 或第二种形式的按钮)

你需要4种方法..

onFormCreate()

加载所有视频并设置为活动状态(启动声音并使其与其他视频不同)

ActiveMiniScreen := miniScr1;
miniScr1.loadVideo()
miniScr1.soundOn
miniScr1.BorderColor:= red

miniScr2.loadVideo()
miniScr2.soundOff
miniScr2.BorderColor:= black
      ...
miniScr12.loadVideo()
miniScr12.soundOff
miniScr12.BorderColor:= black

onMinScreenClick() 所有的 miniSreens 共享同一个 onMiniScreen1Click 方法

ActiveMiniScreen := Tscreen(Sender)
Tscreen(Sender).SoundOn
Tscreen(Sender).BorderColor:= red

onMinDoubleScreenClick()

BigScreen.visible:=true
BigScreen.align:=alClient
BigScreen.loadVideo( ActiveMiniScreen.video )  //load miniScreen active 's video)
BigScreen.soundOn
ActiveMiniScreen.soundOff

onBigScreenDoubleClick()(DoubleClick 或 onClick)或 form2 中的按钮

BigScreen.visible:=false
BigScreen.soundOff
ActiveMiniScreen.soundOn
于 2013-12-10T00:34:40.983 回答