当前位置:   article > 正文

unity PC端 调用FFmpeg生成视频 unity序列帧合成视频_unity ffmpeg合成视频

unity ffmpeg合成视频

两个脚本  一个需要挂载 

FFmpeg软件在下面链接下载   需要放到streamingAsset\ffmpeg文件夹下

下面再出一个安卓调用FFmpeg生成视频的博客

  1. using System.Collections;
  2. using System.Diagnostics;
  3. using System.IO;
  4. using UnityEngine;
  5. public class CreatVideos : MonoBehaviour
  6. {
  7. private string imagePath;
  8. private string ffmpegPath;
  9. private string videoPath;
  10. // Use this for initialization
  11. void Start()
  12. {
  13. Loom.Initialize();
  14. imagePath = GameManager.imgffpath + "/";
  15. ffmpegPath = @Application.streamingAssetsPath + "/ffmpeg/ffmpeg.exe";
  16. videoPath = @Application.streamingAssetsPath + "/视频.mp4";
  17. }
  18. public void CreatVideo()
  19. {
  20. print("开始渲染");
  21. print(imagePath);
  22. print(videoPath);
  23. if (File.Exists(videoPath))
  24. {
  25. File.Delete(videoPath);
  26. }
  27. Loom.RunAsync(() =>
  28. {
  29. //建立外部调用进程
  30. Process p = new Process();
  31. p.StartInfo.FileName = ffmpegPath;
  32. string args = "-f image2 -framerate 12 -i " + imagePath + "%05d.jpg -vcodec libx264 -r 25 " + videoPath;
  33. //%05d是指图片名称00000 00001 00002 如果是1,2,3用%01d
  34. p.StartInfo.Arguments = args;
  35. p.StartInfo.UseShellExecute = false;//不使用操作系统外壳程序启动线程(一定为FALSE,详细的请看MSDN)
  36. p.StartInfo.RedirectStandardError = true;//把外部程序错误输出写到StandardError流中(这个一定要注意,FFMPEG的所有输出信息,都为错误输出流,用StandardOutput是捕获不到任何消息的...)
  37. p.StartInfo.CreateNoWindow = true;//不创建进程窗口
  38. p.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
  39. p.Start();//启动线程
  40. p.BeginErrorReadLine();//开始异步读取
  41. p.WaitForExit();//阻塞等待进程结束
  42. p.Close();//关闭进程
  43. p.Dispose();//释放资源
  44. });
  45. }
  46. private void Output(object sendProcess, DataReceivedEventArgs output)
  47. {
  48. if (!string.IsNullOrEmpty(output.Data))
  49. {
  50. //处理方法...
  51. UnityEngine.Debug.Log(output.Data);
  52. }
  53. }
  54. }

下面的不需要挂载

  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. using System;
  4. using System.Threading;
  5. using System.Linq;
  6. /// <summary>
  7. /// 多线程
  8. /// </summary>
  9. public class Loom : MonoBehaviour
  10. {
  11. public static int maxThreads = 8;
  12. static int numThreads;
  13. private static Loom _current;
  14. public static Loom Current
  15. {
  16. get
  17. {
  18. Initialize();
  19. return _current;
  20. }
  21. }
  22. //####去除Awake
  23. // void Awake()
  24. // {
  25. // _current = this;
  26. // initialized = true;
  27. // }
  28. static bool initialized;
  29. /// <summary>
  30. /// ####作为初始化方法自己调用,可在初始化场景调用一次即可
  31. /// </summary>
  32. public static void Initialize()
  33. {
  34. if (!initialized)
  35. {
  36. if (!Application.isPlaying)
  37. return;
  38. initialized = true;
  39. GameObject g = new GameObject("Loom");
  40. //####永不销毁
  41. DontDestroyOnLoad(g);
  42. _current = g.AddComponent<Loom>();
  43. }
  44. }
  45. private List<Action> _actions = new List<Action>();
  46. public struct DelayedQueueItem
  47. {
  48. public float time;
  49. public Action action;
  50. }
  51. private List<DelayedQueueItem> _delayed = new List<DelayedQueueItem>();
  52. List<DelayedQueueItem> _currentDelayed = new List<DelayedQueueItem>();
  53. /// <summary>
  54. /// 在主线程中运行
  55. /// </summary>
  56. /// <param name="action"></param>
  57. public static void QueueOnMainThread(Action action)
  58. {
  59. QueueOnMainThread(action, 0f);
  60. }
  61. public static void QueueOnMainThread(Action action, float time)
  62. {
  63. if (time != 0)
  64. {
  65. if (Current != null)
  66. {
  67. lock (Current._delayed)
  68. {
  69. Current._delayed.Add(new DelayedQueueItem { time = Time.time + time, action = action });
  70. }
  71. }
  72. }
  73. else
  74. {
  75. if (Current != null)
  76. {
  77. lock (Current._actions)
  78. {
  79. Current._actions.Add(action);
  80. }
  81. }
  82. }
  83. }
  84. public static Thread RunAsync(Action a)
  85. {
  86. Initialize();
  87. while (numThreads >= maxThreads)
  88. {
  89. Thread.Sleep(1);
  90. }
  91. Interlocked.Increment(ref numThreads);
  92. ThreadPool.QueueUserWorkItem(RunAction, a);
  93. return null;
  94. }
  95. private static void RunAction(object action)
  96. {
  97. try
  98. {
  99. ((Action)action)();
  100. }
  101. catch
  102. {
  103. }
  104. finally
  105. {
  106. Interlocked.Decrement(ref numThreads);
  107. }
  108. }
  109. void OnDisable()
  110. {
  111. if (_current == this)
  112. {
  113. _current = null;
  114. }
  115. }
  116. // Use this for initialization
  117. void Start()
  118. {
  119. }
  120. List<Action> _currentActions = new List<Action>();
  121. // Update is called once per frame
  122. void Update()
  123. {
  124. lock (_actions)
  125. {
  126. _currentActions.Clear();
  127. _currentActions.AddRange(_actions);
  128. _actions.Clear();
  129. }
  130. foreach (var a in _currentActions)
  131. {
  132. a();
  133. }
  134. lock (_delayed)
  135. {
  136. _currentDelayed.Clear();
  137. _currentDelayed.AddRange(_delayed.Where(d => d.time <= Time.time));
  138. foreach (var item in _currentDelayed)
  139. _delayed.Remove(item);
  140. }
  141. foreach (var delayed in _currentDelayed)
  142. {
  143. delayed.action();
  144. }
  145. }
  146. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/138463
推荐阅读
相关标签
  

闽ICP备14008679号