Unity中使用AVPRO播放视频

一般来说有两种方式。

1.直接播放:

1.1添加组件

1.2设置参数:

注意Auto Open是开始就就打开准备视频,但不播放。

下方红色矩形框住的区域要勾选,出声音外。

2.代码控制:

代码可以让视频播放更灵活,以及很多不同状态的监听

2.1组件与上方一致,参数与上方图片中参数一致。

2.2代码:

cs 复制代码
using UnityEngine;
using RenderHeads.Media.AVProVideo;

public class AVProVideoController : MonoBehaviour
{
    [Header("AVPro组件")]
    [SerializeField] private MediaPlayer mediaPlayer;
    //[SerializeField] private DisplayUGUI displayUGUI;

    [Header("视频设置")]
    [SerializeField] private string videoPath = "Videos/MyVideo.mp4";
    [SerializeField] private bool autoPlay = true;
    [SerializeField] private bool loop = false;

    private void Start()
    {
        if (mediaPlayer == null)
        {
            mediaPlayer = GetComponent<MediaPlayer>();
        }

        if (mediaPlayer != null)
        {
            // 注册所有事件监听
            RegisterEvents();

            // 加载视频
            LoadVideo();
        }
        else
        {
            Debug.LogError("MediaPlayer组件未找到!");
        }
    }

    private void OnDestroy()
    {
        // 注销事件监听
        UnregisterEvents();
    }

    /// <summary>
    /// 注册所有事件监听
    /// </summary>
    private void RegisterEvents()
    {
        mediaPlayer.Events.AddListener(OnMediaPlayerEvent);
    }

    /// <summary>
    /// 注销所有事件监听
    /// </summary>
    private void UnregisterEvents()
    {
        if (mediaPlayer != null)
        {
            mediaPlayer.Events.RemoveListener(OnMediaPlayerEvent);
        }
    }

