AR中SurfaceTexture流应用视频纹理报错解决及sceneview替代方案
问题解决与替代方案
一、修复“stream has not been initialized”错误
你遇到的错误核心原因是SurfaceTexture未完成有效初始化就被用来构建Stream,Stream无法获取到视频流的尺寸等关键信息。修正思路是先让MediaPlayer完成视频准备流程,拿到视频实际宽高后再初始化SurfaceTexture和Stream,具体实现如下:
修正后的代码示例:
private fun applyVideoTexture( context: Context, engine: Engine, materialInstance: MaterialInstance ) { try { val mediaPlayer = MediaPlayer.create(context, R.raw.samp).apply { isLooping = true // 监听视频准备完成事件 setOnPreparedListener { mp -> // 获取视频实际宽高 val videoWidth = mp.videoWidth val videoHeight = mp.videoHeight // 用视频尺寸初始化SurfaceTexture val surfaceTexture = SurfaceTexture(1).apply { setDefaultBufferSize(videoWidth, videoHeight) } // 构建Stream时明确指定尺寸 val stream = Stream.Builder() .stream(surfaceTexture) .size(videoWidth, videoHeight) .build(engine) // 创建并绑定VideoTexture val videoTexture = VideoTexture.Builder() .build(engine) videoTexture.setExternalStream(engine, stream) // 关联Surface并启动播放 mp.setSurface(Surface(surfaceTexture)) mp.start() // 将纹理设置到MaterialInstance materialInstance.setParameter("texture", videoTexture, TextureSampler()) } } } catch (e: Exception) { e.printStackTrace() } }
关键修正点:
- 等待MediaPlayer准备完成后再处理SurfaceTexture与Stream的创建
- 调用
SurfaceTexture.setDefaultBufferSize()传入视频实际宽高,确保流数据有效 - Stream.Builder添加
.size()参数明确指定流尺寸,避免初始化校验失败
二、sceneview:2.2.0的简化实现方案
sceneview 2.2.0封装了更易用的VideoTexture创建逻辑,无需手动管理MediaPlayer和SurfaceTexture,直接通过setSource绑定视频资源即可:
private fun applyVideoTextureSimplified( context: Context, engine: Engine, materialInstance: MaterialInstance ) { try { val videoTexture = VideoTexture.Builder() .source(context, R.raw.samp) .looping(true) .build(engine) // 启动视频播放 videoTexture.play() // 将纹理绑定到MaterialInstance materialInstance.setParameter("texture", videoTexture, TextureSampler()) } catch (e: Exception) { e.printStackTrace() } }
这种方式由框架内部处理媒体播放、流同步等细节,减少手动编码的出错概率,更适合AR新手快速实现视频纹理需求。
内容的提问来源于stack exchange,提问作者Abhi
相关产品推荐
相关产品推荐

