Unity 使用AVProMovieCapture实现Game视图屏幕录制

内容将会持续更新,有错误的地方欢迎指正,谢谢!

Unity 使用AVProMovieCapture实现Game视图屏幕录制


|-----------------------------------------------------|
| TechX 坚持将创新的科技带给世界! 拥有更好的学习体验 ------ 不断努力,不断进步,不断探索 |

|-------------------------------------------------------------------------|
| TechX ------ 心探索、心进取! 助力快速掌握 AVProMovieCapture 屏幕录制 为初学者节省宝贵的学习时间,避免困惑! |


文章目录


一、导入AVProMovieCapture包

Asset Store资源商店里面可以下载这个插件:

https://assetstore.unity.com/packages/tools/video/avpro-movie-capture-desktop-edition-221914

目前这个插件比较贵,以下提供了老一点的版本,也是可以用的。
https://download.csdn.net/download/caiprogram123/89517225

下载之后解压,并把这个包导入到Unity中,可以看到RenderHeads/AVProMovieCapture


二、屏幕捕捉基本设置

在开始录制Game视图时要对录制做一些基本的设置:

  • 输出文件夹类型:输出视频到哪个位置

  • 输出子文件夹:输出视频位置的子文件夹

  • 分辨率:设置视频的分辨率

  • 帧率:设置视频的帧率

  • 视频前缀:设置视频名称的前缀

csharp 复制代码
//视频输出路径
public string videoOutFolder;
//视频输出路径类型
public OutputPath outputFolderType = defaultOutputFolderType;
//视频输出文件夹
public string outputFolderPath = defaultOutputFolderPath;

//视频降分辨率
public CaptureBase.DownScale downScale = CaptureBase.DownScale.Original;
//视频帧率
public float frame = 60;
//视频前缀
public string prefix = "ScreenCapture";

/// <summary>
/// 设置视频输出路径
/// </summary>
private void SetOutFolderPath()
{
    videoOutFolder = GetFolder(outputFolderType, outputFolderPath);

    if (!Directory.Exists(videoOutFolder))
        Directory.CreateDirectory(videoOutFolder);
    _movieCapture.OutputFolderPath = videoOutFolder;
}

/// <summary>
/// 设置视频画质
/// </summary>
private void SetDownScale()
{
    _movieCapture.ResolutionDownScale = downScale;
}

/// <summary>
/// 设置帧率
/// </summary>
private void SetFrameRate()
{
    _movieCapture.FrameRate = frame;

}

/// <summary>
/// 设置文件前缀
/// </summary>
private void SetPrefix()
{
    _movieCapture.FilenamePrefix = prefix;
}

三、实现Game视图屏幕捕捉功能

1、屏幕捕捉功能

在导入包后就可以进行屏幕录制功能开发,包含开始录频、结束录频、查看最近录制,同时在录制的过程中也能够看到当前当前录制视频的大小和时长。

