Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PJSUA2视频如何将视频表单嵌入C#WinForm_C#_Winforms_Video_Sdl_Pjsip - Fatal编程技术网

PJSUA2视频如何将视频表单嵌入C#WinForm

PJSUA2视频如何将视频表单嵌入C#WinForm,c#,winforms,video,sdl,pjsip,C#,Winforms,Video,Sdl,Pjsip,我想通过C#WinForm制作一个视频通话演示usa pjsua2,我可以使用pjproject中的pjsua示例进行视频通话。但是当我开发一个C#winform演示来预览捕获视频时。我在PJSUA2中找不到控制SDL窗口的API。我找到了一种使用“FindWindow”和“SetParent”win32 API设置Preview SDL窗口的父控件的方法。这不是个好办法,不是吗。在pjsua2中有更好的方法来控制sdl窗口吗 这是我的端点初始化代码ep是一个静态变量 e

我想通过C#WinForm制作一个视频通话演示usa pjsua2,我可以使用pjproject中的pjsua示例进行视频通话。但是当我开发一个C#winform演示来预览捕获视频时。我在PJSUA2中找不到控制SDL窗口的API。我找到了一种使用“FindWindow”和“SetParent”win32 API设置Preview SDL窗口的父控件的方法。这不是个好办法,不是吗。在pjsua2中有更好的方法来控制sdl窗口吗

这是我的端点初始化代码ep是一个静态变量

            ep = new Endpoint();
            ep.libCreate();

            EpConfig epConfig = new EpConfig();
            epConfig.logConfig.writer = new DebugLog();

            ep.libInit(epConfig);

            TransportConfig tcfg = new TransportConfig();
            tcfg.port = 5060;

            ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_UDP,tcfg);
            ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_TCP,tcfg);
            // Start library
            ep.libStart();
这是视频预览代码

 var epdev = ep.vidDevManager().enumDev2();
           
            VideoPreview video = new VideoPreview(epdev[0].id);
            VideoPreviewOpParam videoPreviewOpParam = new VideoPreviewOpParam();
            videoPreviewOpParam.rendId = epdev[1].id;//(int)pjmedia_vid_dev_std_index.PJMEDIA_VID_DEFAULT_RENDER_DEV;
            videoPreviewOpParam.window = new VideoWindowHandle();
            videoPreviewOpParam.window.handle = new WindowHandle();

            //videoPreviewOpParam.window.type = new SWIGTYPE_p_pjmedia_vid_dev_hwnd_type((long)1);
            videoPreviewOpParam.window.handle.setWindow(this.sdlPreview.Handle.ToInt64());
            Debug.WriteLine(this.sdlPreview.Handle);
            Debug.WriteLine(this.sdlPreview.Handle.ToInt64());
            videoPreviewOpParam.show = true;

            video.start(videoPreviewOpParam);
            var window = video.getVideoWindow();
            var videoList = ep.vidDevManager().enumDev2();
            var type = window.getInfo().winHandle.type;
            //var epdev = ep.vidDevManager().getOutputWindowFlags(-1);
            //window.Show(false);

            MediaCoordinate coordinate = new MediaCoordinate();
            coordinate.x = 0;// this.panelCamera.Top;
            coordinate.y = 0;// this.panelCamera.Left;
            window.setPos(coordinate);

            MediaSize size = new MediaSize();
            size.h = (uint)200;//this.panelCamera.Height;
            size.w = (uint)200;//this.panelCamera.Width;
            window.setSize(size);

            //var intPtr = EmbedControl.FindWindow(null, "pjmedia-SDL video");
            //EmbedControl.SetParent(intPtr, this.panelCamera.Handle);
            ////window.getInfo().isNative = false;
            //window.Show(true);

            window.Show(true);

这是win32 api代码

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

当设置
videoPreviewOpParam.show=false时设置后
窗口显示(true)视频表单仍然无法在windows中显示

过了一会儿,我发现我的代码挂起在pjsip源代码
sdl_dev.c
at
strm->window=sdl_CreateWindowFrom(hwnd->info.window)
,我将UserControl.Hanlde发送到
setWindow
,但是当通过DLLImport在这个C#WinForm中使用sdl2.dll时,它运行良好。我哪里出错了? github中有我的示例代码

今天2020-09-02我发现SDL源代码需要调试,当我使用C#DLLImport这个SDL“SDL#U CreateWindowFrom”时,它工作得很好,但是当我使用PJSIP被C#代码调用时,为了调试SDL源代码,我发现它挂在“titleLen=GetWindowTextLength(hwnd)”,它调用win32 API“GetWindowTextLength”来获取windows标题。通过C#DLLImport调用SDL的方法也可以,尽管C#中窗口的hanle与SDL的数据相同

if (_this->CreateSDLWindowFrom(_this, window, data) < 0) {
        SDL_DestroyWindow(window);
        return NULL;
    }
if(\u this->CreateSDLWindowFrom(\u this,window,data)<0){
SDL_窗口(窗口);
返回NULL;
}
但是pjsip通过C调用它只是挂起。我做错了什么

==========最终解决方案=========

我想我找到了原因,在SDL源中,SDL将调用“GetWindowTextLength”或其他win32 API,它将挂起。我发现了一个解释“GetWindowText”的博客

根据第一条规则,如果您试图在自己的进程中从窗口获取文本,并且窗口被挂起,那么GetWindowText()也将挂起。但既然这个窗口属于你的流程,那是你自己的错,你应该输。发送WM_GETTEXT消息可确保正确检索来自执行自定义文本管理(通常为自定义控件)的窗口的文本

我在C#UI线程中使用视频,因此当UI挂起时,获取windows信息的GetWindowText()或win32 api也将挂起。有一个博客