简单介绍
NatCorder 是一个轻量级且易于使用的全功能视频录制 API,适用于 iOS、Android、macOS 和 Windows。借助 NatCorder,您可以录制屏幕、指定的游戏视角、纹理、原始像素数据等。您还可以录制来自音频源、录音器和自定义源的游戏音频。NatCorder 经过大量优化以提高速度,并降低内存占用。
功能包括:
- 超速性能。NatCorder 专为性能进行了大量优化设计。
- 录制任何内容!录制所有可以渲染到纹理中的内容。无论是游戏视角、用户界面、摄像头还是纹理,NatCorder 都可以录制下来。
- 自定义分辨率。以高达全高清 (1920x1080) 的分辨率进行录制,甚至在设备支持的情况下以更高的分辨率进行录制。
- 控制质量。通过指定录制比特率和关键帧间隔,在文件大小或带宽方面对录制进行优化。
- 录制GIF。除了录制 MP4 视频外,NatCorder 还可以在 iOS、Android、macOS 和 Windows 上录制 GIF 动画图像。
- 录制HEVC。NatCorder 支持在 Android、iOS、macOS 和 Windows 上使用 H.265 HEVC 编解码器进行录制。
- 支持AR。NatCorder 完全支持 ARFoundation、ARCore、ARKit 和 Vuforia。
- 完全访问权限。NatCorder 将直接录制到应用程序文档目录中,并提供视频的路径。
- 离线录制。NatCorder 支持在 for 循环中进行录制。这对于转码应用程序非常实用。
- 线程录制。NatCorder 具有线程安全性,让您能够在工作线程中进行录制以进一步提高性能。
- 轻量级打包。该 API 经过专门设计,不会在你的项目中增加不必要的负担或开销。
要求:
- Unity 2018.3+
- Android API 21 级以上
- iOS 11+
- macOS 10.13+
- Windows 10+,仅限 64 位
插件下载
- Unity Asset Store:https://assetstore.unity.com/packages/tools/integration/natcorder-video-recording-api-102645
- CSDN下载地址(可能不是最新版本,但符合下面我要介绍的使用方式):https://download.csdn.net/download/f_957995490/13123314
使用简介
先来看看使用该插件的核心代码(也是我所使用的部分),便是下面的这四行:
RealtimeClock m_clock = new RealtimeClock();
MP4Recorder m_recorder = new MP4Recorder(m_videoWidth, m_videoHeight, 100, m_sampleRate, m_channelCount);//创建录制
CameraInput m_cameraInput = new CameraInput(m_recorder, m_clock, m_recordCamera);//创建画面输入
AudioInput m_audioInput = new AudioInput(m_recorder, m_clock, m_microphoneSource, true);//创建声音输入
分别是创建四个对象,分别是RealtimeClock
一个实时的时钟、MP4Recorder
MP4录制对象、CameraInput
图像输入、AudioInput
声音输入。
此外,在插件中有3个示例场景,分别是录制GIF的Giffy、录制场景中Camera的ReplayCam、录制摄像头的WebCam。其中后面两个都是使用MP4Recorder
对象进行录制,只有GIF使用的是专门的录制对象GIFRecorder
类。GIFRecorder
类的用法与上面列出的MP4Recorder
相同,因为功能要求,我没有尝试,有需要的可以自行测试。
在录制完成之后,需要调用以下代码:
m_audioInput.Dispose();//声音输入停止
m_cameraInput.Dispose();//画面输入停止
string m_resultPath = await m_recorder.FinishWriting();//录制完成写入并保存
代码
一下是我项目中用的代码RecordManager
一个单例管理者。其中还包括了麦克风唤醒代码。为大家提供参考,也欢迎指正错误。
using NatSuite.Recorders;
using NatSuite.Recorders.Clocks;
using NatSuite.Recorders.Inputs;
using System.Collections;
using System.IO;
using UnityEngine;
public class RecordManager
{
private RecordManager()
{
m_videoWidth = Screen.width;
m_videoHeight = Screen.height;
m_recordMicrophone = false;
m_sampleRate = m_channelCount = 0;
m_recordCamera = Camera.main;
m_microphoneSource = m_recordCamera.gameObject.AddComponent<AudioSource>();
}
private static RecordManager m_instance = null;
public static RecordManager GetInstance()
{
if ( null == m_instance )
{
m_instance = new RecordManager();
}
return m_instance;
}
/// <summary>
/// 视频的宽和长
/// </summary>
private readonly int m_videoWidth, m_videoHeight;
/// <summary>
/// 实时时钟
/// </summary>
private RealtimeClock m_clock = null;
/// <summary>
/// 是否录制麦克风
/// </summary>
private bool m_recordMicrophone;
/// <summary>
/// 音频采样率
/// </summary>
private int m_sampleRate;
/// <summary>
/// 音频通道数
/// </summary>
private int m_channelCount;
/// <summary>
/// 录制对象
/// </summary>
private IMediaRecorder m_recorder = null;
/// <summary>
/// 画面输入
/// </summary>
private CameraInput m_cameraInput = null;
/// <summary>
/// 录制的摄像机
/// </summary>
private readonly Camera m_recordCamera = null;
/// <summary>
/// 音源输入
/// </summary>
private AudioInput m_audioInput = null;
/// <summary>
/// 麦克风音源
/// </summary>
private readonly AudioSource m_microphoneSource = null;
/// <summary>
/// 结果地址
/// </summary>
private string m_resultPath;
/// <summary>
/// 开始麦克风
/// </summary>
/// <returns>协程</returns>
public IEnumerator StartMicrophone()
{
m_microphoneSource.mute = m_microphoneSource.loop = m_recordMicrophone = true;
m_microphoneSource.bypassEffects = m_microphoneSource.bypassListenerEffects = false;
m_sampleRate = AudioSettings.outputSampleRate;
m_channelCount = (int)AudioSettings.speakerMode;
m_microphoneSource.clip = Microphone.Start(null, true, 10, AudioSettings.outputSampleRate);//开启麦克风
yield return new WaitUntil(() => Microphone.GetPosition(null) > 0);
m_microphoneSource.Play();
}
/// <summary>
/// 关闭麦克风
/// </summary>
public void StopMicrophone()
{
Microphone.End(null);//关闭麦克风
}
/// <summary>
/// 开始录制
/// </summary>
public void StartRecording()
{
m_clock = new RealtimeClock();
m_recorder = new MP4Recorder(m_videoWidth, m_videoHeight, 100, m_sampleRate, m_channelCount);//创建录制
m_cameraInput = new CameraInput(m_recorder, m_clock, m_recordCamera);//创建画面输入
if (m_recordMicrophone)
{//是否录制麦克风
m_audioInput = new AudioInput(m_recorder, m_clock, m_microphoneSource, true);//创建声音输入
m_microphoneSource.mute = false;
//m_microphoneSource.Play();//播放音源
}
}
/// <summary>
/// 停止录制
/// </summary>
public async void StopRecording()
{
if (m_recordMicrophone)
{//是否录制麦克风
m_microphoneSource.mute = true;
//m_microphoneSource.Stop();//停止音源
m_audioInput.Dispose();//声音输入停止
}
m_cameraInput.Dispose();//画面输入停止
m_resultPath = await m_recorder.FinishWriting();//录制完成写入并保存
Debug.Log($"Saved recording to: {m_resultPath}");
Handheld.PlayFullScreenMovie($"file://{m_resultPath}");//回放
}
public void SaveRecording()
{
}
/// <summary>
/// 移除录制结果
/// </summary>
public void RemoveRecording()
{
if (File.Exists(m_resultPath))
{
File.Delete(m_resultPath);
}
}
}