如何使用ffmpeg压缩avi文件?

时间:2013-04-20 09:59:48

标签: c#

我在我的项目中使用此链接中的这个类:

http://jasonjano.wordpress.com/2010/02/09/a-simple-c-wrapper-for-ffmpeg/

现在在Form1中使用它像这样: 在我的timer1 tick事件中,我创建了avi文件,它没有任何问题:

private void timer1_Tick(object sender, EventArgs e)
        {
            if (playImages == true)
            {
                timer1.Enabled = false;
                play();
                timer1.Enabled = true;
            }
            else
            {
                af.CreateAvi(this.sc);

            }
        }

然后压缩我添加了一个新功能:

public string ConvertH264(string inputPath, string outPath)
        {

            string params1 = string.Format("-i {0}  -vcodec mpeg4 -acodec aac -strict -2 -ar 22050 -b:a 128k {1}", inputPath, outPath);
            string output = _converter.RunProcess(params1);
            return output;
        }

然后在button3中我停止计时器,avi文件在硬盘上我做了:

ConvertH264(@"D:\testdata\new.avi", @"D:\testdata\new.flv");

结果在我的硬盘上有两个文件:

new.avi和new.flv

avi文件是324mb,flv文件是960kb 我可以播放avi文件,但我不能在任何地方播放flv文件。使用flv文件的东西是错误的。

flv文件应该是压缩文件。

可能是什么问题?也许有ffmpeg参数的东西?

string params1 = string.Format("-i {0}  -vcodec mpeg4 -acodec aac -strict -2 -ar 22050 -b:a 128k {1}", inputPath, outPath);

如果需要:这是我在上面的链接中使用它的类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Diagnostics;
using System.Configuration;
using System.Text.RegularExpressions;

namespace ScreenVideoRecorder
{
    public class Converter
    {
        #region Properties
        private string _ffExe;
        public string ffExe
        {
            get
            {
                return _ffExe;
            }
            set
            {
                _ffExe = value;
            }
        }

        private string _WorkingPath;
        public string WorkingPath
        {
            get
            {
                return _WorkingPath;
            }
            set
            {
                _WorkingPath = value;
            }
        }

        #endregion

        #region Constructors
        public Converter()
        {
            Initialize();
        }
        public Converter(string ffmpegExePath)
        {
            _ffExe = ffmpegExePath;
            Initialize();
        }
        #endregion

        #region Initialization
        private void Initialize()
        {
            //first make sure we have a value for the ffexe file setting
            if (string.IsNullOrEmpty(_ffExe))
            {
                _ffExe = @"D:\temp\compress\ffmpeg\ffmpeg.exe"; 

               /* if (o == null)
                {
                    throw new Exception("Could not find the location of the ffmpeg exe file.  The path for ffmpeg.exe " +
                    "can be passed in via a constructor of the ffmpeg class (this class) or by setting in the app.config or web.config file.  " +
                    "in the appsettings section, the correct property name is: ffmpeg:ExeLocation");
                }
                else
                {
                    if (string.IsNullOrEmpty(o.ToString()))
                    {
                        throw new Exception("No value was found in the app setting for ffmpeg:ExeLocation");
                    }
                    _ffExe = o.ToString();
                }*/
            }

            //Now see if ffmpeg.exe exists
            string workingpath = GetWorkingFile();
            if (string.IsNullOrEmpty(workingpath))
            {
                //ffmpeg doesn't exist at the location stated.
                throw new Exception("Could not find a copy of ffmpeg.exe");
            }
            _ffExe = workingpath;

            //now see if we have a temporary place to work
            if (string.IsNullOrEmpty(_WorkingPath))
            {
                _WorkingPath = @"D:\temp\compress\ffmpeg\";
               /* if (o != null)
                {
                    _WorkingPath = o.ToString();
                }
                else
                {
                    _WorkingPath = string.Empty;
                }*/
            }
        }

        private string GetWorkingFile()
        {
            //try the stated directory
            if (File.Exists(_ffExe))
            {
                return _ffExe;
            }

            //oops, that didn't work, try the base directory
            if (File.Exists(Path.GetFileName(_ffExe)))
            {
                return Path.GetFileName(_ffExe);
            }

            //well, now we are really unlucky, let's just return null
            return null;
        }
        #endregion

