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

FFmpeg

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

ffmpeg.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:

 using System;
using System.Configuration;
using System.IO;
// reference https://github.com/LeafDuan/WebPrint/tree/master/WebPrint.Framework
using WebPrint.Framework;
// reference https://github.com/LeafDuan/WebPrint/tree/master/WebPrint.Logging
using WebPrint.Logging; namespace WebPrint.CameraServer.Helper
{
public class FfmpegHelper
{
private static readonly ILogger Logger = LoggerHelper.GetLogger(typeof (FfmpegHelper)); private static string Ffmpeg
{
get { return ConfigurationManager.AppSettings["ffmepg"]; }
} private static string Args
{
get { return ConfigurationManager.AppSettings["args"]; }
} private static string FlvPath
{
get { return ConfigurationManager.AppSettings["flv"]; }
} public static string DecodeMp4ToFlv(string mp4, int timeout = )
{
var ffmpeg = "\"{0}\"".Formatting(Ffmpeg);
var flv = Path.Combine(FlvPath, (Path.GetFileNameWithoutExtension(mp4) ?? string.Empty) + ".flv");
var args = Args.Formatting("\"{0}\"".Formatting(mp4), "\"{0}\"".Formatting(flv));
string output, error;
if (timeout <= )
timeout = **; // timeout = 5 minutes
ProcessHelper.Process(ffmpeg, args, timeout, out output, out error);
if (!error.IsNullOrEmpty())
{
Logger.Error("{0}{1} : {2}{0}".Formatting(Environment.NewLine, "FFmpeg", error));
} return flv;
}
}
}

倒是其中 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 是写得累死了。因为非专业前端,找资料都累死了。

感谢

感谢 @eflay 的解决思路,“通过转封装的方式,以复制的效率实现MP4转FLV”。本人不是很懂这些视频的编码,因此没有想到这么好的解决方式。

同时也找到了一篇很好的解决这个问题的文章 h264格式的flv和mkv无损转换成mp4的方法

利用 FFmpeg 将 MP4 转成 FLV的更多相关文章

  1. ffmpeg 转换 mp4 成 flv

    参考资料: https://addpipe.com/blog/flv-to-mp4/ ffmpeg -i demo.mp4 -c:v libx264 -crf 19 demo.flv 或者 ffmpe ...

  2. 利用Ffmpeg获得flv视频缩略图和视频时间的代码

    问题描述:获得flv视频的缩略图和视频时间长度 谷歌了半天发现可以使用Ffmpeg获得视频的一些信息,先介绍一下FFMEPG 这里简单说一下:FFmpeg是用于录制.转换和流化音频和视频的完整解决方案 ...

  3. (转)MP4文件两种格式AVC1和H264的区别及利用FFMPEG demux为h264码流事项

    出自:http://www.mworkbox.com/wp/work/314.html 2013-05-04 MP4的视频H264封装有2种格式:h264和avc1,对于这个细节,很容易被忽略.笔者也 ...

  4. 利用ffmpeg一步一步编程实现摄像头采集编码推流直播系统

    了解过ffmpeg的人都知道,利用ffmpeg命令即可实现将电脑中摄像头的画面发布出去,例如发布为UDP,RTP,RTMP等,甚至可以发布为HLS,将m3u8文件和视频ts片段保存至Web服务器,普通 ...

  5. Windows 下 ffmpeg 转 mp4

    最近在研究所有视频格式转  mp4 因为html5 只支持mov MP4 等格式..查阅了 很多资料发现  转成flv  很简单.. 可是要转 mp4 就难了... 经过我不屑的努力..终于转换成功了 ...

  6. 用java程序调用ffmpeg执行视频文件格式转换flv

    用java小例题说明更直观:(可以直接编译运行)环境我在windows平台下测试的...需要在e:/下有ffmpeg.exe;mencoder.exe;drv43260.dll;pncrt.dll共4 ...

  7. 利用FFmpeg玩转Android视频录制与压缩(二)<转>

    转载出处:http://blog.csdn.net/mabeijianxi/article/details/72983362 预热 时光荏苒,光阴如梭,离上一次吹牛逼已经过去了两三个月,身边很多人的女 ...

  8. 史林枫:C#.NET利用ffmpeg操作视频实战(格式转换,加水印 一步到位)

    ffmpeg.exe是大名鼎鼎的视频处理软件,以命令行参数形式运行.网上也有很多关于ffmpeg的资料介绍.但是在用C#做实际开发时,却遇到了几个问题及注意事项,比如如何无损处理视频?如何在转换格式的 ...

  9. 利用FFmpeg 将 rtsp 获取H264裸流并保存到文件中

    既然已经可以通过 RTSP 获取h264 裸流了.那么通过 FFmpeg 将其保存到文件中怎么做呢? 一.首先RTSP获取 h264 裸流 我们上面两篇文章主要讲的是通过 rtsp://Your ip ...

随机推荐

  1. day30 UDP协议

    本周安排 周二 socket编程 周三 粘包处理 周四 选课系统 并发编程 周五多道技术 多进程 周六 IPC 互斥锁 常用模块 os* 操作系统 多数是文件操作 os.path 处理文件路径 shu ...

  2. oracle wm_concat() 返回空

    参考 https://www.cnblogs.com/zengweiming/archive/2013/11/20/3433642.html select wm_concat(to_char(str) ...

  3. codeblocks17.12 不能启动调试器

    调试器需要手动指定. settings->debugger->default->executable path.这里默认空的,需要指定.路径在安装目录下的CodeBlocks\Min ...

  4. 条件编译ifndef、ifdef、endif

    1.条件编译命令最常见的形式为: #ifdef 标识符 程序段1 #else 程序段2 #endif 当标识符已经被定义过(一般是用#define命令定义),则对程序段1进行编译,否则编译程序段2.  ...

  5. 设置获取cookie,setCookie,getCookie

    设置cookie: function setCookie(name,value) { var Days = 30; var exp = new Date(); exp.setTime(exp.getT ...

  6. jackson java对象和json对象的互相转换

    概述 Jackson框架是基于Java平台的一套数据处理工具,被称为“最好的Java Json解析器”. Jackson框架包含了3个核心库:streaming,databind,annotation ...

  7. PAT L2-014 列车调度(最长上升nlogn)

    火车站的列车调度铁轨的结构如下图所示. 两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道.每趟列车从入口可以选择任意一条轨道进入,最后从出口离开.在图中有 ...

  8. 项目总结15:JavaScript模拟表单提交(实现window.location.href-POST提交数据效果)

    JavaScript模拟表单提交(实现window.location.href-POST提交数据效果) 前沿 1-在具体项目开发中,用window.location.href方法下载文件,因windo ...

  9. cloud server ribbon 自定义策略配置

    虽然ribbon默认为我们提供了多钟负载均衡策略,但有时候我们仍然需要自定义符合自身业务逻辑的规则 使用配置文件的方式:我们只需要在配置文件中添加配置 serviceId.ribbon.NFLoadB ...

  10. 畅谈Redis和Memcached的区别

    简述 memcached 和 redis 都很类似:都是内存型数据库,数据保存在内存中,通过tcp直接存取,优势是速度快,并发高,缺点是数据类型有限,查询功能不强,一般用作缓存. 那么题主说 memc ...