Ubuntu .net core 中使用 ffmpeg

1. FfmpegHelper.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace com.uplus.ffmpeg
{
    /// <summary>
    ///   FfmpegHelper add by cfl  2022-09-14
    /// </summary>
    public  static class FfmpegHelper
    {
        private static System.Diagnostics.ProcessStartInfo cmdFfmpeg;
        private static System.Diagnostics.ProcessStartInfo cmdFfprobe;
        static FfmpegHelper()
        {

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                string ffmpegPath = "/usr/local/ffmpeg/ffmpeg";
                string ffprobePath = "/usr/local/ffmpeg/ffprobe";
                cmdFfmpeg = new System.Diagnostics.ProcessStartInfo(ffmpegPath);
                cmdFfprobe = new System.Diagnostics.ProcessStartInfo(ffprobePath);
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                string ffmpegPath = AppDomain.CurrentDomain.BaseDirectory + "ffmpeg\\ffmpeg.exe";
                string ffprobePath = AppDomain.CurrentDomain.BaseDirectory + "ffmpeg\\ffprobe.exe";
                cmdFfmpeg = new System.Diagnostics.ProcessStartInfo(ffmpegPath);
                cmdFfprobe = new System.Diagnostics.ProcessStartInfo(ffprobePath);

            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                string ffmpegPath = "/usr/local/ffmpeg/ffmpeg";
                string ffprobePath = "/usr/local/ffmpeg/ffprobe";
                cmdFfmpeg = new System.Diagnostics.ProcessStartInfo(ffmpegPath);
                cmdFfprobe = new System.Diagnostics.ProcessStartInfo(ffprobePath);
            }

            cmdFfmpeg.RedirectStandardError = false; // 輸出錯誤
            cmdFfmpeg.RedirectStandardOutput = true; //輸出打印
            cmdFfmpeg.UseShellExecute = false; //使用Shell
            cmdFfmpeg.CreateNoWindow = true;  //創(chuàng)建黑窗

            cmdFfprobe.RedirectStandardError = false; //set false
            cmdFfprobe.RedirectStandardOutput = true;
            cmdFfprobe.UseShellExecute = false; //set true
            cmdFfprobe.CreateNoWindow = true;  //don't need the black window
        }

        /// <summary>
        /// 獲取視頻信息 add by cfl  2022-09-14
        /// </summary>
        /// <param name="path"></param>
        public static async Task<string> GetVideoInfo(string path)
        {
            string command = $"-i {path} -print_format json -show_format -show_streams -show_data";
            cmdFfprobe.Arguments = command;

            System.Diagnostics.Process cmd = new System.Diagnostics.Process();
            cmd.StartInfo = cmdFfprobe;
            cmd.Start();

            string InfoStr = await cmd.StandardOutput.ReadToEndAsync();
            cmd.WaitForExit();
            return InfoStr;
        }

        /// <summary>
        /// 視頻截圖 add by cfl  2022-09-14
        /// </summary>
        /// <param name="path"></param>
        /// <param name="outPath"></param>
        public static void VideoScreenshot(string path, string outPath)
        {
            string command = $"-i {path} -y -q:v 7 -f image2 -t 0.001 {outPath}";
            cmdFfmpeg.Arguments = command;

            System.Diagnostics.Process cmd = new System.Diagnostics.Process();
            cmd.StartInfo = cmdFfmpeg;
            cmd.Start();
            cmd.WaitForExit();
        }


        #region GetMediaTimeLenMinute (秒)
        public static int GetMediaTimeLenMinute(string path)
        {
            int duration = 0;
            string curr_duration = "00:00:00"; //視頻時長,格式00:08:50
            System.Diagnostics.Process cmd = new System.Diagnostics.Process();
            cmd.StartInfo = cmdFfmpeg;
            cmd.StartInfo.Arguments = " -i " + path;
            cmd.StartInfo.RedirectStandardOutput = true;
            cmd.StartInfo.UseShellExecute = false;
            cmd.StartInfo.CreateNoWindow = true;
            cmd.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            cmd.StartInfo.RedirectStandardError = true;
            cmd.Start();
            StreamReader errorreader = cmd.StandardError;
            cmd.WaitForExit(1000);
            string result = errorreader.ReadToEnd();
            try
            {
                curr_duration = result.Substring(result.IndexOf("Duration: ") + ("Duration: ").Length, ("00:00:00").Length);
                //do something

            }
            catch (Exception ex)
            {
                //do something
            }
            duration = Convert.ToInt32(curr_duration.Split(':')[0]) * 3600 + Convert.ToInt32(curr_duration.Split(':')[1]) * 60 + Convert.ToInt32(curr_duration.Split(':')[2]);
            return duration;
        }
        #endregion

        #region   ConvertVideo
        public static void ConvertVideo(string sourceFile, string playFile)
        {
            Process cmd = new Process();//建立外部調(diào)用線程
            cmd.StartInfo = cmdFfmpeg;

            string strArg = "-i " + sourceFile + " -y -s 640x480 " + playFile + " ";

            cmd.StartInfo.Arguments = strArg;

            cmd.StartInfo.UseShellExecute = false;//不使用操作系統(tǒng)外殼程序啟動線程(一定為FALSE,詳細的請看MSDN)
            cmd.StartInfo.RedirectStandardError = true;//把外部程序錯誤輸出寫到StandardError流中(這個一定要注意,FFMPEG的所有輸出信息,都為錯誤輸出流,用StandardOutput是捕獲不到任何消息的...這是我耗費了2個多月得出來的經(jīng)驗...mencoder就是用standardOutput來捕獲的)
            cmd.StartInfo.CreateNoWindow = false;//不創(chuàng)建進程窗口
            cmd.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(這里是FFMPEG)輸出流時候產(chǎn)生的事件,這里是把流的處理過程轉移到下面的方法中,詳細請查閱MSDN
            cmd.Start();//啟動線程
            cmd.BeginErrorReadLine();//開始異步讀取
            cmd.WaitForExit();//阻塞等待進程結束
            cmd.Close();//關閉進程
            cmd.Dispose();//釋放資源
        }
        #endregion

        public static void ConvertToMp4(string webRootPath, string fileName, string fName)
        {
            string path = $"{webRootPath}{Path.DirectorySeparatorChar}Data{Path.DirectorySeparatorChar}{fileName}";
            string newPath = $"{webRootPath}{System.IO.Path.DirectorySeparatorChar}Data{System.IO.Path.DirectorySeparatorChar}{fName}.mp4";
            if (!File.Exists(newPath))
            {
                System.Diagnostics.Process cmd = new System.Diagnostics.Process();
                var startInfo = new ProcessStartInfo();
                cmd.StartInfo = cmdFfmpeg;
                //cmd.StartInfo.Arguments = $" -i {path}  -y -s 640x480 {newPath}";
                 cmd.StartInfo.Arguments = $" -i {path}  -movflags faststart -pix_fmt yuv420p {newPath}";
                // cmd.StartInfo.Arguments = $" -i {path}  -vcodec libx264 -pix_fmt yuv420p {newPath}";
                //cmd.StartInfo.Arguments = $" -i {path}   -c:v libx264 -mbd 0 -c:a aac -strict -2 -pix_fmt yuv420p -movflags faststart {newPath}";
                cmd.StartInfo.RedirectStandardOutput = true;
                cmd.StartInfo.UseShellExecute = false;
                cmd.StartInfo.CreateNoWindow = true;
                cmd.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                cmd.StartInfo.RedirectStandardError = true;
                cmd.Start();
                StreamReader errorreader = cmd.StandardError;
                cmd.WaitForExit(1000);
                string result = errorreader.ReadToEnd();
            }
        }

        #region  Output
        private static void Output(object sendProcess, DataReceivedEventArgs output)
        {
            if (!String.IsNullOrEmpty(output.Data))
            {
                //處理方法...
                //Console.WriteLine(output.Data);

                ////去獲取時長
                //string partitio1 = @"Duration: \d{2}:\d{2}:\d{2}.\d{2}";
                //if (RegexHelper.IsMatch(partitio1, output.Data))
                //{
                //    string partition = @"(?<=Duration: )\d{2}:\d{2}:\d{2}.\d{2}";
                //    string timespan = RegexHelper.Matchs(output.Data, partition).FirstOrDefault();
                //    TimeSpan span;
                //    if (TimeSpan.TryParse(timespan, out span))
                //    {
                //        Console.WriteLine(span.TotalMilliseconds);
                //    }
                //}

                ////獲取時刻
                //string partitio2 = @"time=\d{2}:\d{2}:\d{2}.\d{2}";
                //if (RegexHelper.IsMatch(partitio2, output.Data))
                //{
                //    string partition = @"(?<=time=)\d{2}:\d{2}:\d{2}.\d{2}";

                //    string timespan = RegexHelper.Matchs(output.Data, partition).FirstOrDefault();
                //    TimeSpan span;
                //    if (TimeSpan.TryParse(timespan, out span))
                //    {
                //        Console.WriteLine(span.TotalMilliseconds);
                //    }
                //}
            }
        }
        #endregion

    }
}


2. 調(diào)用
        [HttpGet]
        public ActionResult<ResponseData> GetVideoInfo(string fileName)
        {
            ResponseData result = new ResponseData();
            try
            {
                int duration = FfmpegHelper.GetMediaTimeLenMinute($"{ServiceBase.Get<HostingEnvironment>().WebRootPath}            {System.IO.Path.DirectorySeparatorChar}Data{System.IO.Path.DirectorySeparatorChar}{fileName}");

                result.ErrorCode = 0;
                result.Message = "操作成功";
                result.DataList = new ModelData { 
                    DataList = duration
                };
                return new JsonResult(result);
            }
            catch (Exception ex)
            {
                return this.ControllerExHandler(result, "GetVideoInfo", ex);
            }

        }

3. 效果:
{
    "ErrorCode": 0,
    "Message": "操作成功",
    "Token": null,
    "DataList": {
        "TotalPage": 0,
        "RecordCount": 0,
        "Info": null,
        "DataList": 185
    }
}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容