        #region Get the File without creating a file lock
        public static System.Drawing.Image LoadImageFromFile(string fileName)
        {
            System.Drawing.Image theImage = null;
            using (FileStream fileStream = new FileStream(fileName, FileMode.Open,
            FileAccess.Read))
            {
                byte[] img;
                img = new byte[fileStream.Length];
                fileStream.Read(img, 0, img.Length);
                fileStream.Close();
                theImage = System.Drawing.Image.FromStream(new MemoryStream(img));
                img = null;
            }
            GC.Collect();
            return theImage;
        }

        public static MemoryStream LoadMemoryStreamFromFile(string fileName)
        {
            MemoryStream ms = null;
            using (FileStream fileStream = new FileStream(fileName, FileMode.Open,
            FileAccess.Read))
            {
                byte[] fil;
                fil = new byte[fileStream.Length];
                fileStream.Read(fil, 0, fil.Length);
                fileStream.Close();
                ms = new MemoryStream(fil);
            }
            GC.Collect();
            return ms;
        }
        #endregion

        #region Run the process
        public string RunProcess(string Parameters)
        {
            //create a process info
            ProcessStartInfo oInfo = new ProcessStartInfo(this._ffExe, Parameters);
            oInfo.UseShellExecute = false;
            oInfo.CreateNoWindow = true;
            oInfo.RedirectStandardOutput = true;
            oInfo.RedirectStandardError = true;

            //Create the output and streamreader to get the output
            string output = null; StreamReader srOutput = null;

            //try the process
            try
            {
                //run the process
                Process proc = System.Diagnostics.Process.Start(oInfo);

                proc.WaitForExit();

                //get the output
                srOutput = proc.StandardError;

                //now put it in a string
                output = srOutput.ReadToEnd();

                proc.Close();
            }
            catch (Exception)
            {
                output = string.Empty;
            }
            finally
            {
                //now, if we succeded, close out the streamreader
                if (srOutput != null)
                {
                    srOutput.Close();
                    srOutput.Dispose();
                }
            }
            return output;
        }
        #endregion

