本章节为您介绍拉流基础功能的接入方法,根据文档提供的操作步骤进行配置,您可接入直播拉流播放控制能力。
真机调试:由于 SDK 使用了大量 Android 系统的音视频接口,这些接口在仿真模拟器下可能会出现异常,推荐您使用真机进行代码调试。
本节为您详细介绍如何通过拉流 SDK 实现直播拉流播放控制的能力,包括但不限于创建播放器、初始化配置、事件监听、设置渲染 View、设置播放地址。
使用拉流 SDK,需要先创建直播播放器。您可以参考以下代码创建播放器。
// 创建播放器 VeLivePlayer mLivePlayer = new VideoLiveManager(Env.getApplicationContext());
您可以通过 VeLivePlayerConfiguration
对播放器进行初始化相关配置。详细参数说明如下表所示。
参数 | 类型 | 说明 |
---|---|---|
enableSei | boolean | 是否开启 SEI 消息的解析。默认值为 false 。 |
enableHardwareDecode | boolean | 是否开启硬件解码功能。默认值为 true 。开启后,如果硬件解码失败,播放器会自动切换为软解码。 |
networkTimeoutMs | int | 网络超时时间,单位为 ms。默认值为 5000 。如果网络请求在超时时间内未收到服务器响应,播放器会认为请求失败。 |
retryIntervalTimeMs | int | 重试时间间隔,单位为 ms。默认值为 5000 。在播放直播时,如果出现网络异常等导致播放中断,播放器会尝试进行重试。 |
retryMaxCount | int | 播放器在网络连接错误的情况下的最大重试次数。默认值为 5 。如果配置为 0 ,表示关闭播放器内部的重试机制。 |
enableLiveDNS | boolean | 是否开启本地 DNS 预解析。默认值为 注意 如果预解析出现异常,可能会影响播放器的正常使用。 |
enableStatisticsCallback | boolean | 是否开启播放信息周期性回调。默认值为 false 。 |
statisticsCallbackInterval | int | 播放信息周期性回调的时间间隔,单位为 s。默认值为 5 。 |
您可以参考以下代码示例进行初始化配置。
// 创建配置 VeLivePlayerConfiguration config = new VeLivePlayerConfiguration(); // 打开周期性回调 config.enableStatisticsCallback = true; // 打开 Local DNS 预解析 config.enableLiveDNS = true; // 初始化播放器 mLivePlayer.setConfig(config);
您可以通过配置事件回调监听来获取播放器的内部状态信息,包括播放器状态、错误信息、音视频首帧回调以及周期性统计数据等。代码示例如下所示。
// VeLivePlayerObserver 回调 VeLivePlayerObserver mLivePlayerObserver = new VeLivePlayerObserver() { @Override public void onError(VeLivePlayer player, VeLivePlayerError error) { // 错误回调 } @Override public void onFirstVideoFrameRender(VeLivePlayer player, boolean isFirstFrame) { // 视频首帧回调 } @Override public void onFirstAudioFrameRender(VeLivePlayer player, boolean isFirstFrame) { // 音频首帧回调 } @Override public void onStallStart(VeLivePlayer player) { // 卡顿开始回调 } @Override public void onStallEnd(VeLivePlayer player) { // 卡顿结束回调 } @Override public void onVideoRenderStall(VeLivePlayer player, long stallTime) { // 视频卡顿回调 } @Override public void onAudioRenderStall(VeLivePlayer player, long stallTime) { // 音频卡顿回调 } @Override public void onResolutionSwitch(VeLivePlayer player, VeLivePlayerDef.VeLivePlayerResolution resolution, VeLivePlayerError error, VeLivePlayerDef.VeLivePlayerResolutionSwitchReason reason) { // 播放档位变化回调 } @Override public void onVideoSizeChanged(VeLivePlayer player, int width, int height) { // 分辨率变化回调 } @Override public void onReceiveSeiMessage(VeLivePlayer player, String message) { // SEI 通知回调 } @Override public void onMainBackupSwitch(VeLivePlayer player, VeLivePlayerDef.VeLivePlayerStreamType streamType, VeLivePlayerError error) { // 主备切换回调 } @Override public void onPlayerStatusUpdate(VeLivePlayer player, VeLivePlayerDef.VeLivePlayerStatus status) { // 播放器状态变化回调 } @Override public void onStatistics(VeLivePlayer player, VeLivePlayerStatistics statistics) { // 周期性回调 } @Override public void onSnapshotComplete(VeLivePlayer player, Bitmap bitmap) { // 截图回调 } @Override public void onRenderVideoFrame(VeLivePlayer player, VeLivePlayerVideoFrame videoFrame) { // 视频帧订阅回调 } @Override public void onRenderAudioFrame(VeLivePlayer player, VeLivePlayerAudioFrame audioFrame) { // 音频帧订阅回调 } } // 配置播放器回调 mLivePlayer.setObserver(mLivePlayerObserver);
为了展示播放器的视频画面,您需要配置一个渲染 View。播放器提供了 SurfaceView 和 TextureView 两种方法来配置渲染 View。
渲染方式/维度 | SurfaceView | TextureView |
---|---|---|
特点 | 独立绘图表面、高效的复杂 UI 绘制 | 兼容普通 View、支持动画和变换效果 |
线程 | 独立线程绘制,不占用主线程资源 | 与 Activity 或 Fragment 一致的生命周期 |
适用场景 | 复杂 UI 绘制、高效绘图、游戏等 | 图像展示、动画效果、与普通 View 兼容的场景 |
请根据您的需求选择合适的渲染方式,并参考下列示例代码进行配置。
<SurfaceView android:id="@+id/surfaceView" android:layout_width="match_parent" android:layout_height="match_parent" />
setSurfaceHolder
接口来配置 SurfaceView。代码示例如下所示。SurfaceView surfaceView = findViewById(R.id.surfaceView); mLivePlayer.setSurfaceHolder(surfaceView.getHolder());
注意
使用 SurfaceView 渲染视频画面时,设备的 API 级别必须为 24 或更高版本。如果设备的 API 级别低于 24,可能会出现视图层级错乱和动画不同步等问题。建议在低版本设备上,采用其他渲染方式或升级设备的 API 级别以获得最佳的播放体验。
<TextureView android:id="@+id/textureView" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@null" />
setSurface
接口来配置 TextureView。代码示例如下所示。TextureView textureView = findViewById(R.id.textureView); // 配置 SurfaceTexture 监听器。 textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) { // 当 TextureView 的 SurfaceTexture 创建完成后回调。 mLivePlayer.setSurface(new Surface(surfaceTexture)); } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) { // 在 TextureView 大小变化时回调。 } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { // 在 TextureView 被销毁之前回调,返回 true 表示自己处理 SurfaceTexture 的销毁。 return true; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { // 在 TextureView 更新时回调。 } });
通过 setPlayUrl
接口配置单一播放地址,支持 RTMP、FLV、HLS 等直播协议地址。代码示例如下所示。
// 通过 URL 进行播放 String playUrl = "http://pull.example.com/live/stream.flv"; // 配置播放地址 mLivePlayer.setPlayUrl(playUrl);
说明
如果您需要配置多路组合播放地址,可使用 setPlayStreamData
接口,该接口支持 RTM、QUIC、主备流、多档位、ABR 等功能,详细的代码示例和接入方法请参考进阶功能接入。
您可以通过以下接口调整播放画面的填充模式、镜像和旋转角度,以获得更好的观看体验。
通过播放器的 setRenderFillMode
接口可以配置播放画面的填充模式,播放器支持以下 3 种填充模式。
填充模式 | 说明 |
---|---|
VeLivePlayerFillModeAspectFit | 显示完整的视频帧。视频帧等比缩放,直至视频帧恰好在画布上全部显示。如果视频帧长宽比例与画布不同,视窗上未被视频帧填满区域将填充为黑色。 |
VeLivePlayerFillModeFullFill | 视频帧自适应画布。视频帧非等比缩放,直至填满画布。在此过程中,视频帧的长宽比例可能会发生变化。 |
VeLivePlayerFillModeAspectFill | 视频填满画布。视频帧等比缩放,直至填满画布,超出屏幕的部分将被裁剪,画面可能不完整。 |
您可以参考以下代码示例配置填充模式。
// 配置填充模式 mLivePlayer.setRenderFillMode(VeLivePlayerFillModeAspectFill);
通过播放器的 setRenderMirror
接口可以配置播放画面的镜像模式,播放器支持以下 3 种镜像模式。
镜像 | 说明 |
---|---|
VeLivePlayerMirrorNone | 关闭镜像 |
VeLivePlayerMirrorHorizontal | 水平镜像 |
VeLivePlayerMirrorVertical | 垂直镜像 |
您可以参考以下代码示例配置镜像。
// 配置水平镜像 mLivePlayer.setRenderMirror(VeLivePlayerMirrorHorizontal);
通过播放器的 setRenderRotation
接口可以配置播放画面的旋转角度,播放器支持以下 4 种旋转角度。
旋转 | 说明 |
---|---|
VeLivePlayerRotation0 | 关闭旋转 |
VeLivePlayerRotation90 | 顺时针旋转 90 度 |
VeLivePlayerRotation180 | 顺时针旋转 180 度 |
VeLivePlayerRotation270 | 顺时针旋转 270 度 |
您可以参考以下代码示例配置旋转角度。
// 配置画面旋转 90 度 mLivePlayer.setRenderRotation(VeLivePlayerRotation90);
调用播放器的 play
接口开始播放。代码示例如下所示。
mLivePlayer.play(); //开始播放。
调用播放器的 isPlaying
接口可以获取当前的播放状态。代码示例如下所示。
boolean isPlaying = mLivePlayer.isPlaying(); //获取播放状态
调用播放器的 pause
接口暂停播放,代码示例如下所示。
mLivePlayer.pause(); //暂停播放
说明
在直播中,暂停和停止的行为相同。暂停后再调用 play
方法,播放器将重新拉流。
调用播放器的 stop
接口停止播放。代码示例如下所示。
mLivePlayer.stop(); //停止播放
调用播放器的 destroy
接口销毁播放器并释放内存。当您停止播放后需要销毁播放器时,请调用该接口。代码示例如下所示。
mLivePlayer.destroy(); // 销毁拉流引擎,退出前释放播放器和内存
在应用程序从前台切换到后台时,播放器默认会继续播放音频。如果您希望在后台状态停止播放,可参考以下示例代码。
@Override protected void onResume() { super.onResume(); if (mLivePlayer != null) { mLivePlayer.play(); // 回到前台,继续播放 } } @Override protected void onPause() { super.onPause(); if (mLivePlayer != null) { mLivePlayer.pause(); // 退到后台,暂停播放 } }
调用播放器的 setMute
接口可以控制是否静音播放。代码示例如下所示。
mLivePlayer.setMute(true); // 配置静音播放
调用播放器的 isMute
接口可以获取当前是否为静音状态。代码示例如下所示。
boolean isMute = mLivePlayer.isMute(); // 获取静音状态
调用播放器的 setPlayerVolume
接口可以控制播放音量,参数表示音量大小,默认值为 1.0,取值范围为 [0.0,1.0]。代码示例如下所示。
mLivePlayer.setPlayerVolume(0.5f); // 配置播放音量
您可以通过调用 setLogLevel
设置打印到控制台的日志级别,代码示例如下:
// 输出 DEBUG、INFO、WARNING 和 ERROR 级别的日志 VeLivePlayer.setLogLevel(VeLivePlayerLogConfig.VeLivePlayerLogLevel.VeLivePlayerLogLevelDebug);