    /// <summary>
    /// AVPro事件回调
    /// </summary>
    private void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)
    {
        switch (et)
        {
            case MediaPlayerEvent.EventType.ReadyToPlay:
                OnVideoReadyToPlay();//视频准备就绪
                break;

            case MediaPlayerEvent.EventType.Started:
                OnVideoStarted();//视频开始播放
                break;

            case MediaPlayerEvent.EventType.FirstFrameReady:
                OnFirstFrameReady();//视频第一帧已准备就绪
                break;

            case MediaPlayerEvent.EventType.FinishedPlaying:
                OnVideoFinished();//视频播放完成
                break;

            case MediaPlayerEvent.EventType.Closing:
                OnVideoClosing();//视频正在关闭
                break;

            case MediaPlayerEvent.EventType.Error:
                OnVideoError(errorCode);
                break;

            case MediaPlayerEvent.EventType.SubtitleChange:
                OnSubtitleChange();
                break;

            case MediaPlayerEvent.EventType.Stalled:
                OnVideoStalled();
                break;

            case MediaPlayerEvent.EventType.Unstalled:
                OnVideoUnstalled();//视频恢复播放
                break;

            case MediaPlayerEvent.EventType.ResolutionChanged:
                OnResolutionChanged();//分辨率改变
                break;

            case MediaPlayerEvent.EventType.StartedSeeking:
                OnStartedSeeking();//开始跳转播放位置(不只跳转时间,更改倍速和重播也会执行)
                break;

            case MediaPlayerEvent.EventType.FinishedSeeking:
                OnFinishedSeeking();//跳转完成(不只跳转时间,更改倍速和重播也会执行)
                break;

            case MediaPlayerEvent.EventType.StartedBuffering:
                OnStartedBuffering();//视频开始缓冲
                break;

            case MediaPlayerEvent.EventType.FinishedBuffering:
                OnFinishedBuffering();//视频缓冲完成
                break;

            case MediaPlayerEvent.EventType.PropertiesChanged:
                OnPropertiesChanged();
                break;

            case MediaPlayerEvent.EventType.PlaylistItemChanged:
                OnPlaylistItemChanged();
                break;

            case MediaPlayerEvent.EventType.PlaylistFinished:
                OnPlaylistFinished();
                break;
        }
    }

    #region 事件处理方法

    /// <summary>
    /// 视频准备就绪,可以开始播放
    /// </summary>
    private void OnVideoReadyToPlay()
    {
        Debug.Log("视频准备就绪!");
        Debug.Log($"视频时长: {mediaPlayer.Info.GetDuration()} 秒");
        Debug.Log($"视频分辨率: {mediaPlayer.Info.GetVideoWidth()}x{mediaPlayer.Info.GetVideoHeight()}");

        if (autoPlay)
        {
            mediaPlayer.Play();
        }
    }

    /// <summary>
    /// 视频开始播放
    /// </summary>
    private void OnVideoStarted()
    {
        Debug.Log("视频开始播放");
    }

    /// <summary>
    /// 第一帧准备就绪
    /// </summary>
    private void OnFirstFrameReady()
    {
        Debug.Log("第一帧已准备就绪");
    }

    /// <summary>
    /// 视频播放完成
    /// </summary>
    private void OnVideoFinished()
    {
        Debug.Log("视频播放完成!");

        if (loop)
        {
            mediaPlayer.Rewind(false);
            mediaPlayer.Play();
        }
    }

    /// <summary>
    /// 视频正在关闭
    /// </summary>
    private void OnVideoClosing()
    {
        Debug.Log("视频正在关闭");
    }

    /// <summary>
    /// 视频播放错误
    /// </summary>
    private void OnVideoError(ErrorCode errorCode)
    {
        Debug.LogError($"视频播放错误: {errorCode}");
    }

    /// <summary>
    /// 字幕改变
    /// </summary>
    private void OnSubtitleChange()
    {
        Debug.Log("字幕改变");
    }

    /// <summary>
    /// 视频卡顿
    /// </summary>
    private void OnVideoStalled()
    {
        Debug.LogWarning("视频卡顿");
    }

    /// <summary>
    /// 视频恢复
    /// </summary>
    private void OnVideoUnstalled()
    {
        Debug.Log("视频恢复播放");
    }

    /// <summary>
    /// 分辨率改变
    /// </summary>
    private void OnResolutionChanged()
    {
        Debug.Log($"分辨率改变: {mediaPlayer.Info.GetVideoWidth()}x{mediaPlayer.Info.GetVideoHeight()}");
    }

    /// <summary>
    /// 开始跳转
    /// </summary>
    private void OnStartedSeeking()
    {
        Debug.Log("开始跳转播放位置");
    }

    /// <summary>
    /// 跳转完成
    /// </summary>
    private void OnFinishedSeeking()
    {
        Debug.Log("跳转完成");
    }

    /// <summary>
    /// 开始缓冲
    /// </summary>
    private void OnStartedBuffering()
    {
        Debug.Log("开始缓冲...");
    }

    /// <summary>
    /// 缓冲完成
    /// </summary>
    private void OnFinishedBuffering()
    {
        Debug.Log("缓冲完成");
    }

    /// <summary>
    /// 属性改变
    /// </summary>
    private void OnPropertiesChanged()
    {
        Debug.Log("视频属性改变");
    }

    /// <summary>
    /// 播放列表项改变
    /// </summary>
    private void OnPlaylistItemChanged()
    {
        Debug.Log("播放列表项改变");
    }

    /// <summary>
    /// 播放列表完成
    /// </summary>
    private void OnPlaylistFinished()
    {
        Debug.Log("播放列表播放完成");
    }

    #endregion

    #region 公共控制方法

    /// <summary>
    /// 加载视频
    /// </summary>
    public void LoadVideo()
    {
        if (mediaPlayer != null && !string.IsNullOrEmpty(videoPath))
        {
            mediaPlayer.OpenMedia(new MediaPath(videoPath, MediaPathType.RelativeToStreamingAssetsFolder), autoPlay);
            Debug.Log($"正在加载视频: {videoPath}");
        }
    }

    /// <summary>
    /// 加载指定路径的视频
    /// </summary>
    public void LoadVideo(string path, MediaPathType pathType = MediaPathType.RelativeToStreamingAssetsFolder)
    {
        if (mediaPlayer != null && !string.IsNullOrEmpty(path))
        {
            mediaPlayer.OpenMedia(new MediaPath(path, pathType), autoPlay);
            Debug.Log($"正在加载视频: {path}");
        }
    }

    /// <summary>
    /// 播放视频
    /// </summary>
    public void Play()
    {
        if (mediaPlayer != null && mediaPlayer.Control != null)
        {
            mediaPlayer.Play();
        }
    }

    /// <summary>
    /// 暂停视频
    /// </summary>
    public void Pause()
    {
        if (mediaPlayer != null && mediaPlayer.Control != null)
        {
            mediaPlayer.Pause();
        }
    }

    /// <summary>
    /// 停止视频
    /// </summary>
    public void Stop()
    {
        if (mediaPlayer != null && mediaPlayer.Control != null)
        {
            mediaPlayer.Stop();
        }
    }

    /// <summary>
    /// 关闭视频
    /// </summary>
    public void Close()
    {
        if (mediaPlayer != null)
        {
            mediaPlayer.CloseMedia();
        }
    }

    /// <summary>
    /// 跳转到指定时间(秒)
    /// </summary>
    public void SeekToTime(float timeInSeconds)
    {
        if (mediaPlayer != null && mediaPlayer.Control != null)
        {
            mediaPlayer.Control.Seek(timeInSeconds);
        }
    }

    /// <summary>
    /// 设置音量 (0-1)
    /// </summary>
    public void SetVolume(float volume)
    {
        if (mediaPlayer != null && mediaPlayer.Control != null)
        {
            mediaPlayer.AudioVolume = volume;
        }
    }

    /// <summary>
    /// 设置播放速度
    /// </summary>
    public void SetPlaybackRate(float rate)
    {
        if (mediaPlayer != null && mediaPlayer.Control != null)
        {
            mediaPlayer.Control.SetPlaybackRate(rate);
        }
    }

    /// <summary>
    /// 获取当前播放时间(秒)
    /// </summary>
    public float GetCurrentTime()
    {
        if (mediaPlayer != null && mediaPlayer.Control != null)
        {
            return (float)mediaPlayer.Control.GetCurrentTime();
        }
        return 0f;
    }

    /// <summary>
    /// 获取视频总时长(秒)
    /// </summary>
    public float GetDuration()
    {
        if (mediaPlayer != null && mediaPlayer.Info != null)
        {
            return (float)mediaPlayer.Info.GetDuration();
        }
        return 0f;
    }

    /// <summary>
    /// 判断是否正在播放
    /// </summary>
    public bool IsPlaying()
    {
        //视频播放完后停留在最后的时候,还是会显示播放状态为true,bug!!!
        return mediaPlayer != null && mediaPlayer.Control != null && mediaPlayer.Control.IsPlaying();
    }

    #endregion

    #region Update方法 - 用于实时监控

    private void Update()
    {
        // 可以在这里添加实时监控逻辑
        // 例如更新进度条、显示当前时间等

        if (mediaPlayer != null && mediaPlayer.Control != null && mediaPlayer.Control.IsPlaying())
        {
            // 获取当前播放进度
            float currentTime = GetCurrentTime();
            float duration = GetDuration();

            if (duration > 0)
            {
                float progress = currentTime / duration;
                // 这里可以更新UI进度条
                // progressSlider.value = progress;
            }
        }








        #region 测试
        if (Input.GetKeyDown(KeyCode.F))
        {
            mediaPlayer.Play();
        }
        if (Input.GetKeyDown(KeyCode.G))
        {
            mediaPlayer.Pause();
        }
        if (Input.GetKeyDown(KeyCode.H))
        {
            mediaPlayer.Stop();
        }
        if (Input.GetKeyDown(KeyCode.J))
        {
            mediaPlayer.CloseMedia();
        }
        if (Input.GetKeyDown(KeyCode.K))
        {
            if (GetCurrentTime()+5.0f<GetDuration())
            {
                SeekToTime(GetCurrentTime() + 5.0f);
            }
        }
        if (Input.GetKeyDown(KeyCode.L))
        {
            SetPlaybackRate(3);
        }
        if (Input.GetKeyDown(KeyCode.P))
        {
            SetPlaybackRate(1);
        }
        if (Input.GetKeyDown(KeyCode.O))
        {
            mediaPlayer.Rewind(false);
            mediaPlayer.Play();
        }
        if (Input.GetKeyDown(KeyCode.I))
        {
            SetVolume(mediaPlayer.AudioVolume+0.01f);
        }
        if (Input.GetKeyDown(KeyCode.U))
        {
            IsPlaying();
        }
        #endregion
    }

    #endregion
}
相关推荐
Ray Liang20 小时前
用六边形架构与整洁架构对比是伪命题?
java·python·c#·架构设计
Scout-leaf4 天前
WPF新手村教程(三)—— 路由事件
c#·wpf
用户298698530144 天前
程序员效率工具:Spire.Doc如何助你一键搞定Word表格排版
后端·c#·.net
mudtools5 天前
搭建一套.net下能落地的飞书考勤系统
后端·c#·.net
玩泥巴的5 天前
搭建一套.net下能落地的飞书考勤系统
c#·.net·二次开发·飞书
唐宋元明清21886 天前
.NET 本地Db数据库-技术方案选型
windows·c#
lindexi6 天前
dotnet DirectX 通过可等待交换链降低输入渲染延迟
c#·directx·d2d·direct2d·vortice
REDcker6 天前
WebCodecs VideoDecoder 的 hardwareAcceleration 使用
前端·音视频·实时音视频·直播·webcodecs·videodecoder
gihigo19986 天前
基于TCP协议实现视频采集与通信
网络协议·tcp/ip·音视频
qq_454245036 天前
基于组件与行为的树状节点系统
数据结构·c#