zoukankan      html  css  js  c++  java
  • ffmpeg在asp.net 视频转换

    ffmpeg是一个源于Linux的工具软件,是FLV视频转换器,可以轻易地实现FLV向其它格式avi、asf、 mpeg的转换或者将其它格式转换为flv。在视频播客中,我们通常使用它把我们上传的视频转换为FLV格式,以尽可能大地压缩视频,实现在现有网络带宽上流畅播放视频剪辑。(车延禄)
    ffmpeg是DOS控制台程序,它有自己的执行语法,只要我们把它的语法功能掌握好,就可以在命令提示符下使用它来把相应的视频转换为flv格式的文件了。
    一、ffmpeg的语法
    如:ffmpeg -i aaa.avi -y -s 400*300 -f image2 -ss 0 aaa.jpg -ab 56 -ar 22050 -qmin 3 -qmax 8 -r 15 -qscale 7 aaa.flv
    执行过程:

    《图1》
    执行结果:

    《图2》
    参数好多,还有未列出来的参数。下面我们把一些常用的参数介绍一下。
        -y 是否覆盖输出文件。即如果aaa.flv文件已经存在的话,不经提示就覆盖掉了
        -i "aaa.avi"    输入文件。可以自己加路径
        -s 400*300 要生成的视频文件的分辨率大小
        -f image2   要输出的格式是图片格式
    (车延禄)
        -ss 0 aaa.jpg 要截取图片的位置,在第0秒截取图片,并保存为aaa.jpg文件
        -aspect 视频纵横比4:3或16:9
        -vcodec xvid    使用XVID编码压缩视频
        -acodec aac 音频编码用AAC
        -ab 56 设定声音比特率,-ac设为立体声时要以一半比特率来设置
        -ac 2   设定声道数,1就是单声道,2就是立体声
        -ar 22050   设定声音采样率
        -qmin 3 设定最小质量,与-qmax(设定最大质量)共用,
        -qmax 8 设定最大质量,与-qmin(设定最小质量)共用,
        -r 15   桢速率(可以改,确认非标准桢率会导致音画不同步,所以只能设定为15或者29.97)
        -qscale 7   以7质量为基础的VBR,取值0.01-255,越小视频质量越好
        aaa.flv 目标文件的文件名
        -vol 200    音频音量大小
    通过ffmpeg这个命令我们就可以把avi、asf、mpeg等格式的文件转换为flv视频文件,并生成视频截图。

    二、在C#中调用ffmpeg命令
    1.执行转换命令:
        ffmpeg是外部命令,在C#中我们需要使用Process来调用外部命令
        //实例化Process,用一个独立线程来执行ffmpeg.exe程序
       
     Process p = new Process();
        //指定Process要执行的外部命令,这里需要指定ffmpeg.exe所在位置的全路径
        p.StartInfo.FileName = "ffmpeg.exe";
        //ffmpeg.exe执行的时候需要的参数
        p.StartInfo.Arguments = " -i aaa.avi -y -s 400*300 -f image2 -ss 0 aaa.jpg -ab 56 -ar 22050 -qmin 3 -qmax 8 -r 15 -qscale 7 aaa.flv";
        //执行ffmpeg.exe文件的时候不显示黑色的dos窗口
        p.StartInfo.CreateNoWindow = true;
        //执行线程
        p.Start();
        当线程启动的时候就会执行ffmpeg进行视频转换了

    2.如何取得ffmpeg的转换进度?
        要取得ffmpeg的转换进度不是一件容易的事情,因为ffmpeg没有提供直接取得转换进度的方法,我们只好开动脑瓜来实现它。能过上面第一张图,我们我们可以看到在转换过程中会产生一系列的数据,如果我们能够取到其中的数据,我们就可以解析出转换进度了。

    《图3》
        如何取得ffmpeg的转换进度呢?Process提供了两个事件ErrorDataReceivedOutputDataReceived来处理线程执行过程中的输出数据
        ......
        //启用错误输出
        p.StartInfo.RedirectStandardError = true;
        //启用标准输出
        //p.StartInfo.RedirectStandardOutput = true;
        //指定错误输出的处理程序
        p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);
        //指定标准输出的处理程序
        //p.OutputDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);
        ......
        p.Start();
        //读取错误输出信息
        p.BeginErrorReadLine();
        注意:在ffmpeg的执行过程输出数据全部以错误输出产生的(不知道这是什么原因),所以大家不要从标准输出中去取数据,那是取不出来的
        void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {

            if (!String.IsNullOrEmpty(e.Data))
            {
                //通过e.Data.ToString()来截取字符串获得有效信息
            }
        }

    3.如何在转换完成后删除原来的视频文件
    在转换完flv视频后,我们应当把原来视频文件删除,这又是一个问题。我们要确保视频已转换完毕后再删除原来的视频文件,否则由于原视频文件正在使用,会产生删除异常。视频转换的过程是以一个独立线程运行的,我们应当确保在视频转换线程结束后再执行删除,所以删除功能不应在视频转换线程中实现,而应在主线程中实现。(车延禄)
    主线程是如何知道视频转换线程执行完成了呢?
    我们可以使用Process对象的Exited事件来实现这个功能。Process对象的Exited事件是在线程执行结束并释放资源后才触发的。要想使这个事件生效需要设置Process对象的p.EnableRaisingEvents = true;,如果p.EnableRaisingEvents = false;则不会触发Exited事件。
        p.EnableRaisingEvents = true;
        p.Exited += new EventHandler(p_Exited);

        void p_Exited(object sender, EventArgs e)
        {
            File.Delete(Server.MapPath("Video/bbb.avi"));
        }

    三、在ASP.NET使用ffmpeg进行视频转换的参考代码
    配置文件:
        <appSettings>
            <add key="ffname" value="ffmpeg"/>
            <add key="cvt" value=" -i aaa.avi -y -s 400*300 -f image2 -ss 0 aaa.jpg -ab 56 -ar 22050 -qmin 3 -qmax 8 -r 15 -qscale 7 aaa.flv"/>
        </appSettings>

    转换代码:(车延禄)
       //读取配置文件中的ffmpeg命令和执行参数
        string exe = ConfigurationManager.AppSettings["ffname"].ToString();
        string str = ConfigurationManager.AppSettings["cvt"].ToString();

        string filename = Session["name"].ToString();
        //取出主文件名(不含扩展名)
        filename = filename.Substring(filename.LastIndexOf("\") + 1, filename.LastIndexOf(".")-filename.LastIndexOf("\")-1);
        //把原来的aaa.avi,aaa.jpg,aaa.flv等文件的主文件名换为当前主文件名
        str = str.Replace("aaa.avi", Server.MapPath("Video/")+filename+".avi");
        str = str.Replace("aaa.jpg", Server.MapPath("Over/Image/") + filename + ".jpg");
        str = str.Replace("aaa.flv", Server.MapPath("Over/Video/") + filename + ".flv");
        try
        {
            Process p = new Process();
            p.StartInfo.FileName = Server.MapPath("Libs\") + exe;//指定ffmpeg命令
            p.StartInfo.Arguments = str;    //指定ffmpeg参数
            p.StartInfo.UseShellExecute = false;    //输出信息重定向
            p.StartInfo.CreateNoWindow = true; //不产生dos对话框
            p.StartInfo.RedirectStandardError = true;   //重定向错误输出
            p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);   //指定错误输入处理函数
            p.EnableRaisingEvents = true;   //启用线程结束事件执行权
            p.Exited += new EventHandler(p_Exited); //指定线程结束事件处理函数
            p.Start();
            p.BeginErrorReadLine(); //产生数据时时,读取数据
        }
        catch (Exception ex)
        {
            Response.Write(ex.Message);
        }
        //当页面显示"OVER"时,只说明当前主线程执行到此处,但Process p线程正在处理视频,还没有结束。
        Response.Write("OVER");


        //当Process p被释放时触发该方法
        void p_Exited(object sender, EventArgs e)
        {
            File.Delete(Server.MapPath("Video/bbb.avi"));
        }

        //ffmpeg每产生一行输出数据就会触发一次该方法
        void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {

            if (!String.IsNullOrEmpty(e.Data))
            {
                //......更新数据库中字段,标识该视频为已转换完毕
            }

        }

  • 相关阅读:
    集合
    16
    最常使用Eclipse快捷键
    Java小菜的进阶之路(异常捕获与处理(一))
    0803作业
    0801作业
    java中this与super的见解
    7.27作业
    7.23作业
    java内部类的浅谈(错误之处还请见谅!)
  • 原文地址:https://www.cnblogs.com/fogwang/p/4552512.html
Copyright © 2011-2022 走看看