csharp 复制代码
 private long _lastFileSize;
 private uint _lastEncodedMinutes;
 private uint _lastEncodedSeconds;
 private uint _lastEncodedFrame;

 private StringBuilder _fileSize = new StringBuilder();
 private StringBuilder _videoLength = new StringBuilder();
 
 /// <summary>
 /// 开始录制
 /// </summary>
 private void StartCapture()
 {
     _lastFileSize = 0;
     _lastEncodedMinutes = _lastEncodedSeconds = _lastEncodedFrame = 0;
     if (_movieCapture != null)
     {
         _movieCapture.StartCapture();
         startRecord.interactable = false;
         stopRecord.interactable = true;
     }
 }

 /// <summary>
 /// 停止录制
 /// </summary>
 private void StopCapture()
 {
     if (_movieCapture != null)
     {
         if (_movieCapture.IsCapturing())
         {
             _movieCapture.StopCapture();
             startRecord.interactable = true;
             stopRecord.interactable = false;
         }
     }
 }

 /// <summary>
 /// 文件大小设置
 /// </summary>
 /// <param name="lastFileSize"></param>
 private void FileSize()
 {
     _lastFileSize = _movieCapture.GetCaptureFileSize();

     _fileSize.Clear();
     _fileSize.Append((_lastFileSize / (1024f * 1024f)).ToString("F1"));
     _fileSize.Append("MB");
 }

 /// <summary>
 /// 视频长度设置
 /// </summary>
 private void VideoLength()
 {
     if (!_movieCapture.IsRealTime)
     {
         _lastEncodedSeconds = (uint)Mathf.FloorToInt(_movieCapture.CaptureStats.NumEncodedFrames / _movieCapture.FrameRate);
     }
     else
     {
         _lastEncodedSeconds = _movieCapture.CaptureStats.TotalEncodedSeconds;
     }

     _lastEncodedMinutes = _lastEncodedSeconds / 60;
     _lastEncodedSeconds = _lastEncodedSeconds % 60;
     _lastEncodedFrame = _movieCapture.CaptureStats.NumEncodedFrames % (uint)_movieCapture.FrameRate;

     _videoLength.Clear();

     _videoLength.Append(_lastEncodedMinutes.ToString("00"));
     _videoLength.Append(":");
     _videoLength.Append(_lastEncodedSeconds.ToString("00"));
     _videoLength.Append(".");
     _videoLength.Append(_lastEncodedFrame.ToString("000"));
 }
 
  • 开始录制: 开始进行Game视图录制
  • 结束录制: 结束录制,录制结束后,视频会进进行保存
  • 最新录制: 显示最近录制的视频记录
  • File Size: 当前录制视频的文件大小
  • Video Length: 当前录制视频的时长

2、视频列表功能

在视频录制完成后,会将视频信息进行保存,当点击最新录制会显示视频列表窗口,在这里你可以找到所有的最近录制的视频记录。

csharp 复制代码
public class RecordList : MonoBehaviour
{
    public RecordItem recordItemPre;
    private List<RecordItem> records = new List<RecordItem>();

    /// <summary>
    /// 初始化记录表
    /// </summary>
    /// <param name="saveInfos"></param>
    public void InitRecordList(List<VideoInfo> videoList)
    {
        gameObject.SetActive(true);

        for (int i = 0; i < records.Count; i++)
        {
            Destroy(records[i].gameObject);
        }

        records.Clear();

        for (int i = 0; i < videoList.Count; i++)
        {
            RecordItem recordItem = Instantiate(recordItemPre, recordItemPre.transform.parent);
            recordItem.InitRecordItem(videoList[i]);
            records.Add(recordItem);
            recordItem.gameObject.SetActive(true);
        }
    }
}
csharp 复制代码
 public class RecordItem : MonoBehaviour
 {
     public Text videoName;
     public Text videoSize;
     public Text videoLength;
     public Text lastModifyTime;
     public Button view;
     public VideoControl videoControl;
     private VideoInfo videoInfo;

     // Start is called before the first frame update
     void Start()
     {
         view.onClick.AddListener(() => {
             videoControl.VideoControlInit(videoInfo.videoPath);
         });
     }

     /// <summary>
     /// 初始化记录表
     /// </summary>
     /// <param name="saveInfo"></param>
     public void InitRecordItem(VideoInfo videoInfo)
     {
         this.videoInfo = videoInfo;
         videoName.text = videoInfo.videoName;
         videoSize.text = (videoInfo.videoSize / (1024f * 1024f)).ToString("F1") + "MB";
         videoLength.text = (videoInfo.videoLength / 60).ToString("00") + ":" + (videoInfo.videoLength % 60).ToString("00");
         lastModifyTime.text = videoInfo.lastModifyTime;
     }
 }
  • 名称: 视频名称
  • 大小: 视频文件大小
  • 时长: 视频时长
  • 最后修改: 视频保存时间
  • 查看: 播放视频

3、视频播放功能

在视频列表中,点击查看按钮就可以播放该视频。

csharp 复制代码
public class VideoControl : MonoBehaviour
{
    public Text title;
    public VideoPlayer player;
    public Slider videoSlider;
    public Button close;
    public Text videotime;
    public Text videoLength;

    string videoPath;

    private void Update()
    {
        if (player.isPlaying)
        {
            SetCurPlayTime();
            SetPlaySchedule();
        }
    }

    private void Awake()
    {
        player.prepareCompleted += OnPrepareCompleted;
    }

    private void OnDestroy()
    {
        player.prepareCompleted -= OnPrepareCompleted;
    }

