简单易懂,直接上代码
/*********************************************
* BFramework
* FFmpeg工具
* 创建时间:2023/06/30 15:34:41
*********************************************/
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using UnityEngine;
using Debug = UnityEngine.Debug;
namespace MainPackage
{
/// <summary>
/// FFmpeg工具
/// </summary>
public static class FFmpegUtil
{
private static FFmpegInfo _ffpInfo = new FFmpegInfo();
/// <summary>
/// 视频裁剪
/// </summary>
/// <param name="startTime">开始时间</param>
/// <param name="intervalTime">裁剪时长</param>
/// <param name="inputFullPath">输入的文件全路径名</param>
/// <param name="outPath">输出的文件夹</param>
/// <param name="newVideoName">新视频的名字</param>
public static void CutVideo(int startTime, int intervalTime, string inputFullPath, string outPath = null, string newVideoName = null)
{
//常规检测
newVideoName = CheckNewVideoName(newVideoName);
CheckOutPath(outPath);
//正式执行
var outFullPath = outPath + $"/{newVideoName}.mp4";
_ffpInfo.Execute($"-i {inputFullPath} -ss {startTime} -t {intervalTime} -codec copy {outFullPath}");
}
/// <summary>
/// 检测是否有视频名
/// </summary>
private static string CheckNewVideoName(string newVideoName)
{
//视频名
if (string.IsNullOrWhiteSpace(newVideoName))
{
newVideoName = Application.productName + "_" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
}
return newVideoName;
}
/// <summary>
/// 检测是否有输出路径
/// </summary>
private static void CheckOutPath(string outPath)
{
//输出位置
if (string.IsNullOrWhiteSpace(outPath))
{
outPath = Application.persistentDataPath + "/Video";
if (!Directory.Exists(outPath))
{
Directory.CreateDirectory(outPath);
}
}
}
/// <summary>
/// 停止当前的行为
/// </summary>
public static void CloseFFmpeg()
{
_ffpInfo.CloseFFmpegProcess();
}
}
public class FFmpegInfo
{
private Process _ffp;
private string _ffpPath = Application.streamingAssetsPath + "/ffmpeg.exe";
private bool _isRunning;
/// <summary>
/// 执行FFmpeg的命令行
/// </summary>
/// <param name="cmdReadStr"></param>
/// <param name="isShowCmd"></param>
public void Execute(string cmdReadStr,bool isShowCmd = false)
{
//正在执行中
if (_isRunning)
{
Debug.LogError("视频处理正在执行中,请稍后再试!");
return;
}
_isRunning = true;
//杀死已有的ffmpeg进程,不要加.exe后缀
Process[] goDie = Process.GetProcessesByName("ffmpeg");
foreach (Process p in goDie)
{
p.Kill();
}
//执行新的
new Thread(() =>
{
_ffp = new Process();
_ffp.StartInfo.FileName = _ffpPath; // 进程可执行文件位置
_ffp.StartInfo.Arguments = cmdReadStr; // 传给可执行文件的命令行参数
_ffp.StartInfo.CreateNoWindow = !isShowCmd; // 是否显示控制台窗口
_ffp.StartInfo.UseShellExecute = isShowCmd; // 是否使用操作系统Shell程序启动进程
_ffp.OutputDataReceived += (s, e) => ShowResult(e);
_ffp.ErrorDataReceived += (s, e) => ShowResult(e);
_ffp.Start();
_ffp.WaitForExit();
_ffp.Close();
_isRunning = false;
}).Start();
}
private static void ShowResult(DataReceivedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Data))
{
Debug.Log(e.Data);
}
}
/// <summary>
/// 主动退出进程
/// </summary>
public void CloseFFmpegProcess()
{
if (_ffp != null)
{
try
{
_ffp.StandardInput.WriteLine("q");//在这个进程的控制台中模拟输入q,用于暂停录制
_ffp.Close();
_ffp.Dispose();
_ffp = null;
Debug.Log("主动退出FFmpeg进程");
}
catch (Exception)
{
Debug.LogError("没有进程可杀");
}
}
else
{
Debug.LogError("FFmpeg进程为空");
}
}
}
}