最近,我看到了一个非常好的主意,就是放一个视频片段。这是关于“像滚石”,我们可以在这里看到: http://video.bobdylan.com/desktop.html
如您所见,您可以与之互动,使用向上/向下键更改频道。
我下载了所有16个单独的子剪辑。
现在,挑战在于制作一个程序,一个单独的玩家也可以做同样的事情。
我试图在另一个论坛上得到一些帮助,但现在我陷入了编程阶段。
请看看这里:
编辑: [已删除链接] 它是Videohelp论坛,与此问题具有相同标题的主题]
我写了一个小程序来加载视频并用马赛克显示它们。这是“改变频道”功能的第一步。 我正在使用DSPack组件,它使用DirectShow和Direct9库,使用Delphi 7。
这里,到目前为止我得到了什么:
如图所示,已加载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;
上面,我试图让第一个Clip覆盖整个区域并保持其他视频不可见。但是事情变坏了,因为我可以看到VideoWindow 2,3和4,而不是大视频VideoWindow1。
我们的想法是使用热键切换大屏幕和小屏幕,以及“更改频道”。
为了保留处理和同步,我想只运行一个音频轨道。如何从DirectShow过滤器中分离出来?我需要它只播放一个音频。如果我只需要其中一个音轨,那么运行所有音轨的好主意。我必须将其他人静音。
说,我有两个问题:
1 - 如何使上述代码更好地同时处理太多视频。
2 - 如何将音频轨道与其他所有视频静音,但第一个视频会保持活跃状态。
答案 0 :(得分:0)
使用OOP似乎是一项很好的任务。但即使没有阵列,你也可以轻松实现。我会告诉你一个想法..
<强>说明/功能强>
同时12个迷你屏幕(一个有声音) 你想要一个大屏幕(有可能再次为选择新频道改为12)
<强>实现:强>
1)加载12个视频并打开屏幕1的声音 2)更改活动的miniScreen(更改焦点和活动声音) 3)openBigScreen与选定的电影 4)返回12miniScreens
<强>组件:强>
无功 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
答案 1 :(得分: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);