简单易懂,直接上代码

/*********************************************
 * 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进程为空");
            }
        }
    }
}

最后修改:2023 年 07 月 04 日
如果觉得我的文章对你有用,请随意赞赏