You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

259 lines
8.4 KiB

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FFmpegOut;
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using UnityEngine.UI;
using System.Linq;
[RequireComponent(typeof(CameraCapture))]
[RequireComponent(typeof(AudioListenerRecorder))]
public class MovieRecorder : MonoBehaviour {
//the most important is FPS ,take care if u do not want the mistake what happen to the audio and capture is not have synchronization
private CameraCapture cameraCapture;
private AudioListenerRecorder audioListenerRecord;
private bool recording;
public bool IsRecord { get { return recording; } }
#region Editable properties
[SerializeField]
private string fileName;
[SerializeField]
FFmpegPipe.Codec _codec;
[SerializeField]
public SaveAudio.Savetype saveAudioType;
[SerializeField]
private float RecordTime;
[SerializeField]
private bool reservedOriginal;
#endregion
private float StartRecordTime;
public delegate void RecordFinished();
public static event RecordFinished FinishedEvent;
#region UI
[SerializeField]
private RectTransform UIPanel;
[SerializeField]
private Text InputFileName;
[SerializeField]
private Text uiRecordTime;
[SerializeField]
private Toggle recordToggle;
[SerializeField]
private Dropdown mediaTypeDrop;
[SerializeField]
private Dropdown audioTypeDrop;
[SerializeField]
private Text InputWidth;
[SerializeField]
private Text InputHeight;
public string InputfileName { set { fileName = value; } }
private bool enableUI = false;
#endregion
void Awake()
{
cameraCapture = GetComponent<CameraCapture>();
audioListenerRecord = GetComponent<AudioListenerRecorder>();
if(UIPanel == null)
{
UIPanel = GameObject.Find("RecordUICanvas").transform.Find("Panel").GetComponent<RectTransform>();
}
if(UIPanel != null)
{
InputFileName = UIPanel.transform.Find("FileName").Find("InputField").GetComponent<InputField>().textComponent;
uiRecordTime = UIPanel.transform.Find("RecordTime").GetChild(0).GetComponent<Text>();
recordToggle = UIPanel.transform.Find("RecordToggle").GetComponent<Toggle>();
mediaTypeDrop = UIPanel.transform.Find("MediaTypeDropdown").GetComponent<Dropdown>();
audioTypeDrop = UIPanel.transform.Find("AudioTypeDropdown").GetComponent<Dropdown>();
InputWidth = UIPanel.transform.Find("width").Find("InputField").GetComponent<InputField>().textComponent;
InputHeight = UIPanel.transform.Find("height").Find("InputField").GetComponent<InputField>().textComponent;
enableUI = false;
List<Dropdown.OptionData> mediaTypeOptions = new List<Dropdown.OptionData>();
for (int i=0;i< (int)Enum.GetValues(typeof(FFmpegPipe.Codec)).Cast<FFmpegPipe.Codec>().Max() + 1;i++)
{
mediaTypeOptions.Add(new Dropdown.OptionData(((FFmpegPipe.Codec)i).ToString()));
}
mediaTypeDrop.AddOptions(mediaTypeOptions);
//mediaTypeDrop.onValueChanged.AddListener((v) => SetMediaType(v));
List<Dropdown.OptionData> audioTypeOptions = new List<Dropdown.OptionData>();
for (int i = 0; i < (int)Enum.GetValues(typeof(SaveAudio.Savetype)).Cast<SaveAudio.Savetype>().Max()+1; i++)
{
audioTypeOptions.Add(new Dropdown.OptionData(((SaveAudio.Savetype)i).ToString()));
}
audioTypeDrop.AddOptions(audioTypeOptions);
//audioTypeDrop.onValueChanged.AddListener((v) => SetAudioType(v));
}
UIPanel.gameObject.SetActive(enableUI);
}
// Use this for initialization
void Start () {
recording = false;
FinishedEvent += ShowReocrdTime;
}
// Update is called once per frame
void Update () {
if(Input.GetKeyDown(KeyCode.R))
{
if(!recording)
{
fileName = DateTime.Now.ToString("yyyy-MMdd-HHmmss");
StartRecord(fileName);
}
else
{
StopRecord();
}
}
if (Input.GetKeyDown(KeyCode.F2))
{
enableUI = !enableUI;
UIPanel.gameObject.SetActive(enableUI);
}
if (recording)
{
CountRecordTime();
}
if(enableUI)
{
recordToggle.isOn = recording;
uiRecordTime.text = RecordTime.ToString();
}
}
void CountRecordTime()
{
RecordTime = Time.time - StartRecordTime;
}
public void StartRecord(string filename)
{
if (recording)
return;
fileName = filename;
StartRecord();
}
public void StartRecord()
{
if (recording)
return;
if (enableUI)
{
fileName = InputFileName.text;
if(fileName == null || fileName == "")
fileName = DateTime.Now.ToString("yyyy-MMdd-HHmmss");
SetMediaType(mediaTypeDrop.value);
SetAudioType(audioTypeDrop.value);
int width;
int height;
if (Int32.TryParse(InputWidth.text, out width) && Int32.TryParse(InputHeight.text, out height))
{
cameraCapture.SetResolution(width, height);
}
}
recording = true;
cameraCapture._codec = _codec;
audioListenerRecord.saveAudioType = saveAudioType;
cameraCapture.StartCapture("Tempmovie" + fileName);
audioListenerRecord.StartRecord("Tempaudio" + fileName);
StartRecordTime = Time.time;
}
public void StopRecord()
{
if (!recording)
return;
CountRecordTime();
cameraCapture.StopCapture();
audioListenerRecord.StopRecord();
StartCoroutine(StartCombine());
recording = false;
}
public void SetMediaType(int i)
{
_codec = (FFmpegPipe.Codec)i;
}
public void SetAudioType(int i)
{
saveAudioType = (SaveAudio.Savetype)i;
}
IEnumerator StartCombine()
{
yield return new WaitForSeconds(0.5f);
string Arguments = "-i " + "Tempmovie" + fileName + FFmpegPipe.GetSuffix(_codec) +
" -i " + "Tempaudio" + fileName + "." + audioListenerRecord.saveAudioType.ToString() +
" -c copy -map 0:0 -map 1:0 -ar " + audioListenerRecord.outputRate.ToString() + " " + fileName + FFmpegPipe.GetSuffix(_codec);
if (_codec == FFmpegPipe.Codec.H264 && audioListenerRecord.saveAudioType == SaveAudio.Savetype.wav)
Arguments = "-i " + "Tempmovie" + fileName + FFmpegPipe.GetSuffix(_codec) +
" -i " + "Tempaudio" + fileName + "." + audioListenerRecord.saveAudioType.ToString() +
" -c copy -map 0:0 -map 1:0 -acodec mp3 -vcodec copy -ar " + audioListenerRecord.outputRate.ToString() + " " + fileName + FFmpegPipe.GetSuffix(_codec);
yield return ExcuteProcess(FFmpegConfig.BinaryPath, Arguments, (s, e) => print(e.Data));
if (!reservedOriginal)
{
File.Delete(Application.dataPath + "/../Tempmovie" + fileName + FFmpegPipe.GetSuffix(_codec));
File.Delete(Application.dataPath + "/../Tempaudio" + fileName + "." +audioListenerRecord.saveAudioType.ToString());
}
if (FinishedEvent != null)
FinishedEvent();
}
void ShowReocrdTime()
{
print("RecordTime:" + RecordTime);
}
IEnumerator ExcuteProcess(string fileName, string arg, DataReceivedEventHandler output)
{
Thread WriteThread = new Thread(() => _ExcuteProcess(fileName, arg, output));
WriteThread.Start();
while (WriteThread.IsAlive)
yield return null;
}
void _ExcuteProcess(string fileName, string arg, DataReceivedEventHandler output)
{
using (var p = new Process())
{
p.StartInfo.FileName = fileName;
p.StartInfo.Arguments = arg;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardOutput = true;
p.OutputDataReceived += output;
p.ErrorDataReceived += output;
p.Start();
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.WaitForExit();
}
}
}