You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 10:42:32