本文介绍如何在集成Unity的iOS原生项目中截取和录制屏幕
完整代码请查看Record_Screen_In_Unity
由于Unity不熟练,不知道怎么直接在Unity里录制屏幕。查询网上的方法,基本都是采用Unity的插件录制,不过基本都是收费插件,所以我们采用曲线救国,自己制作录制脚本。
思路是首先在Unity里获取当前屏幕截图,传给native,原生使用GPUImage进行视频的合成
1. 准备工作
新建一个Unity和原生混合的工程(参考之前的文章),在主场景中放置一个白色的球,方便我们录制时验证
2. Unity端
- 获取AR摄像头采集的原始数据
使用ARCameraManager
的TryGetLatestImage
方法获取XRCameraImage
对象,再用XRCameraImageConversionParams
把数据转成需要的格式
cameraManager.TryGetLatestImage(out XRCameraImage image)
renderTexture = new Texture2D(image.width, image.height, TextureFormat.BGRA32, false);
conversionParams = new XRCameraImageConversionParams(image, TextureFormat.BGRA32, CameraImageTransformation.None);
intPtr = new IntPtr(renderTexture.GetRawTextureData<byte>().GetUnsafePtr());
var rawTextureData = renderTexture.GetRawTextureData<byte>();
try
{
image.Convert(conversionParams, intPtr, rawTextureData.Length);
}
finally
{
image.Dispose();
}
renderTexture.Apply();
NativeAPI.SendVideoData(renderTexture.GetRawTextureData(), rawTextureData.Length);
- 获取屏幕渲染结果
使用Texture2D
的ReadPixels
获取屏幕渲染结果
renderTexture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
renderTexture.Apply();
byte[] rawData = renderTexture.GetRawTextureData();
NativeAPI.SendVideoData(rawData, rawData.Length);
3. Native端
使用GPUImageRawDataInput
作为输入,GPUImageMovieWriter
作为输出
摄像头数据是旋转的,添加GPUImageTransformFilter
旋转回来
如果不是录制全屏,添加GPUImageCropFilter
截取屏幕的某一部分
注意:
初始化GPUImageMovieWriter注意宽高需要是16的倍数,否则会有黑边
4. 音频录制
通过OnAudioFilterRead(float[] data, int channels)
采集unity的声音传给Native端,在Native端将音频数据转为CMSampleBuffer
塞入GPUImage
Unity设置的音频采样率要和Native端统一
AudioSettings.outputSampleRate = 44100;
注意:
OnAudioFilterRead
方法只有在添加了AudioSource
组件后才会回调,并且AudioSource的playOnAwake
需要为false
完整代码请查看Record_Screen_In_Unity