用unity写一个录制屏幕和麦克风的脚本
时间: 2023-05-18 08:06:04 浏览: 107
录制屏幕和声音
4星 · 用户满意度95%
可以使用Unity自带的ScreenCapture和Microphone类来实现录制屏幕和麦克风的功能。以下是一个简单的示例代码:
```
using UnityEngine;
using System.Collections;
using System.IO;
public class Recorder : MonoBehaviour {
public int frameRate = 30;
public int width = 1920;
public int height = 1080;
public string outputPath = "output.mp4";
private bool isRecording = false;
private float startTime;
private string tempPath;
void Start () {
tempPath = Path.Combine(Application.temporaryCachePath, "temp.mp4");
}
void Update () {
if (Input.GetKeyDown(KeyCode.R)) {
if (!isRecording) {
StartRecording();
} else {
StopRecording();
}
}
}
void StartRecording () {
isRecording = true;
startTime = Time.time;
Screen.SetResolution(width, height, false);
Application.targetFrameRate = frameRate;
Microphone.Start(null, true, 10, AudioSettings.outputSampleRate);
}
void StopRecording () {
isRecording = false;
Screen.SetResolution(Screen.currentResolution.width, Screen.currentResolution.height, true);
Application.targetFrameRate = -1;
Microphone.End(null);
StartCoroutine(EncodeVideo());
}
IEnumerator EncodeVideo () {
yield return new WaitForEndOfFrame();
var audioClip = Microphone.GetClip(null, false);
var videoEncoder = new VideoEncoder(tempPath, width, height, frameRate);
var audioEncoder = new AudioEncoder(tempPath, audioClip);
var videoThread = new System.Threading.Thread(videoEncoder.Encode);
var audioThread = new System.Threading.Thread(audioEncoder.Encode);
videoThread.Start();
audioThread.Start();
videoThread.Join();
audioThread.Join();
File.Move(tempPath, outputPath);
Debug.Log("Video saved to " + outputPath);
}
}
public class VideoEncoder {
private string outputPath;
private int width;
private int height;
private int frameRate;
public VideoEncoder (string outputPath, int width, int height, int frameRate) {
this.outputPath = outputPath;
this.width = width;
this.height = height;
this.frameRate = frameRate;
}
public void Encode () {
var args = string.Format("-y -f rawvideo -pix_fmt rgba -s {0}x{1} -r {2} -i - -c:v libx264 -preset ultrafast -crf 0 {3}", width, height, frameRate, outputPath);
var process = new System.Diagnostics.Process();
process.StartInfo.FileName = "ffmpeg";
process.StartInfo.Arguments = args;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();
var stdin = process.StandardInput.BaseStream;
var stdout = process.StandardOutput.BaseStream;
var stderr = process.StandardError.BaseStream;
var buffer = new byte[width * height * 4];
while (true) {
var time = Time.time - startTime;
if (time < 0) {
continue;
}
var frame = Mathf.FloorToInt(time * frameRate);
if (frame >= 0 && frame < maxFrames) {
var rect = new Rect(0, 0, width, height);
var tex = new Texture2D(width, height, TextureFormat.RGBA32, false);
tex.ReadPixels(rect, 0, 0);
tex.Apply();
var pixels = tex.GetRawTextureData();
stdin.Write(pixels, 0, pixels.Length);
Destroy(tex);
} else if (frame >= maxFrames) {
break;
}
}
stdin.Close();
process.WaitForExit();
Debug.Log(process.StandardError.ReadToEnd());
}
}
public class AudioEncoder {
private string outputPath;
private AudioClip audioClip;
public AudioEncoder (string outputPath, AudioClip audioClip) {
this.outputPath = outputPath;
this.audioClip = audioClip;
}
public void Encode () {
var args = string.Format("-y -f s16le -ar {0} -ac 1 -i - -c:a aac -b:a 256k {1}", audioClip.frequency, outputPath);
var process = new System.Diagnostics.Process();
process.StartInfo.FileName = "ffmpeg";
process.StartInfo.Arguments = args;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();
var stdin = process.StandardInput.BaseStream;
var stdout = process.StandardOutput.BaseStream;
var stderr = process.StandardError.BaseStream;
var buffer = new float[audioClip.samples * audioClip.channels];
audioClip.GetData(buffer, 0);
var bytes = new byte[buffer.Length * 2];
for (int i = 0; i < buffer.Length; i++) {
var sample = Mathf.Clamp01(buffer[i]);
var value = (short)(sample * 32767);
bytes[i * 2] = (byte)(value & 0xff);
bytes[i * 2 + 1] = (byte)(value >> 8);
}
stdin.Write(bytes, 0, bytes.Length);
stdin.Close();
process.WaitForExit();
Debug.Log(process.StandardError.ReadToEnd());
}
}
```
这个脚本使用了ffmpeg来编码视频和音频,需要在系统中安装ffmpeg并将其添加到环境变量中。录制视频时,可以按下R键开始/停止录制,录制完成后会保存为一个MP4文件。
阅读全文