    public void VideoControlInit(string videoPath)
    {
        this.videoPath = videoPath;

        gameObject.SetActive(true);
        SetVideoPlayPath(videoPath);
        PlayVideo();
    }

    /// <summary>
    /// 视频准备
    /// </summary>
    /// <param name="videoSource"></param>
    private void OnPrepareCompleted(VideoPlayer videoSource)
    {
        SetVideoName();
        SetVideoLength();
    }

    /// <summary>
    /// 设置视频名称
    /// </summary>
    private void SetVideoName()
    {
        title.text = Path.GetFileNameWithoutExtension(videoPath);
    }

    /// <summary>
    /// 设置播放器路径
    /// </summary>
    /// <param name="path"></param>
    public void SetVideoPlayPath(string path)
    {
        player.url = path;
    }

    /// <summary>
    /// 当前视频播放时间
    /// </summary>
    private void SetCurPlayTime()
    {
        videotime.text = TimeProcess(player.time);
    }

    /// <summary>
    /// 设置视频时长
    /// </summary>
    /// <param name="length"></param>
    private void SetVideoLength()
    {
        videoLength.text = TimeProcess(player.length);
    }

    /// <summary>
    /// 设置播放进度
    /// </summary>
    private void SetPlaySchedule()
    {
        videoSlider.value = (float)player.frame / player.frameCount;
    }

    /// <summary>
    /// 时间处理
    /// </summary>
    /// <param name="time"></param>
    /// <returns></returns>
    private string TimeProcess(double time)
    {
        int minutes = (int)time / 60;
        int seconds = (int)time % 60;
        return minutes.ToString("00") + ":" + seconds.ToString("00");
    }

    /// <summary>
    /// 视频播放
    /// </summary>
    public void PlayVideo()
    {
        player.Play();
    }
}

视频播放时,会显示视频名称、时长、当前时间和播放进度


四、MovieCapture项目地址

项目完整地址:

https://gitcode.com/CTLittleNewbie/ScreenRecord_240520/


|-----------------------------------------------|
| TechX ------ 心探索、心进取! 每一次跌倒都是一次成长 每一次努力都是一次进步 |


END 感谢您阅读本篇博客!希望这篇内容对您有所帮助。如果您有任何问题或意见,或者想要了解更多关于本主题的信息,欢迎在评论区留言与我交流。我会非常乐意与大家讨论和分享更多有趣的内容。
如果您喜欢本博客,请点赞和分享给更多的朋友,让更多人受益。同时,您也可以关注我的博客,以便及时获取最新的更新和文章。
在未来的写作中,我将继续努力,分享更多有趣、实用的内容。再次感谢大家的支持和鼓励,期待与您在下一篇博客再见!

相关推荐
南無忘码至尊2 小时前
Unity学习90天 - 第 6 天 -学习物理 Material + 重力与阻力并实现弹跳球和冰面滑动效果
学习·unity·游戏引擎
mxwin4 小时前
Unity 单通道立体渲染(Single Pass Instanced)对 Shader 顶点布局的特殊要求
unity·游戏引擎·shader
魔士于安6 小时前
unity 低多边形 无人小村 木质建筑 晾衣架 盆子手推车,桌子椅子,罐子,水井
游戏·unity·游戏引擎·贴图·模型
RReality7 小时前
【Unity Shader URP】简易卡通着色(Simple Toon)实战教程
ui·unity·游戏引擎·图形渲染·材质
魔士于安7 小时前
unity 骷髅人 连招 武器 刀光 扭曲空气
游戏·unity·游戏引擎·贴图·模型
洛阳吕工9 小时前
从 micro-ROS 到 px4_ros2:ROS2 无人机集成开发实战指南
游戏引擎·无人机·cocos2d
风酥糖10 小时前
Godot游戏练习01-第29节-游戏导出
游戏·游戏引擎·godot
瑞瑞小安10 小时前
Unity功能篇:文本框随文字内容动态调整
ui·unity
南無忘码至尊10 小时前
Unity学习90天-第7天-学习委托与事件(简化版)
学习·unity·游戏引擎
君莫愁。10 小时前
【Unity】解决UGUI的Button无法点击/点击无反应的排查方案
unity·c#·游戏引擎·解决方案·ugui·按钮·button