close

P.S.1.或許有其他錄影的方式,只是我沒找到而已...

P.S.2.此方法無法錄製聲音!必須另外錄製聲音後,利用ffmpeg將影片和聲音合併,這部分以後會在另做篇教學

Unity沒有錄影功能,所以需要使用ffmpeg將截取下來的多張圖片合併成一個影片

截圖方法可以看這篇

ffmpeg用於Unity部分則是參考這篇

此方法目前只適用於Windows,Android部分則需要自行去編譯原始碼並使用同樣的方法完成,或者改用Everyplay

 

下載static版並解壓縮

 

 

Unity建立一個新專案

 

將剛剛解壓縮的ffmepg檔案bin\ffmpeg.exe放到Unity專案內(若將Unity專案編譯成執行檔,則同樣要把ffmpeg.exe放到編譯出來的執行檔資料夾下)

 

在場景中央放個Cube,同時為了明顯看出有在轉動所以將Cube進行放大和傾斜

 

建立一個C# Script,並命名為Test.cs


using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Threading;
using UnityEngine;

public class Test : MonoBehaviour
{
    public GameObject cube;
    private Thread t;
    private string fileName = "pic";//檔案名稱
    private string filePath = "D:/Test";//pic檔案儲存路徑
    private string fileExtension = ".png";//pic副檔名
    private string ffmpegPath;//ffmpeg.exe路徑
    private string videoOutput = "D:/video.mp4";
    private int fileCount = 1;//文件數量,從1開始
    private bool isGetPicture = true;//判斷當前圖片是否儲存完畢
    private bool imgToVideo = false;//判斷是否要開始製作影片

    private void Start()
    {
        ffmpegPath = Application.dataPath;
    }

    private void Update()
    {
        cube.transform.Rotate(new Vector3(0, 5, 0));

        if (imgToVideo == false && isGetPicture == true)
        {
            isGetPicture = false;
            StartCoroutine(GetPicture());
        }
        else if (imgToVideo == true)
        {
            isGetPicture = false;
            imgToVideo = false;
            t = new Thread(Run);
            t.Start();
        }
    }

    private void OnGUI()
    {
        if (GUILayout.Button("ImgToVideo"))
            imgToVideo = true;
    }

    private IEnumerator GetPicture()
    {
        yield return new WaitForEndOfFrame();

        //ffmpeg的image轉video要求圖片長寬接為偶數
        int newW = Screen.width % 2 == 0 ? Screen.width : Screen.width - 1;
        int newH = Screen.height % 2 == 0 ? Screen.height : Screen.height - 1;

        Texture2D t2d = new Texture2D(newW, newH);
        t2d.ReadPixels(new Rect(0, 0, newW, newH), 0, 0, true);

        //若資料夾不存在則創建資料夾
        if (!Directory.Exists(filePath))
            Directory.CreateDirectory(filePath);

        using (FileStream fs = new FileStream(filePath + "/" + fileName + fileCount + fileExtension, FileMode.Create))
        {
            BinaryWriter bw = new BinaryWriter(fs);
            bw.Write(t2d.EncodeToPNG());
        }
        fileCount++;
        Destroy(t2d);

        isGetPicture = true;
    }

    private void Run()
    {
        using (Process p = new Process())
        {
            p.StartInfo.FileName = ffmpegPath + "/ffmpeg.exe";//ffmpeg 路徑 & 檔案 名稱
            p.StartInfo.Arguments = "-i " + filePath + "/" + fileName + "%d"+ fileExtension +" -c:v libx264 -r 30 -pix_fmt yuv420p " + videoOutput;//ffmpeg的image to video指令,詳情請參考ffmpeg官網

            p.StartInfo.UseShellExecute = false;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardOutput = true;

            p.Start();
            p.BeginOutputReadLine();
            p.BeginErrorReadLine();
            p.WaitForExit();
            p.CloseMainWindow();
            p.Close();
        }
    }

    private void OnDisable()
    {
        UnityEngine.Debug.Log("離開場景,關閉所有任務");
        isGetPicture = false;
        imgToVideo = false;
        t.Abort();
    }
}


完成後將程式碼拉到任一元件上(我放到Camera上)、放置要旋轉Cube,按下執行就會立刻截圖,按下imgToVideo後停止截圖,並將剛剛截取的圖片製作成mp4檔。

 

 

成為影片檔了↓↓↓↓↓↓

arrow
arrow
    全站熱搜

    Yang 發表在 痞客邦 留言(1) 人氣()