朱贝文 2025-09-20 12:58 采纳率: 100%
浏览 13
已结题

Unity在Pico端使用AVProVideo显示播放多个视频的问题

Unity做Pico端博物馆项目,有18个地方播放视频,程序打开都展示第一帧画面,人物靠近显示屏才播放视频,远离暂停,使用AVProVideo打开视频总有随机两个没有加载。写在for循环里面最后两个没有加载,怎么解决?下面是开始初始加载视频的方法:

1.


private IEnumerator LoadVideo()
    {
        yield return null;  //下一帧开始处理
        Debug.Log("开始执行...");
        for (int i = 0; i < mediaObjList.Count; i++)
        {
            MediaPlayer mediaPlayer = mediaObjList[i].transform.Find("MediaPlayer").GetComponent<MediaPlayer>();
            yield return mediaPlayer.OpenMedia(false);
        }
    }

  • 写回答

6条回答 默认 最新

  • 檀越@新空间 2025-09-20 12:59
    关注

    中午好🌞🌞🌞
    本答案参考通义千问

    在使用 Unity + AVProVideoPico 端开发博物馆项目时,遇到 18 个视频中随机两个未加载 的问题,且 写在 for 循环里最后两个未加载,这是一个典型的 异步加载与资源释放冲突资源初始化顺序问题


    🚨 问题分析

    1. AVProVideo 的 OpenMedia 方法是异步的,它需要一定时间来加载视频内容。
    2. 如果你直接在 for 循环中调用 yield return mediaPlayer.OpenMedia(false);可能会导致多个协程同时执行,造成资源竞争或加载失败。
    3. Pico 设备性能有限,如果一次性加载太多视频资源,可能导致部分资源无法正确加载。
    4. 最后一个视频可能因协程提前结束而没有被处理

    ✅ 解决方案

    1. 优化协程逻辑,确保每个视频都完整加载

    private IEnumerator LoadVideo()
    {
        Debug.Log("开始执行...");
        
        for (int i = 0; i < mediaObjList.Count; i++)
        {
            MediaPlayer mediaPlayer = mediaObjList[i].transform.Find("MediaPlayer").GetComponent<MediaPlayer>();
            
            // 确保MediaPlayer存在
            if (mediaPlayer == null)
            {
                Debug.LogError("MediaPlayer 未找到: " + mediaObjList[i].name);
                continue;
            }
    
            // 异步加载视频
            yield return mediaPlayer.OpenMedia(false);
    
            // 可选:等待一段时间,防止资源争抢
            yield return new WaitForSeconds(0.1f);
        }
    }
    

    重点说明:

    • 每个 OpenMedia 都要 yield return,确保前一个完成后再继续下一个。
    • 添加 WaitForSeconds(0.1f) 是为了防止 Pico 设备资源过载,提高稳定性。

    2. 使用更安全的初始化方式(推荐)

    private IEnumerator LoadVideo()
    {
        Debug.Log("开始执行...");
    
        for (int i = 0; i < mediaObjList.Count; i++)
        {
            MediaPlayer mediaPlayer = mediaObjList[i].transform.Find("MediaPlayer").GetComponent<MediaPlayer>();
    
            if (mediaPlayer == null)
            {
                Debug.LogError("MediaPlayer 未找到: " + mediaObjList[i].name);
                continue;
            }
    
            // 使用 OpenMediaWithFile 代替 OpenMedia
            yield return mediaPlayer.OpenMediaWithFile(false, "YourVideoPath" + i + ".mp4");
    
            // 可选:等待一段时间
            yield return new WaitForSeconds(0.1f);
        }
    }
    

    重点说明:

    • 使用 OpenMediaWithFile 更稳定,避免路径错误。
    • 确保你的视频文件路径正确,并且已经打包到 Unity 项目中。

    3. 检查视频资源是否正确导入和打包

    • 确保所有视频文件已放入 Assets/Resources/ 文件夹,或者通过 StreamingAssets 加载。
    • 在 Pico 上运行时,确保视频文件已正确打包到 APK 中。
    • 避免使用绝对路径,尽量使用相对路径或 Resources.Load()

    4. 增加日志输出,定位未加载的视频

    LoadVideo() 中添加详细日志:

    Debug.Log($"尝试加载第 {i} 个视频: {mediaObjList[i].name}");
    

    这样可以判断哪几个视频未加载,进一步排查问题。


    5. 优化内存管理,避免资源泄露

    • 不需要播放的视频应调用 mediaPlayer.Dispose(); 释放资源。
    • 使用 Destroy(mediaPlayer.gameObject); 释放不使用的对象。

    📌 总结解决方案(有序列表)

    1. 确保每个 OpenMedia 都有 yield return,避免并发加载。
    2. 使用 OpenMediaWithFile 替代 OpenMedia,提升稳定性。
    3. 检查视频路径是否正确,确保资源已打包。
    4. 添加详细日志,定位未加载的视频。
    5. 合理释放未使用的视频资源,避免内存溢出。

    🛠️ 示例代码(修改后)

    private IEnumerator LoadVideo()
    {
        Debug.Log("开始执行...");
    
        for (int i = 0; i < mediaObjList.Count; i++)
        {
            Transform mediaPlayerTransform = mediaObjList[i].transform.Find("MediaPlayer");
            if (mediaPlayerTransform == null)
            {
                Debug.LogError("MediaPlayer 未找到: " + mediaObjList[i].name);
                continue;
            }
    
            MediaPlayer mediaPlayer = mediaPlayerTransform.GetComponent<MediaPlayer>();
            if (mediaPlayer == null)
            {
                Debug.LogError("MediaPlayer 组件未找到: " + mediaObjList[i].name);
                continue;
            }
    
            string videoPath = "Videos/Video" + i; // 根据实际路径调整
            Debug.Log($"尝试加载第 {i} 个视频: {videoPath}");
    
            yield return mediaPlayer.OpenMediaWithFile(false, videoPath);
    
            // 等待 0.1 秒,防止资源争抢
            yield return new WaitForSeconds(0.1f);
        }
    
        Debug.Log("所有视频加载完成!");
    }
    

    如果你能提供具体的 mediaObjList 结构和视频路径,我可以进一步帮你调试。希望这些建议能帮助你解决问题!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 10月3日
  • 已采纳回答 9月25日
  • 创建了问题 9月20日