我正在使用 OSSBuild 和 gstreamersharp 开发 C# WPF 应用程序。我正在使用 XOverlayAdapter 在我拥有 Windows 句柄的托管 WindowsForms 控件上显示视频。除了我将 playbin2 状态设置为 NULL 或 READY 的情况外,一切都运行良好。这正是我正在做的(如果元素已正确创建,我删除了所有检查):
创建一个游戏箱
Gst.BasePlugins.PlayBin2 playBin = new Gst.BasePlugins.PlayBin2(); playBin.PlayFlags &= ~((Gst.BasePlugins.PlayBin2.PlayFlagsType)(1 << 2)); playBin.Bus.AddSignalWatch(); playBin.Bus.EnableSyncMessageEmission(); playBin.Bus.Message += new Gst.MessageHandler(OnPlayBinMessage);
创建视频接收器
Gst.Video.VideoSink videoSink = Gst.ElementFactory.Make("dshowvideosink") as Gst.Video.VideoSink; videoSink["force-aspect-ratio"] = true;
将视频接收器与 WindowsForms 控件(屏幕)相关联,以在我的 WPF 窗口的矩形区域中显示视频。
Gst.Interfaces.XOverlayAdapter overlayAdapter = new Gst.Interfaces.XOverlayAdapter(videoSink.Handle); overlayAdapter.XwindowId = (ulong)screen.Handle;
将视频接收器附加到播放箱
playBin.VideoSink = videoSink;
将 playbin 的 URI 设置为我硬盘上的某个视频文件
playBin.SetState(Gst.State.Ready); playBin.Uri = @"file:///" + fileName.Replace('\\', '/'); playBin.SetState(Gst.State.Paused);
现在我可以通过改变 playbin 的状态来播放和暂停视频
playBin.SetState(Gst.State.Playing); playBin.SetState(Gst.State.Paused);
到目前为止一切顺利,我可以播放、暂停、搜索显示在我窗口矩形区域中的视频。当我尝试播放另一个视频文件时,问题就开始了。根据网上找到的所有手册,我应该在更改 URI 之前将管道状态设置为 NULL 或 READY:
打开另一个视频文件
playBin.SetState(Gst.State.Ready); playBin.Uri = @"file:///" + newFileName.Replace('\\', '/'); playBin.SetState(Gst.State.Playing);
不幸的是,这会导致我窗口中的矩形区域变成黑色,并导致 GStreamer 创建一个单独的窗口。它与更改 URI 无关,它是将 playbin 状态设置为 NULL 或 READY,这会断开视频输出与叠加层的连接。我做错了什么?
最佳答案
解决方案是防止视频接收器改变其状态。 感谢来自 gstreamer-devel 邮件列表的 Stefan Sauer。
playBin.VideoSink.SetLockedState(true);
playBin.SetState(Gst.State.Ready);
playBin.Uri = @"file:///" + newFileName.Replace('\\', '/');
playBin.SetState(Gst.State.Paused);
playBin.VideoSink.SetLockedState(false);
关于c# - 将 Playbin 状态设置为 NULL 或 READY 后 GStreamer XOverlay 丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8294177/