zoukankan      html  css  js  c++  java
  • 利用ffmpeg转换mp4文件

    这个是我今天整理项目的时候无意发现的,当时主要是用它来转换flv文件在手机上使用,后来买了psp之后就没有用了,记录一下,以后写这种类似的程序可以参考。

    class VideoConverter : IDisposable
    {
        public string InputFile { get; private set; }
        public string OutPutFile { get; private set; }
        public int Progress { get; private set; }
        public object Tag { get; set; }

        double totalTime;

        public VideoConverter(string input, string output)
        {
            InputFile = input;
            OutPutFile = output;
        }

        ~VideoConverter()
        {
            Dispose();
        }

        const string ffmpeg_exe = "ffmpeg.exe";

        /// <summary>
        ///
    这个是个阻塞调用,切勿在ui线程上调用
        /// </summary>
        public void Process()
        {
            var sb = new StringBuilder();
            ExcuteProcess(ffmpeg_exe, string.Format(" -i \"{0}\"", InputFile), (s, e) => sb.AppendLine(e.Data));
            var totalT = SimpleMatch(sb.ToString(), @"Duration:\s+(\S+?)[,\s]");
            var totalTs = TimeSpan.Parse(totalT);
            totalTime = totalTs.TotalSeconds;
            ExcuteProcess(ffmpeg_exe, string.Format(" -i \"{0}\" \"{1}\" ", InputFile, OutPutFile), (s, e) => ProcessOutPut(e.Data));        
            Progress = 100;
            Console.WriteLine("-----------{0}---------", Progress);
        }

        string SimpleMatch(string data, string patten)
        {
            Console.WriteLine(data);
            var m = System.Text.RegularExpressions.Regex.Match(data, patten);
            return m.Groups[1].Value;
        }

        void ExcuteProcess(string exe, string arg, DataReceivedEventHandler output)
        {
            Console.WriteLine(exe + " " + arg);
            using (var p = new Process())
            {
                killHanlder = p.Kill;
                p.StartInfo.FileName = exe;
                p.StartInfo.Arguments = arg;

                p.StartInfo.UseShellExecute = false;    //
    输出信息重定向
                p.StartInfo.CreateNoWindow = true;
                p.StartInfo.RedirectStandardError = true;
                p.StartInfo.RedirectStandardOutput = true;

                p.OutputDataReceived += output;
                p.ErrorDataReceived += output;

                p.Start();                    //
    启动线程
                p.BeginOutputReadLine();
                p.BeginErrorReadLine();
                p.WaitForExit();            //
    等待进程结束
            }

            killHanlder = null;
        }

        void ProcessOutPut(string output)
        {
            Console.WriteLine(output);
            if (string.IsNullOrEmpty(output))
                return;

            if (!output.Contains("time="))
                return;

            var current = SimpleMatch(output, @"time=(\S+)");
            var currentTime = double.Parse(current);

            Progress = (int)(currentTime * 100 / totalTime);
            if (Progress > 100)
                Progress = 100;

            Console.WriteLine("-----------{0}---------", Progress);
        }

        #region IDisposable
    成员

        Action killHanlder;
        public void Dispose()
        {
            if (killHanlder == null)
                return;

            killHanlder();
            killHanlder = null;
        }

        #endregion
    }

    ffmpeg下载地址:http://ffdshow.faireal.net/mirror/ffmpeg/

  • 相关阅读:
    第3、4、5讲
    .NetCore使用EF5操作Oracle,解决列自增序列绑定不生效的问题
    ASP.NET Core 之 Identity 入门(一)
    ORACLE NLS_DATE_FORMAT设置
    ORA12514遇到了怎么排查问题出在哪
    Oracle特殊字符查询语句
    ORA00821: Specified value of sga_target 3072M is too small, needs to be at least 12896M
    如何定位哪些SQL产生了大量的Redo日志
    Oracle定位对阻塞的对象或锁信息
    Oracle Undo和Redo的关系,区别及相关查询
  • 原文地址:https://www.cnblogs.com/TianFang/p/1386250.html
Copyright © 2011-2022 走看看