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

问题描述

我想通过C#WinForm进行视频通话演示美国pjsua2,我可以在pjproject中使用pjsua示例进行视频通话。但是当我开发一个C#winform演示来预览捕获视频时。我在PJSUA2中找不到用于控制SDL窗口的API。我找到了一种使用“ FindWindow”和“ SetParent” win32 API设置preveiw 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;之后设置window.Show(true);时,视频表单仍无法在窗口中显示。

过了一会儿,我发现我的代码在sdl_dev.c的pjsip源代码 strm->window = SDL_CreateWindowFrom(hwnd->info.window);处挂起,我向setWindow发送了一个UserControl.Hanlde,但是使用sdl2.dll时在DLLImport的C#WinForm中,它运行良好。我哪里做错了? github github sample code

中有我的示例代码

今天2020-09-02我找到了要调试的SDL源代码,当我使用C#DLL导入SDL“ SDL_CreateWindowFrom”时,它可以正常工作,但是当我使用CJS代码调用PJSIP来调试SDL源代码时,我发现它挂在“ titleLen = GetWindowTextLength(hwnd);”上它将调用win32 API“ GetWindowTextLengthW”以获取Windows标题。通过C#DLLImport调用SDL的相同方法也可以正常工作。尽管C#中的窗口句柄与SDL的数据相同

if (_this->CreateSDLWindowFrom(_this,window,data) < 0) {
        SDL_DestroyWindow(window);
        return NULL;
    }

,但是通过C#由pjsip调用,它只是挂了。我在做什么错了?

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

我认为我找到了原因,在SDL中,SDL会调用“ GetWindowTextLength”或其他win32 API,它将挂起。我发现一个博客,上面写着“ GetWindowText”,

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

我在C#UI线程中使用视频,因此当UI挂起时,GetWindowText()或其他获取Windows信息的win32 api也将挂起。有博客The secret life of GetWindowText

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...