zoukankan      html  css  js  c++  java
  • ffmpeg实现

    最近做一个小项目,要在线播放录制的 MP4 视频,想开源的 flash player 或 html 5 可以播放。可,虽然 MP4 是 H.264 编码,但就是播放不了。可能是封装方式(PS 方式)不一样吧。由于录制用的第三方设备,不能修改参数,只能自己使用工具转码了。

    FFmpeg

    网上一搜索,就找到了大名鼎鼎的 FFmpeg ,好像 google 的 youtube 后台也是用的这个转码,国内的很多视频播放器核心也是这个。有了这个实现起来就非常简单了。FFmpeg 转码时占用 CPU 很高,可以到 100%,也不知道该怎么解决此问题。转码只要一条指令就行了:

    ffmpeng.exe -i source.mp4 -c:v libx264 -crf 24 destination.flv

    这是最简单的设置,更多可以去官网看详细的参数,其中 -crf 很重要,是控制转码后视频的质量,质量越高,文件也就越大。

    The range of the quantizer scale is 0-51: where 0 is lossless, 23 is default, and 51 is worst possible. A lower value is a higher quality and a subjectively sane range is 18-28. Consider 18 to be visually lossless or nearly so: it should look the same or nearly the same as the input but it isn't technically lossless.

    官网的解释(翻译):

    此值的范围是 0 到 51:0 表示高清无损;23 是默认值(如果没有指定此参数);51 虽然文件最小,但效果是最差的。

    值越小,质量越高,但文件也越大,建议的值范围是 18 到 28。而值 18 是视觉上看起来无损或接近无损的,当然不代表是数据(技术上)的转码无损。

    Coding:

    实现起来也是很简单,只要使用 Processs 后台转码就行,请看 FfmpegHelper :

    复制代码
     1 using System;
     2 using System.Configuration;
     3 using System.IO;
     4 // reference https://github.com/LeafDuan/WebPrint/tree/master/WebPrint.Framework
     5 using VehicleVideo.Framework;
     6 // reference https://github.com/LeafDuan/WebPrint/tree/master/WebPrint.Logging
     7 using VehicleVideo.Logging;
     8 
     9 namespace VehicleVideo.CameraServer.Helper
    10 {
    11     public class FfmpegHelper
    12     {
    13         private static readonly ILogger Logger = LoggerHelper.GetLogger(typeof (FfmpegHelper));
    14 
    15         private static string Ffmpeg
    16         {
    17             get { return ConfigurationManager.AppSettings["ffmepg"]; }
    18         }
    19 
    20         private static string Args
    21         {
    22             get { return ConfigurationManager.AppSettings["args"]; }
    23         }
    24 
    25         private static string FlvPath
    26         {
    27             get { return ConfigurationManager.AppSettings["flv"]; }
    28         }
    29 
    30         public static string DecodeMp4ToFlv(string mp4, int timeout = 0)
    31         {
    32             var ffmpeg = ""{0}"".Formatting(Ffmpeg);
    33             var flv = Path.Combine(FlvPath, (Path.GetFileNameWithoutExtension(mp4) ?? string.Empty) + ".flv");
    34             var args = Args.Formatting(""{0}"".Formatting(mp4), ""{0}"".Formatting(flv));
    35             string output, error;
    36             if (timeout <= 0)
    37                 timeout = 5*60*1000; // timeout = 5 minutes
    38             ProcessHelper.Process(ffmpeg, args, timeout, out output, out error);
    39             if (!error.IsNullOrEmpty())
    40             {
    41                 Logger.Error("{0}{1} : {2}{0}".Formatting(Environment.NewLine, "FFmpeg", error));
    42             }
    43 
    44             return flv;
    45         }
    46     }
    47 }
    复制代码

    倒是其中 Process 的实现需要技巧,尤其是针对 output、error 和 timeout 的处理。如果不使用 AutoResetEvent ,process 很容易卡死在 error output 上(IO blocked)。其中针对超时,做了一个处理,就是 kill 掉 process ,免得引起资源霸占和泄露(过多 ffmpeg 进程)。

    附:Flash 推荐

    可以转码成 html 5 支持的 H.264,也可以其他格式,如 flv。为了兼容 IE6 及以上浏览器,只能使用 flash 播放的方式了。使用的是开源的 vcastr22.swf,可能由于开源,项目现在没有人维护了。

    最后吐槽一句:盼 IE9 以下的版本早日寿终正寝。为了随窗口以 16:9 的尺寸自动缩放,兼容 IE6、7 的 css 和 js 是写得累死了。因为非专业前端,找资料都累死了。
    转自http://www.cnblogs.com/ranmofang/p/4390712.html

  • 相关阅读:
    file is universal (3 slices) but does not contain a(n) armv7s slice error for static libraries on iOS
    WebImageButton does not change images after being enabled in Javascript
    ajax OPTION
    编程遍历页面上所有TextBox控件并给它赋值为string.Empty?
    获取海洋天气预报
    C#线程系列教程(1):BeginInvoke和EndInvoke方法
    js控制只能输入数字和小数点
    Response.AddHeader(,)
    ManualResetEvent的理解
    Convert.ToInt32、int.Parse(Int32.Parse)、int.TryParse、(int) 区别
  • 原文地址:https://www.cnblogs.com/liuwenbohhh/p/4390769.html
Copyright © 2011-2022 走看看