用户使用移动设备进行直播或视频通话时,通常有以下几种旋转方式:
- 固定竖屏
- 固定横屏
- 横竖屏自动切换
以下示例中“拉流端”渲染画面的模式以默认的 “ASPECT_FIT”(等比缩放,可能有黑边)方式,具体请参考 ZegoViewMode。 固定竖屏:表示推流端固定采集以竖屏方式展示的视频,此时当对端设备方向为竖屏时,观看到的画面为充满设备屏幕的竖屏效果。当对端设备方向为横屏时,观看到的画面为相对推流端图像有一定旋转角度的效果(下图以逆时针旋转 90 度为例)。
- 如果设备的旋转方向锁定:
- 如果设备的旋转方向不锁定:
固定横屏:表示推流端固定采集以横屏方式展示的视频,此时当对端设备方向为横屏时,观看到的画面为充满设备屏幕的横屏效果。当对端设备方向为竖屏时,观看到的画面为相对推流端图像有一定旋转角度的效果(下图以逆时针旋转 90 度为例)。
- 如果设备的旋转方向锁定:
- 如果设备的旋转方向不锁定:
横竖屏自动切换:提供视频旋转功能,用户可以根据需要将视频相比于手机正立的方向逆时针旋转 90,180 或 270 度。便于用户结合视频场景需要,获取想要的视频渲染效果。视频旋转后会自动进行调整,以适配编码后的图像分辨率。
以上三种方式调用的接口存在差异,详细描述请参考本文的 使用步骤。
实例源码下载
请参考 下载示例源码 获取源码。
相关源码请查看 “/ZegoExpressExample/CommonFeatures/src/main/java/im/zego/videorotation” 目录下的文件。
前提条件
在实现视频采集旋转之前,请确保:
- 已在项目中集成 ZEGO Express SDK,实现基本的实时音视频功能,详情请参考 快速开始 – 集成 和 快速开始 – 实现视频通话。
- 已在 ZEGO 控制台 创建项目,并申请有效的 AppID,详情请参考 控制台 – 项目管理 中的“项目信息”。
使用步骤
4.1 固定竖屏
使用竖屏直播或视频通话时,宽的分辨率应比高的分辨率小,假设为 “360 × 640”,则需要通过如下步骤实现功能。
步骤一:调用 createEngine 接口创建 SDK 引擎实例,详情请参考 快速开始 – 实现流程 的 “3.1 创建引擎”。
// 创建引擎,通用场景接入,并注册 self 为 eventHandler 回调
// 不需要注册回调的话,eventHandler 参数可以传 null,后续可调用 "setEventHandler:" 方法设置回调
ZegoEngineProfile profile = new ZegoEngineProfile();
profile.appID = ; // 请通过官网注册获取,格式为:1234567890L
profile.scenario = ZegoScenario.GENERAL; // 通用场景接入
profile.application = getApplication();
engine = ZegoExpressEngine.createEngine(profile, null);
步骤二:(可选)调用 setVideoConfig 接口设置编码分辨率,默认值为 “360 × 640”, 可以根据需要调整,若保持默认值则跳过此步骤。
ZegoVideoConfig config = new ZegoVideoConfig();
竖屏直播的分辨率设置如下:
config.setEncodeResolution(360, 640);
ZegoExpressEngine.getEngine().setVideoConfig(config);
步骤三:调用 loginRoom 接口登录房间,详情请参考 快速开始 – 实现流程 的 “3.2 登录房间”。
ZegoExpressEngine.getEngine().loginRoom("test_roomid", new ZegoUser("test_userid"), null);
步骤四:调用 startPreview 接口启动本地预览,用于显示本地画面。textureViewLocalPreview 为布局上的 TextureView 对象。
ZegoExpressEngine.getEngine().startPreview(new ZegoCanvas(textureViewLocalPreview));
步骤五:调用 startPublishingStream 接口开始推流,将本地的音视频流推送到实时音视频云,详情请参考 快速开始 – 实现流程 的 “3.3 推流”。
ZegoExpressEngine.getEngine().startPublishingStream("test_streamid");
步骤六:使用固定的竖屏方式进行直播或视频通话。
4.2 固定横屏
使用横屏直播或视频通话时,宽的分辨率应比高的分辨率大,假设为 “640 × 360”,则需要通过如下步骤实现功能。 步骤一:调用 createEngine 接口创建 SDK 引擎实例,详情请参考 快速开始 – 实现流程 的 “3.1 创建引擎”。
// 创建引擎,通用场景接入,并注册 self 为 eventHandler 回调
// 不需要注册回调的话,eventHandler 参数可以传 null,后续可调用 "setEventHandler:" 方法设置回调
ZegoEngineProfile profile = new ZegoEngineProfile();
profile.appID = ; // 请通过官网注册获取,格式为:1234567890L
profile.scenario = ZegoScenario.GENERAL; // 通用场景接入
profile.application = getApplication();
engine = ZegoExpressEngine.createEngine(profile, null);
步骤二:调用 setVideoConfig 接口设置编码分辨率为 “640 × 360”。
ZegoVideoConfig config = new ZegoVideoConfig();
横屏直播的分辨率设置如下:
config.setEncodeResolution(640, 360);
ZegoExpressEngine.getEngine().setVideoConfig(config);
步骤三:调用 setAppOrientation 接口设置视频的朝向,若逆时针旋转 90 度,则如下接口传参为 ZegoOrientation.ORIENTATION_90。若顺时针旋转 90 度,则传参为 ZegoOrientation.ORIENTATION_270。
ZegoExpressEngine.getEngine().setAppOrientation(ZegoOrientation.ORIENTATION_90);
步骤四:调用 loginRoom 接口登录房间,详情请参考 快速开始 – 实现流程 的 “3.2 登录房间”。
ZegoExpressEngine.getEngine().loginRoom("test_roomid", new ZegoUser("test_userid"), null);
步骤五:调用 startPreview 接口启动本地预览,用于显示本地画面。textureViewLocalPreview 为布局上的 TextureView 对象。
ZegoExpressEngine.getEngine().startPreview(new ZegoCanvas(textureViewLocalPreview));
步骤六:调用 startPublishingStream 接口开始推流,将本地的音视频流推送到实时音视频云,详情请参考 快速开始 – 实现流程 的 “3.3 推流”。
ZegoExpressEngine.getEngine().startPublishingStream("test_streamid");
步骤七:使用固定的横屏方式进行直播或视频通话。
4.3 横竖屏自动切换
若直播或视频通话过程中 App 的设置为视频画面根据重力感应的变化而旋转,则需要监听对应平台的屏幕旋转事件,并依此做视频方向的旋转。 当开发者使用 SDK 采集时,横竖屏切换主要通过 setVideoConfig 接口设置编码分辨率,并通过 setAppOrientation 接口设置视频朝向。 在对应 Activity 中监听屏幕旋转事件触发的 “onConfigurationChanged” 回调,在事件处理的回调中修改对应编码分辨率并告知 SDK App 的方向。
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
ZegoVideoConfig videoConfig = ZegoExpressEngine.getEngine().getVideoConfig();
ZegoOrientation orientation = ZegoOrientation.ORIENTATION_0;
if(Surface.ROTATION_0 == this.getWindowManager().getDefaultDisplay().getRotation()){
orientation = ZegoOrientation.ORIENTATION_0;
videoConfig.setEncodeResolution(360, 640);
}else if(Surface.ROTATION_180 == this.getWindowManager().getDefaultDisplay().getRotation()){
orientation = ZegoOrientation.ORIENTATION_180;
videoConfig.setEncodeResolution(360, 640);
}else if(Surface.ROTATION_270 == this.getWindowManager().getDefaultDisplay().getRotation()){
orientation = ZegoOrientation.ORIENTATION_270;
videoConfig.setEncodeResolution(640, 360);
}else if(Surface.ROTATION_90 == this.getWindowManager().getDefaultDisplay().getRotation()){
orientation = ZegoOrientation.ORIENTATION_90;
videoConfig.setEncodeResolution(640, 360);
}
ZegoExpressEngine.getEngine().setAppOrientation(orientation);
ZegoExpressEngine.getEngine().setVideoConfig(videoConfig);
}
当开发者使用 自定义视频采集 时,监听设备方向变化后,可参考以下两种方式实现横竖屏切换:
- 自行处理视频帧数据:在设备方向变化的回调中,对采集到的视频帧数据做旋转处理,再将处理后的数据通过 sendCustomVideoCaptureTextureData 接口传给 SDK。
- 通过 SDK 处理视频帧数据:在设备方向变化的回调中,在将采集到的视频帧数据传给 SDK 之前,根据实际朝向设置 ZegoVideoEncodedFrameParam 中的 “rotation”,调用 sendCustomVideoCaptureEncodedData 接口传入视频帧数据和设置朝向的参数,将数据传给 SDK。
API 参考列表
方法描述createEngine创建引擎单例对象setVideoConfig设置视频配置setAppOrientation设置采集视频的朝向loginRoom登录房间startPreview启动/更新本地预览startPublishingStream开始推流
常见问题
Q:为什么录制出来的直播流好像看不了?
A:由于横竖屏切换时,流的编码分辨率被修改,部分第三方播放器对分辨率修改的视频兼容性不好,可能会出现播放失败的问题,因此一般不推荐在直播或视频过程中进行横竖屏切换时修改分辨率。
原创文章,作者:ZEGO即构科技,如若转载,请注明出处:https://market-blogs.zego.im/reports-technique/460/