iOS下使用PJSIP库自定义视频通话视图求助(仿WhatsApp布局)
实现iOS PJSIP类似WhatsApp的视频通话布局
要实现远程视频全屏显示、本地视频以小窗口悬浮右侧的布局,仅通过硬编码尺寸调用pjsua_vid_win_set_size无法满足需求,需要区分本地/远程窗口、动态适配屏幕并调整层级,具体实现步骤如下:
1. 区分本地预览与远程视频窗口
- 远程视频窗口ID:在通话媒体状态激活的回调(如
on_call_media_state)中,通过pjsua_call_get_vid_win获取。 - 本地预览窗口ID:调用
pjsua_vid_preview_start启动本地摄像头预览时,会返回对应的窗口ID。
2. 设置远程视频窗口全屏显示
动态获取当前屏幕的安全区尺寸,将远程窗口铺满整个屏幕:
// 获取屏幕及安全区参数 let screenBounds = UIScreen.main.bounds let safeAreaInsets = UIApplication.shared.windows.first?.safeAreaInsets ?? .zero // 构造全屏尺寸 let fullSize = pjmedia_rect_size() fullSize.w = UInt32(screenBounds.width) fullSize.h = UInt32(screenBounds.height - safeAreaInsets.top - safeAreaInsets.bottom) // 设置远程窗口位置(从安全区顶部开始,左上角原点) let remoteWinPos = pjmedia_rect() remoteWinPos.x = 0 remoteWinPos.y = UInt32(safeAreaInsets.top) remoteWinPos.size = fullSize pjsua_vid_win_set_pos(remoteWid, &remoteWinPos)
3. 设置本地小窗口悬浮右侧
将本地窗口设为固定小尺寸,放置在屏幕右下角(避开安全区):
// 定义本地窗口尺寸(按16:9比例,宽度为屏幕1/3) let localWidth = UInt32(screenBounds.width / 3) let localHeight = UInt32(localWidth * 9 / 16) let localSize = pjmedia_rect_size(w: localWidth, h: localHeight) // 计算本地窗口位置:右下角预留边距,避开底部安全区 let localPos = pjmedia_rect() localPos.x = UInt32(screenBounds.width - localWidth - 16) // 右侧留16pt边距 localPos.y = UInt32(screenBounds.height - localHeight - safeAreaInsets.bottom - 16) // 底部留边距+安全区 localPos.size = localSize // 应用本地窗口的位置与尺寸 pjsua_vid_win_set_pos(localWid, &localPos)
4. 确保本地窗口在顶层
通过层级设置让本地小窗显示在远程视频之上:
// 数值越大层级越高,确保本地窗口层级高于远程 pjsua_vid_win_set_zorder(localWid, 1) pjsua_vid_win_set_zorder(remoteWid, 0)
关键注意事项
- 禁止硬编码尺寸:不同iOS设备屏幕尺寸、安全区差异大,必须动态获取屏幕参数。
- 监听屏幕旋转:若支持横屏,需在屏幕旋转回调中重新计算并更新两个窗口的位置与尺寸。
- 权限与初始化:确保已获取摄像头、麦克风权限,且PJSIP视频模块已正确启用初始化。
内容的提问来源于stack exchange,提问作者Shital Bhikhadiya
相关产品推荐
相关产品推荐

