zoukankan      html  css  js  c++  java
  • asp.net C#调用mencoder处理视频的方法

    话说,视频处理还是比较容易折腾的东西。但是,困难在,如果准确的把错误捕获到。这个程序虽然没有写全,但大体上都给出了。具体的原理:使用Process调用shell执行外部的编码程序。

    而且,现在比较好的转换程序也只有mencoder和FFMpeg这两个。这两个最牛的一点,就是必须进行命令行模式进行处理视频的牛X物品。所以,当我们调用shell执行这两个东西的时候,我们只看到了CPU狂被占用,却看不到最终结果到底执行的怎么样了。啊,俺的心哪,再次被你深深的伤害了。如果这样占用CPU的话,那服务器不就那啥了?而且,如果好几个用户都上传了这视频,那服务器……不行,俺的心沉底碎啦!

    不管怎么说,这个的确是比较好的方法,以上的问题,我还在寻找解决方案。不知道多会才能真正的解决的说......

    异步读取输出信息的代码...

    public void ConvertVideo(string str)
        {
            Process p = new Process();//建立外部调用线程  
            p.StartInfo.FileName = @"d:\p\mencoder.exe";//要调用外部程序的绝对路径  
            p.StartInfo.Arguments = " " + str; //参数(这里就是FFMPEG的参数了)  
             p.StartInfo.UseShellExecute = false;//不使用操作系统外壳程序启动线程(一定为FALSE,详细的请看MSDN)  
                 p.StartInfo.RedirectStandardError = true;// 把外部程序错误输出写到StandardError流中(这个一定要注意,FFMPEG的所有输出信息,都为错误输出流,用StandardOutput 是捕获不到任何消息的...这是我耗费了2个多月得出来的经验...mencoder就是用standardOutput来捕获的)  
                 p.StartInfo.CreateNoWindow = false;//不创建进程窗口  
                 p.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN  
                 p.Start();//启动线程  
                 p.BeginErrorReadLine();//开始异步读取  
                 p.WaitForExit();//阻塞等待进程结束  
                 p.Close();//关闭进程  
                 p.Dispose();//释放资源   
        } 
         private void Output(object sendProcess, DataReceivedEventArgs output)  
         {  
            if (!String.IsNullOrEmpty(output.Data))  
            {  
                     //处理方法...  
                Response.Write(output.Data);
             }  
        }  

    引用
    BeginErrorReadLine 可同步或异步读取 StandardError 流。Read、ReadLine 和 ReadToEnd 等方法对进程的错误输出流执行同步读取操作。这些同步读取操作只有在关联的 Process写入其 StandardError 流或关闭该流后才能完成。相反,BeginErrorReadLine 在 StandardError 流上开始异步读取操作。此方法会为流输出启用指定的事件处理程序并立即返回到调用方,这样当流输出被定向到该事件处理程序时,调用方还可以执行其他操作。 按照这些步骤对 Process 的 StandardError 执行异步读取操作: 将 UseShellExecute 设置为 false。 将 RedirectStandardError 设置为 true。 向 ErrorDataReceived 事件添加事件处理程序。事件处理程序必须与 System.Diagnostics.DataReceivedEventHandler 委托签名相匹配。 启动 Process。 调用 Process 的 BeginErrorReadLine。此调用将启动 StandardError 上的异步读取操作。 启动异步读取操作时,关联的 Process 每向其 StandardError 流写入一行文本时,都将调用该事件处理程序。可通过调用 CancelErrorRead取消异步读取操作。可通过调用方或事件处理程序取消读取操作。取消之后,可以再次调用 BeginErrorReadLine 继续进行异步读取操作。 ErrorDataReceived 事件指示关联的进程已写入其重定向 StandardError 流中。该事件仅在对 StandardError 进行异步读取操作期间发生。若要启动异步读取操作,必须重定向 Process 的 StandardError 流,向 ErrorDataReceived 事件添加事件处理程序,并调用 BeginErrorReadLine。之后,每当该进程向重定向 StandardError 流中写入一行时,ErrorDataReceived 事件都会发出信号,直到该进程退出或调用 CancelErrorRead为止。  


    同步读取输出信息的代码...

        public void ConvertVideo(string str)
        {
            Process p = new Process();//建立外部调用线程  
            p.StartInfo.FileName = @"d:\p\mencoder.exe";//要调用外部程序的绝对路径  
            p.StartInfo.Arguments = " " + str; //参数(这里就是FFMPEG的参数了)  
            p.StartInfo.UseShellExecute = false;//不使用操作系统外壳程序启动线程(一定为FALSE,详细的请看MSDN)  
            p.StartInfo.RedirectStandardError = true;// 把外部程序错误输出写到StandardError流中(这个一定要注意,FFMPEG的所有输出信息,都为错误输出流,用StandardOutput 是捕获不到任何消息的...这是我耗费了2个多月得出来的经验...mencoder就是用standardOutput来捕获的)  
            p.StartInfo.CreateNoWindow = false;//不创建进程窗口  
            p.Start();//启动线程  
            p.WaitForExit();//等待完成  
            p.StandardError.ReadToEnd();//开始同步读取  
            p.Close();//关闭进程  
            p.Dispose();//释放资源  
        } 

    引用
    StandardError 可以同步或异步读取重定向的 StandardError 流。Read、ReadLine 和 ReadToEnd 等方法对进程的错误输出流执行同步读取操作。这些同步读取操作只有在关联的 Process 写入其 StandardError 流或关闭该流后才能完成。相反,BeginErrorReadLine 在 StandardError 流上开始异步读取操作。此方法为流输出启用一个指定的事件处理程序并立即返回到调用方,这样当流输出被定向到该事件处理程序时,调用方可以执行其他操作。 同步读取操作在读取 StandardError 流的调用方及写入该流中的子进程之间引入一个依赖项。这些依赖项可能导致产生死锁情况。调用方读取子进程的重定向流时依赖于该子进程。调用方将等待读取操 作,直到子进程写入流或关闭流为止。子进程写入足够多的数据以填充重定向流的时间依赖于父进程。子进程将等待下一次写操作,直到父进程读取了全部流或关闭 该流为止。当调用方和子进程相互等待对方完成操作时,就会产生死锁情况,使双方都无法继续执行操作。您可以通过计算调用方和子进程之间的依赖项从而避免出 现死锁情况。


    我在.NET 2.0中用这些代码,调用FFMPEG很方便...

    至于同步还是异步...我会选择异步的...因为异步很方便,有信息就会自动输出...输出的信息还可以经过特定的处理代码,把进度等信息显示出来...至于代码怎么写,无非就是文本处理操作...什么indexof,substring或者正则表达式之类的...

    这只是代码模型而已,可以引申出更高级的处理类,例如多线程调用,多线程并发处理,自动搜索数据库里没转换的内容转换,根据列表转换等...


    如果需要mencoder ,请使用这个链接下载:http://www.presscott.com.cn/other/package.rar 记得用迅雷下载,不然你只能空欢喜一场的说。ftp://ftp.mplayerhq.hu/MPlayer/contrib/win32/ 这里的版本比较全,你可以找你何时得下载。匿名FTP啊~
    官网:http://www.mplayerhq.hu/

    如果需要FFMpeg,http://down1.chinaunix.net/distfiles/ 去下载。最新版本是没有编译出来的,所以新版本请自己编译吧。
    官网:http://ffmpeg.org/index.html

    俺这blog中有一篇关于编译这东西的一个教程,而且非常全面,您可以毫不吝啬的去观赏哦~
    http://1229363.blog.163.com/blog/static/197434272009712241577/
  • 相关阅读:
    【基础】jquery全选、反选、全不选代码
    【基础】jquery全选、反选、全不选代码
    收集一些程序员励志经典名言
    收集一些程序员励志经典名言
    收集一些程序员励志经典名言
    防止表单重复提交的解决方案整理
    Git使用教程
    2019牛客暑期多校训练营(第二场)J Subarray
    Hibernate-配置
    与项目欧拉速度比较:C vs Python与Erlang vs Haskell
  • 原文地址:https://www.cnblogs.com/top5/p/1685463.html
Copyright © 2011-2022 走看看