        #region GetVideoInfo
        public VideoFile GetVideoInfo(MemoryStream inputFile, string Filename)
        {
            string tempfile = Path.Combine(this.WorkingPath, System.Guid.NewGuid().ToString() + Path.GetExtension(Filename));
            FileStream fs = File.Create(tempfile);
            inputFile.WriteTo(fs);
            fs.Flush();
            fs.Close();
            GC.Collect();

            VideoFile vf = null;
            try
            {
                vf = new VideoFile(tempfile);
            }
            catch (Exception ex)
            {
                throw ex;
            }

            GetVideoInfo(vf);

            try
            {
                File.Delete(tempfile);
            }
            catch (Exception)
            {

            }

            return vf;
        }
        public VideoFile GetVideoInfo(string inputPath)
        {
            VideoFile vf = null;
            try
            {
                vf = new VideoFile(inputPath);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            GetVideoInfo(vf);
            return vf;
        }
        public void GetVideoInfo(VideoFile input)
        {
            //set up the parameters for video info
            string Params = string.Format("-i {0}", input.Path);
            string output = RunProcess(Params);
            input.RawInfo = output;

            //get duration
            Regex re = new Regex("[D|d]uration:.((\\d|:|\\.)*)");
            Match m = re.Match(input.RawInfo);

            if (m.Success)
            {
                string duration = m.Groups[1].Value;
                string[] timepieces = duration.Split(new char[] { ':', '.' });
                if (timepieces.Length == 4)
                {
                    input.Duration = new TimeSpan(0, Convert.ToInt16(timepieces[0]), Convert.ToInt16(timepieces[1]), Convert.ToInt16(timepieces[2]), Convert.ToInt16(timepieces[3]));
                }
            }

            //get audio bit rate
            re = new Regex("[B|b]itrate:.((\\d|:)*)");
            m = re.Match(input.RawInfo);
            double kb = 0.0;
            if (m.Success)
            {
                Double.TryParse(m.Groups[1].Value, out kb);
            }
            input.BitRate = kb;

            //get the audio format
            re = new Regex("[A|a]udio:.*");
            m = re.Match(input.RawInfo);
            if (m.Success)
            {
                input.AudioFormat = m.Value;
            }

            //get the video format
            re = new Regex("[V|v]ideo:.*");
            m = re.Match(input.RawInfo);
            if (m.Success)
            {
                input.VideoFormat = m.Value;
            }

            //get the video format
            re = new Regex("(\\d{2,3})x(\\d{2,3})");
            m = re.Match(input.RawInfo);
            if (m.Success)
            {
                int width = 0; int height = 0;
                int.TryParse(m.Groups[1].Value, out width);
                int.TryParse(m.Groups[2].Value, out height);
                input.Width = width;
                input.Height = height;
            }
            input.infoGathered = true;
        }
        #endregion

        #region Convert to FLV
        public OutputPackage ConvertToFLV(MemoryStream inputFile, string Filename)
        {
            string tempfile = Path.Combine(this.WorkingPath, System.Guid.NewGuid().ToString() + Path.GetExtension(Filename));
            FileStream fs = File.Create(tempfile);
            inputFile.WriteTo(fs);
            fs.Flush();
            fs.Close();
            GC.Collect();

            VideoFile vf = null;
            try
            {
                vf = new VideoFile(tempfile);
            }
            catch (Exception ex)
            {
                throw ex;
            }

            OutputPackage oo = ConvertToFLV(vf);

            try
            {
                File.Delete(tempfile);
            }
            catch (Exception)
            {

            }

            return oo;
        }
        public OutputPackage ConvertToFLV(string inputPath)
        {
            VideoFile vf = null;
            try
            {
                vf = new VideoFile(inputPath);
            }
            catch (Exception ex)
            {
                throw ex;
            }

            OutputPackage oo = ConvertToFLV(vf);
            return oo;
        }
        public OutputPackage ConvertToFLV(VideoFile input)
        {
            if (!input.infoGathered)
            {
                GetVideoInfo(input);
            }
            OutputPackage ou = new OutputPackage();

            //set up the parameters for getting a previewimage
            string filename = System.Guid.NewGuid().ToString() + ".jpg";
            int secs;

            //divide the duration in 3 to get a preview image in the middle of the clip
            //instead of a black image from the beginning.
            secs = (int)Math.Round(TimeSpan.FromTicks(input.Duration.Ticks / 3).TotalSeconds, 0);

            string finalpath = Path.Combine(this.WorkingPath, filename);
            string Params = string.Format("-i {0} {1} -vcodec mjpeg -ss {2} -vframes 1 -an -f rawvideo", input.Path, finalpath, secs);
            string output = RunProcess(Params);

            ou.RawOutput = output;

            if (File.Exists(finalpath))
            {
                ou.PreviewImage = LoadImageFromFile(finalpath);
                try
                {
                    File.Delete(finalpath);
                }
                catch (Exception) { }
            }
            else
            { //try running again at frame 1 to get something
                Params = string.Format("-i {0} {1} -vcodec mjpeg -ss {2} -vframes 1 -an -f rawvideo", input.Path, finalpath, 1);
                output = RunProcess(Params);

                ou.RawOutput = output;

                if (File.Exists(finalpath))
                {
                    ou.PreviewImage = LoadImageFromFile(finalpath);
                    try
                    {
                        File.Delete(finalpath);
                    }
                    catch (Exception) { }
                }
            }

            finalpath = Path.Combine(this.WorkingPath, filename);
            filename = System.Guid.NewGuid().ToString() + ".flv";
            Params = string.Format("-i {0} -y -ar 22050 -ab 64 -f flv {1}", input.Path, finalpath);
            output = RunProcess(Params);

            if (File.Exists(finalpath))
            {
                ou.VideoStream = LoadMemoryStreamFromFile(finalpath);
                try
                {
                    File.Delete(finalpath);
                }
                catch (Exception) { }
            }
            return ou;
        }
        #endregion
    }

    public class VideoFile
    {
        #region Properties
        private string _Path;
        public string Path
        {
            get
            {
                return _Path;
            }
            set
            {
                _Path = value;
            }
        }

        public TimeSpan Duration { get; set; }
        public double BitRate { get; set; }
        public string AudioFormat { get; set; }
        public string VideoFormat { get; set; }
        public int Height { get; set; }
        public int Width { get; set; }
        public string RawInfo { get; set; }
        public bool infoGathered { get; set; }
        #endregion

        #region Constructors
        public VideoFile(string path)
        {
            _Path = path;
            Initialize();
        }
        #endregion

        #region Initialization
        private void Initialize()
        {
            this.infoGathered = false;
            //first make sure we have a value for the video file setting
            if (string.IsNullOrEmpty(_Path))
            {
                throw new Exception("Could not find the location of the video file");
            }

            //Now see if the video file exists
            if (!File.Exists(_Path))
            {
                throw new Exception("The video file " + _Path + " does not exist.");
            }
        }
        #endregion
    }

