UbuntuFFmpegLinux ♥ Windows

Ubuntu .net core 中使用 ffmpeg

2022-09-14  本文已影响0人  Rinaloving
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;  //创建黑窗

            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();//建立外部调用线程
            cmd.StartInfo = cmdFfmpeg;

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

            cmd.StartInfo.Arguments = strArg;

            cmd.StartInfo.UseShellExecute = false;//不使用操作系统外壳程序启动线程(一定为FALSE,详细的请看MSDN)
            cmd.StartInfo.RedirectStandardError = true;//把外部程序错误输出写到StandardError流中(这个一定要注意,FFMPEG的所有输出信息,都为错误输出流,用StandardOutput是捕获不到任何消息的...这是我耗费了2个多月得出来的经验...mencoder就是用standardOutput来捕获的)
            cmd.StartInfo.CreateNoWindow = false;//不创建进程窗口
            cmd.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅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. 调用
        [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
    }
}
上一篇 下一篇

猜你喜欢

热点阅读