zoukankan      html  css  js  c++  java
  • 使用FFMPEG进行一些视频处理(C#)视频合并、转码、获取时长

    FFMPEG的强大无需多说,举几个用到的功能,直接贴代码了

    还有更多命令用到时搜索即可

    视频转码

    public static string DecodeMp4ToFlv(string mp4, string format = ".flv", int timeout = 0)
            {
                var args = "-y -i {0} -vcodec copy {1}".Formatting(""{0}"".Formatting(mp4), ""{0}"".Formatting(strFlvPath));
                string output, error;
                if (timeout <= 0)
                    timeout = 5*60*1000; // 超时时间 = 5 分钟
                ProcessHelper.Process(strFFMPEGPath, args, timeout, out output, out error);
                if (!error.IsNullOrEmpty())
                {
                    Logger.Error("{0}{1} : {2}{0}".Formatting(Environment.NewLine, "FFmpeg", error));
                }
    
                return flv;
            }

    视频合并

    public static string ConcatMp4(string mp41, string mp42)
            {

    var args = " -i "concat:" + mp41 + "|" + mp42 + "|" -c copy -bsf:a aac_adtstoasc -movflags +faststart " + outputpath; string output, error; int timeout = 2 * 60 * 1000; // 超时时间 = 2 分钟 ProcessHelper.Process(strFFMPEGPath, args, timeout, out output, out error); if (!error.IsNullOrEmpty()) { Logger.Error("{0}{1} : {2}{0}".Formatting(Environment.NewLine, "FFmpeg", error)); } return outputpath;
     }

    获取视频时长

    private static int GetVideoDuration(string ffmpegfile, string sourceFile)
            {
                try
                {
                    using (System.Diagnostics.Process ffmpeg = new System.Diagnostics.Process())
                    {
                        String duration;  // soon will hold our video's duration in the form "HH:MM:SS.UU"  
                        String result;  // temp variable holding a string representation of our video's duration  
                        StreamReader errorreader;  // StringWriter to hold output from ffmpeg  
    
                        // we want to execute the process without opening a shell  
                        ffmpeg.StartInfo.UseShellExecute = false;
                        //ffmpeg.StartInfo.ErrorDialog = false;  
                        ffmpeg.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                        // redirect StandardError so we can parse it  
                        // for some reason the output comes through over StandardError  
                        ffmpeg.StartInfo.RedirectStandardError = true;
                        // set the file name of our process, including the full path  
                        // (as well as quotes, as if you were calling it from the command-line)  
                        ffmpeg.StartInfo.FileName = ffmpegfile;
    
                        // set the command-line arguments of our process, including full paths of any files  
                        // (as well as quotes, as if you were passing these arguments on the command-line)  
                        ffmpeg.StartInfo.Arguments = "-i " + sourceFile;
    
                        // start the process  
                        ffmpeg.Start();
    
                        // now that the process is started, we can redirect output to the StreamReader we defined  
                        errorreader = ffmpeg.StandardError;
    
                        // wait until ffmpeg comes back  
                        ffmpeg.WaitForExit();
    
                        // read the output from ffmpeg, which for some reason is found in Process.StandardError  
                        result = errorreader.ReadToEnd();
    
                        // a little convoluded, this string manipulation...  
                        // working from the inside out, it:  
                        // takes a substring of result, starting from the end of the "Duration: " label contained within,  
                        // (execute "ffmpeg.exe -i somevideofile" on the command-line to verify for yourself that it is there)  
                        // and going the full length of the timestamp  
    
                        duration = result.Substring(result.IndexOf("Duration: ") + ("Duration: ").Length, ("00:00:00").Length);
    
                        string[] ss = duration.Split(':');
                        int h = int.Parse(ss[0]);
                        int m = int.Parse(ss[1]);
                        int s = int.Parse(ss[2]);
                        return h * 3600 + m * 60 + s;
                    }
                }
                catch (System.Exception ex)
                {
                    return 60;
                }
            }  

    Process处理类如下,也可以自己写个
    public static void Process(string startFile, string args, int timeout, out string standardOutput,
                out string standardError)
            {
                using (var process = new ProcessExecutor(startFile, args, timeout))
                {
                    process.Execute(out standardOutput, out standardError);
                }
            }
    internal class ProcessExecutor : IDisposable
        {
            private readonly StringBuilder error;
            private readonly AutoResetEvent errorWaitHandle;
            private readonly StringBuilder output;
            private readonly int timeout;
            private AutoResetEvent outputWaitHandle;
            private Process process;
    
            public ProcessExecutor(string startFile, string args, int timeout = 0)
            {
                process = new Process();
                //设置进程启动信息属性StartInfo,这是ProcessStartInfo类
                process.StartInfo.FileName = Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(startFile));
                process.StartInfo.Arguments = Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(args));
    
                process.StartInfo.UseShellExecute = false;
                //提供的标准输出流只有2k,超过大小会卡住;如果有大量输出,就读出来
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardError = true;
                process.StartInfo.CreateNoWindow = true;
    
                output = new StringBuilder();
                error = new StringBuilder();
    
                outputWaitHandle = new AutoResetEvent(false);
                errorWaitHandle = new AutoResetEvent(false);
    
                this.timeout = timeout;
    
                RegisterToEvents();
            }
    
            public void Dispose()
            {
                UnregisterFromEvents();
    
                if (process != null)
                {
                    process.Dispose();
                    process = null;
                }
                if (errorWaitHandle != null)
                {
                    errorWaitHandle.Close();
                    outputWaitHandle = null;
                }
                if (outputWaitHandle != null)
                {
                    outputWaitHandle.Close();
                    outputWaitHandle = null;
                }
            }
    
            public void Execute(out string standardOutput, out string standardError)
            {
                process.Start();
    
                process.BeginOutputReadLine();
                process.BeginErrorReadLine();
    
                if (process.WaitForExit(timeout) &&
                    outputWaitHandle.WaitOne(timeout) &&
                    errorWaitHandle.WaitOne(timeout))
                {
    
                }
                else
                {
                    // if timeout then kill the procee
                    process.Kill();
                }
    
                standardOutput = output.ToString();
                standardError = error.ToString();
            }
    
            private void RegisterToEvents()
            {
                process.OutputDataReceived += process_OutputDataReceived;
                process.ErrorDataReceived += process_ErrorDataReceived;
            }
    
            private void UnregisterFromEvents()
            {
                process.OutputDataReceived -= process_OutputDataReceived;
                process.ErrorDataReceived -= process_ErrorDataReceived;
            }
    
            private void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
            {
                if (e.Data == null)
                {
                    errorWaitHandle.Set();
                }
                else
                {
                    error.AppendLine(e.Data);
                }
            }
    
            private void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
            {
                if (e.Data == null)
                {
                    outputWaitHandle.Set();
                }
                else
                {
                    output.AppendLine(e.Data);
                }
            }
        }
  • 相关阅读:
    按钮,文本框
    d01
    第一天,对于课程和工作的了解
    javaweb概念性知识
    Jdbc概念性知识
    连接数据库,和数据增删改
    oracle基础概念性知识
    面向对象java知识汇总题
    javaweb
    date日期
  • 原文地址:https://www.cnblogs.com/jhlong/p/7417130.html
Copyright © 2011-2022 走看看