    public class OutputPackage
    {
        public MemoryStream VideoStream { get; set; }
        public System.Drawing.Image PreviewImage { get; set; }
        public string RawOutput { get; set; }
        public bool Success { get; set; }
    }
}

这是日志:

4/20/2013--5:32 PM ==> 
4/20/2013--6:47 PM ==> ffmpeg version N-52233-gee94362 Copyright (c) 2000-2013 the FFmpeg developers
4/20/2013--6:47 PM ==>   built on Apr 18 2013 02:55:39 with gcc 4.8.0 (GCC)
4/20/2013--6:47 PM ==>   configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
4/20/2013--6:47 PM ==>   libavutil      52. 26.100 / 52. 26.100
4/20/2013--6:47 PM ==>   libavcodec     55.  2.100 / 55.  2.100
4/20/2013--6:47 PM ==>   libavformat    55.  2.100 / 55.  2.100
4/20/2013--6:47 PM ==>   libavdevice    55.  0.100 / 55.  0.100
4/20/2013--6:47 PM ==>   libavfilter     3. 56.103 /  3. 56.103
4/20/2013--6:47 PM ==>   libswscale      2.  2.100 /  2.  2.100
4/20/2013--6:47 PM ==>   libswresample   0. 17.102 /  0. 17.102
4/20/2013--6:47 PM ==>   libpostproc    52.  3.100 / 52.  3.100
4/20/2013--6:47 PM ==> Input #0, avi, from 'D:\testdata\new.avi':
4/20/2013--6:47 PM ==>   Duration: 00:00:02.12, start: 0.000000, bitrate: 1658893 kb/s
4/20/2013--6:47 PM ==>     Stream #0:0: Video: rawvideo, bgra, 1920x1080, 25 tbr, 25 tbn, 25 tbc
4/20/2013--6:47 PM ==> Codec AVOption b (set bitrate (in bits/s)) specified for output file #0 (D:\testdata\new.flv) has not been used for any stream. The most likely reason is either wrong type (e.g. a video option with no video streams) or that it is a private option of some encoder which was not actually used for any stream.
4/20/2013--6:47 PM ==> Output #0, flv, to 'D:\testdata\new.flv':
4/20/2013--6:47 PM ==>   Metadata:
4/20/2013--6:47 PM ==>     encoder         : Lavf55.2.100
4/20/2013--6:47 PM ==>     Stream #0:0: Video: mpeg4 ([9][0][0][0] / 0x0009), yuv420p, 1920x1080, q=2-31, 200 kb/s, 1k tbn, 25 tbc
4/20/2013--6:47 PM ==> Stream mapping:
4/20/2013--6:47 PM ==>   Stream #0:0 -> #0:0 (rawvideo -> mpeg4)
4/20/2013--6:47 PM ==> Press [q] to stop, [?] for help
4/20/2013--6:47 PM ==> frame=    8 fps=0.0 q=18.4 size=     599kB time=00:00:00.32 bitrate=15326.9kbits/s    
4/20/2013--6:47 PM ==> frame=   14 fps= 12 q=31.0 size=     669kB time=00:00:00.56 bitrate=9779.3kbits/s    
4/20/2013--6:47 PM ==> frame=   20 fps= 12 q=31.0 size=     680kB time=00:00:00.80 bitrate=6966.3kbits/s    
4/20/2013--6:47 PM ==> frame=   24 fps= 11 q=31.0 size=     688kB time=00:00:00.96 bitrate=5872.3kbits/s    
4/20/2013--6:47 PM ==> frame=   31 fps= 11 q=31.0 size=     764kB time=00:00:01.24 bitrate=5044.3kbits/s    
4/20/2013--6:47 PM ==> frame=   37 fps= 11 q=24.8 size=     853kB time=00:00:01.48 bitrate=4723.3kbits/s    
4/20/2013--6:47 PM ==> frame=   42 fps= 11 q=31.0 size=     859kB time=00:00:01.68 bitrate=4190.6kbits/s    
4/20/2013--6:47 PM ==> frame=   48 fps= 11 q=31.0 size=     885kB time=00:00:01.92 bitrate=3777.2kbits/s    
4/20/2013--6:47 PM ==> frame=   53 fps= 11 q=31.0 size=     956kB time=00:00:02.12 bitrate=3695.0kbits/s    
4/20/2013--6:47 PM ==> frame=   53 fps= 11 q=31.0 Lsize=     956kB time=00:00:02.12 bitrate=3695.1kbits/s    
4/20/2013--6:47 PM ==> 
4/20/2013--6:47 PM ==> video:955kB audio:0kB subtitle:0 global headers:0kB muxing overhead 0.135293%
4/20/2013--6:47 PM ==> 
4/20/2013--6:47 PM ==> 

0 个答案:

没有答案