demo:新增xor播放支持
sdk:player: texture 播放链优化
This commit is contained in:
@@ -582,7 +582,9 @@ player.play()
|
||||
|
||||
- `RTMP` 播放支持 `SurfaceView`、`TextureView`、`SurfaceTexture`
|
||||
- `RTC/WHEP` 播放支持 `SurfaceViewRenderer`、`TextureView`,以及高级场景下的 `SurfaceTexture`
|
||||
- 当前版本建议在 **开始播放前** 选定渲染后端;当前 Demo 在首页设置中统一选择,进入页面后不再暴露热切换
|
||||
- `RTMP/VOD` 的 `TextureView / SurfaceTexture` 默认走 **direct output**,优先保证首帧和低延迟
|
||||
- 当前版本建议在 **开始播放前** 选定渲染后端;运行中如需变更目标,请走 `clearRenderTarget()` + `setRenderView(...)` / `setRenderSurfaceTexture(...)` 的显式重绑流程
|
||||
- Flutter 场景优先使用 `setRenderSurfaceTexture(...)`,配合 Flutter `Texture` widget 使用;如 UI 层级正确性优先,不建议继续依赖 `Hybrid Composition + SurfaceView`
|
||||
|
||||
控制接口:
|
||||
|
||||
@@ -599,6 +601,29 @@ player.play()
|
||||
- `clearRenderTarget()`:解绑当前渲染面,播放会话可继续存活
|
||||
- `seekBy(deltaMs)`:播放进度跳转(仅在流支持快进/回放时有效)
|
||||
|
||||
### 7.3.2 Flutter / SurfaceTexture 接入建议
|
||||
|
||||
如果业务侧需要把视频放到 Flutter UI 层下面,并正常叠加按钮、封面、弹层、动画,推荐使用:
|
||||
|
||||
- Flutter 侧创建 `TextureRegistry.SurfaceTextureEntry`
|
||||
- Android 插件层取出 `SurfaceTexture`
|
||||
- 调用 `setRenderSurfaceTexture(surfaceTexture, width, height)`
|
||||
- Flutter 页面使用 `Texture(textureId)` 显示视频
|
||||
|
||||
示意:
|
||||
|
||||
```kotlin
|
||||
player.setRenderSurfaceTexture(surfaceTexture, width, height)
|
||||
player.prepareToPlay()
|
||||
player.play()
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- `SurfaceTexture` 生命周期由调用方负责
|
||||
- 销毁前建议先调用 `clearRenderTarget()` 或直接 `release()`
|
||||
- 如果页面重建、Texture 重新申请或 Flutter 侧切换 textureId,需要重新绑定新的 `SurfaceTexture`
|
||||
|
||||
### 7.4 播放回调
|
||||
|
||||
```kotlin
|
||||
@@ -622,6 +647,60 @@ player.delegate = object : SellyLiveVideoPlayerDelegate {
|
||||
- `Reconnecting`
|
||||
- `Failed`
|
||||
|
||||
首帧语义说明:
|
||||
|
||||
- 默认 `DIRECT` 模式下,`onFirstVideoFrameRendered()` 对应 decoder 首帧可用时机
|
||||
- 对 `TextureView / SurfaceTexture` 且启用了 playback processing 的场景,SDK 会等待目标渲染面确认首帧已真正呈现后,再触发 `onFirstVideoFrameRendered()`
|
||||
- `onFirstAudioFrameRendered()` 仍表示音频首帧可播放时机;在 texture-backed processing 场景中,音频与视频首帧不一定完全同一时刻
|
||||
|
||||
### 7.4.1 播放侧帧回调与二次处理
|
||||
|
||||
播放器支持一组独立于采集/推流链路的播放侧高级能力:
|
||||
|
||||
- `setPlaybackFrameObserver(observer)`:播放侧只读帧回调
|
||||
- `setPlaybackVideoProcessor(processor)`:播放侧可写纹理处理
|
||||
|
||||
当前能力边界:
|
||||
|
||||
- 当前仅支持 **texture-backed** 播放目标:`TextureView` / `SurfaceTexture`
|
||||
- 当前仅支持 `preferredFormat = TEXTURE_2D`
|
||||
- 当前仅支持 `stage = RENDER_PRE_DISPLAY`
|
||||
- 当前默认渲染模式为 `DIRECT`
|
||||
- 只有设置了有效的 observer / processor,才会切到 `PROCESSING`
|
||||
- 如果当前 render target 已经绑定,新增或移除 observer / processor 后,需要 **重绑一次 texture render target** 才会生效
|
||||
- `RTC/WHEP` 播放当前不支持这套 playback processing;当前主要用于 `RTMP/VOD` 播放链
|
||||
|
||||
只读 observer 示例:
|
||||
|
||||
```kotlin
|
||||
player.setPlaybackFrameObserver(object : PlaybackFrameObserver {
|
||||
override val config = PlaybackFrameObserverConfig(
|
||||
preferredFormat = VideoProcessFormat.TEXTURE_2D,
|
||||
stage = VideoStage.RENDER_PRE_DISPLAY
|
||||
)
|
||||
|
||||
override fun onTextureFrame(frame: VideoTextureFrame) {
|
||||
// 读取播放侧纹理帧信息
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
可写 processor 示例:
|
||||
|
||||
```kotlin
|
||||
player.setPlaybackVideoProcessor(object : PlaybackVideoProcessor {
|
||||
override val config = PlaybackVideoProcessorConfig(
|
||||
preferredFormat = VideoProcessFormat.TEXTURE_2D,
|
||||
mode = VideoProcessMode.READ_WRITE,
|
||||
stage = VideoStage.RENDER_PRE_DISPLAY
|
||||
)
|
||||
|
||||
override fun processTexture(input: VideoTextureFrame, outputTextureId: Int) {
|
||||
// 将后处理结果写入 outputTextureId
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### 7.5 播放 API 速览(含 Demo 未覆盖)
|
||||
|
||||
创建与渲染:
|
||||
@@ -634,6 +713,8 @@ player.delegate = object : SellyLiveVideoPlayerDelegate {
|
||||
- `setRenderSurfaceTexture(surfaceTexture, width, height)`:绑定 `SurfaceTexture`(调用方负责 SurfaceTexture 生命周期)
|
||||
- `clearRenderTarget()`:解绑当前渲染面
|
||||
- `getRenderView()`:获取当前渲染 View
|
||||
- `setPlaybackFrameObserver(observer)`:设置播放侧只读 observer(texture 路径)
|
||||
- `setPlaybackVideoProcessor(processor)`:设置播放侧 processor(texture 路径)
|
||||
|
||||
播放控制:
|
||||
|
||||
@@ -655,6 +736,12 @@ player.delegate = object : SellyLiveVideoPlayerDelegate {
|
||||
- `setRenderView(surfaceView)` / `setRenderView(textureView)`:手动绑定现有 View
|
||||
- `setRenderSurfaceTexture(surfaceTexture, width, height)`:高级场景使用 `SurfaceTexture`(调用方负责 SurfaceTexture 生命周期)
|
||||
- `clearRenderTarget()`:解绑当前渲染面但不一定立即销毁播放实例
|
||||
- `setPlaybackFrameObserver(observer)` / `setPlaybackVideoProcessor(processor)`:点播同样支持 texture-backed playback processing
|
||||
|
||||
补充说明:
|
||||
|
||||
- 点播在重绑 `TextureView / SurfaceTexture` 后,会自动复用最近一次视频宽高信息,保持正确显示比例
|
||||
- 如在已有 texture 目标上新增或移除 observer / processor,也需要重绑一次 texture render target 才会应用新的渲染模式
|
||||
|
||||
因此 Demo 中点播页的 `SurfaceView / TextureView` 选择,也与直播播放页保持一致,均在首页设置中统一生效。
|
||||
|
||||
@@ -681,6 +768,10 @@ player.delegate = object : SellyLiveVideoPlayerDelegate {
|
||||
|
||||
- 推流前先完成采集预览
|
||||
- `SurfaceView / TextureView` backend 建议在开始推流或播放前选定
|
||||
- Flutter 场景优先使用 `setRenderSurfaceTexture(...)`,不要把 `Hybrid Composition + SurfaceView` 当成默认方案
|
||||
- 普通播放默认保持 `DIRECT`;只有确实需要播放侧帧观察或纹理后处理时,再启用 playback processing
|
||||
- playback processing 当前仅建议用于 `TextureView / SurfaceTexture + TEXTURE_2D + RENDER_PRE_DISPLAY`
|
||||
- 变更 texture 路径的 observer / processor 后,显式重绑一次 render target
|
||||
- `RTC/WHIP` 的美颜、滤镜、水印、观测优先使用 `TEXTURE_2D`
|
||||
- `I420 / RGBA` 仅在算法必须访问 CPU 像素时再使用
|
||||
- 完整重写输出的 GPU 处理器设置 `fullRewrite = true`;叠加类处理保留默认值
|
||||
@@ -723,13 +814,13 @@ SDK 不解析 URL 中的鉴权信息,所有鉴权均通过 `token` 属性完
|
||||
|
||||
- 普通原生 Android 页面,优先使用默认 `SurfaceView`,性能最优
|
||||
- 需要与按钮、封面、弹层等普通 View 正常混排时,优先使用 `TextureView`
|
||||
- Flutter 场景通过 `setRenderSurfaceTexture()` 接入,走 `TextureView` 同一套渲染管线
|
||||
- Flutter 场景通过 `setRenderSurfaceTexture()` 接入,配合 Flutter `Texture` widget 使用
|
||||
- 当前版本建议在开始推流/播放前选定 backend;当前 Demo 在首页设置中统一选择,进入页面后不支持切换
|
||||
|
||||
### Q5.1:`TextureView` 模式下,VOD/RTMP 播放的 `BufferQueueProducer timeout` 日志是什么?
|
||||
**A:**
|
||||
|
||||
SDK 内部使用 GL Bridge 将 MediaCodec 硬解输出通过 OpenGL 中转渲染到 TextureView,大幅减少此类日志。如在极端场景下仍偶现,属于 Android 系统 BufferQueue 机制限制,不影响播放功能。`SurfaceView` 路径不存在此问题。
|
||||
当前 `RTMP/VOD` 的 `TextureView / SurfaceTexture` 默认走 direct output,以缩短首帧和减少黑屏。极端机型或系统版本下仍可能偶现 `BufferQueueProducer timeout` / `BufferQueue has been abandoned` 之类系统日志;如果不伴随黑屏、花屏、卡死,通常可视为 Android BufferQueue 机制噪声。开启 playback processing 时,texture 路径内部会启用额外的处理中转链,日志形态也可能与 direct 模式不同。
|
||||
|
||||
### Q5.2:`attach` 和 `set` 两套 API 的区别?
|
||||
**A:**
|
||||
|
||||
Reference in New Issue
Block a user