我在我的项目中使用的这个链接中有这个类:
http://jasonjano.wordpress.com/2010/02/09/a-simple-c-wrapper-for-ffmpeg/
现在在 Form1 中我像这样使用它:在我的 timer1 滴答事件中,我创建了 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");
结果在我的硬盘上有两个文件:
新的.avi 和新的.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 ==>