使用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);
            }
        }
    }
时间: 2024-10-29 04:39:48

使用FFMPEG进行一些视频处理(C#)视频合并、转码、获取时长的相关文章

asp+ffmpeg获取视频的时长

<% '视频数据定义 ffmpeg = "C:\ffmpeg\bin\ffmpeg.exe" video  = "D:\test\ffmpeg\test2\m1080p1.wmv" 'wscript脚本定义 set WshShell = CreateObject("Wscript.Shell") str2 = "cmd.exe /c "&ffmpeg&" -i "&video&

获取音、视频时长(NAudio,Shell32,FFmpeg)

参考网址:https://blog.csdn.net/u013810234/article/details/57471780 以下为本次测试用到的音.视频格式: audio :".wav;.mp3;.wma;.ra;.mid;.ogg;.ape;.au;.aac;"; vedio :".mp4;.mpg;.mpeg;.avi;.rm;.rmvb;.wmv;.3gp;.flv;.mkv;.swf;.asf;"; Note: 1. 测试音.视频均为对应格式的有效文件(下

layui上传视频并获得视频时长的方法

layui官方上传视频时并没直接提供获取视频时长的方法,需要我们间接获得 HTML增加一个<video>标签,因为video标签可以帮我们获取视频时长 <video id="videoattr" width="250" height="100" ></video> 当然,你也可以设置隐藏. 然后JS就可以利用<video>的duration来得到时长. //同时绑定多个元素,并将属性设定在元素上 u

FFmpeg的使用&mdash;&mdash;PHP转换视频、截取视频以及JW Player播放器控制

转载:http://blog.csdn.net/zm2714/article/details/7916440 给朋友做的一个项目中,涉及到上传视频.转换视频.自动截取已上传视频内容中的一帧做为缩略图片.本篇记录在完成这篇项目过程中的所掌握的一些知识以及经验教训. 上传视频这块暂时不说了,在项目中关于上传这一块涉及进度条的问题,总觉得的不够完美.虽然目前已解决这一块内容,但上传大文件来说,在某些方面仍不够100%的符合要求.有时间在整理这一块.在这篇文章中,由于是在整理这个项目内容,所以有关上传方

用FFMPEG做基于图像变形的视频处理

用FFMPEG做基于图像变形的视频处理 在图像变形算法已知的情况下,我们已求得BMP图像的变形效果.因此,要处理视频,也需要把图像的帧提取出来.这里我使用的是FFMPEG. 步骤如下: 1. 分离音视频工a 和 v 2.将视频v的每一帧提取出来,打包成YUV文件 3.读YUV,将每一帧转成BMP图像,进行图像变形或其它处理,再转回YUV. 4.将新得到的所有YUV帧打包成一个新的YUV文件, 将此文件编码成H264 5.混流H264和第一步得到的音频a,得到新的视频文件. 以上步骤中所有的音视频

FFmpeg+NeroAacEnc多音轨音频与视频合成

工欲善其事必先利其器,工具是必须先准备滴: FFmpeg:http://ffmpeg.zeranoe.com/builds/ ,选最新Static版本下载,exe程序在bin文件夹下,其他是开发者用的 NeroAacEnc:http://www.nero.com/eng/downloads-nerodigital-nero-aac-codec.php ,需填写邮箱地址才能下载. 下面开始吧 方法1 使用ffmpeg实现合并多个音频为一个音频的方法: http://blog.chinaunix.n

ffmpeg最新的yum源地址及视频去logo

一:ffmpeg 最新yum源 cat /etc/yum.repo.d/atrpms.repo [atrpms] name=Red Hat Enterprise Linux $releasever - $basearch - ATrpms failovermethod=priority baseurl=http://dl.atrpms.net/el$releasever-$basearch/atrpms/stable enabled=1 gpgcheck=0 gpgkey=file:///etc

FFmpeg--如何同步音视频的解决方案

如何同步视频 PTS和DTS 幸运的是,音频和视频流都有一些关于以多快速度和什么时间来播放它们的信息在里面.音频流有采样,视频流有每秒的帧率.然而,如果我们只是简单的通过数帧和乘以帧率的方式来同步视频,那么就很有可能会失去同步.于是作为一种补充,在流中的包有种叫做DTS(解码时间戳)和PTS(显示时间戳)的机制.为了这两个参数,你需要了解电影存放的方式.像MPEG等格式,使用被叫做B帧(B表示双向bidrectional)的方式.另外两种帧被叫做I帧和P帧(I表示关键帧,P表示预测帧).I帧包含

Centos7安装ffmpeg和使用youtube-dl下载Youtube视频

FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.称之为音视频处理的神器都不过分.国内的暴风影音.QQ影音和格式工厂等等,都是FFMPEG换个马甲.国外的开源项目养活了多少国内产品. 安装ffmpeg CentOS 6和7安装方法是不一样的,下面分别说明: 安装前都需要先安装epel扩展源 yum -y install epel-release CentOS 6比较简单,安装yum源之后直接安装即可: su -c 'yum localinstall --nog