着自媒体兴起,许多人会自拍视频或者找视频素材裁剪,配上背景音乐或解说,加上各种特效边框,处理后再生成新的视频文件,发布到各大平台。生成的原始视频文件都很大,我们需要转换格式或者压缩大小,便于上传或者在其他如手机等设备上分享。
FFmpeg是一款开源免费的多媒体视频处理工具,功能包括视频采集功能、视频格式转换、视频抓图、给视频加水印等。它提供了录制、转换以及流化音视频的完整解决方案。
FFmpeg项目在开源界的影响力也是数一数二的。几乎你所见到的视频转换软件或播放器中用到的功能或编码/解码都基于FFmpeg。它采用LGPL或GPL许可证,曾今国内某些知名播放器使用FFmpeg源码未声明,被FFmpeg钉在历史的耻辱柱上。
FFmpeg提供源码,可自行编译。几乎所有发行版Linux仓库中已有FFmpeg,可以直接安装。
# debian/ubuntu
apt install ffmpeg
# redhat/centos/fedora'
yum install ffmpeg
或
dnf install ffmpeg
FFmpeg官方也提供二进制包:ffmpeg.org/download.html
推荐使用FFmpeg官方static二进制包,无需额外动态库,仅一个可执行文件官网下载后的FFmpeg解压后有三个可执行文件:ffmpeg、ffprobe、ffplay。
官网下载后的FFmpeg解压后有三个可执行文件:
ffmpeg -i video.wma ./video.mp4
把 video.wma 视频文件转换成 mp4 格式。ffmpeg mp4 格式默认使用h264编码
ffmpeg -i video.wma -c:v libx265 video.mp4
把 video.wma 视频文件转换成 h265 编码的 mp4 格式。
h265比h264编码有更高的压缩率,在低码率下生成的文件更小。
也就是说,相同质量下的h265编码比h264更清晰。相同大小的视频文件,h265编码比h264编码的视频文件体积更小。但是当视频码率到达一定大小时,两者清晰度区别不大。
h264比h265有更好的兼容性,有些手机默认不支持h265编码的视频文件,需要借助软件解码。
视频转换,h265编码比h264编码用时会更长,更消耗CPU资源。
ffmpeg -i video.mp4 -s 1280x720 video2.mp4
将视频压缩到1280x720分辨率。
ffmpeg -i video.mp4 -ss 00:00:10 -i video.mp4 -t 00:00:30 -c:v copy -c:a copy cut.mp4
不改变视频和音频的编码截剪视频,保留从视频10秒之后开始30秒,因为音频视频编码指定参数值copy,不会影响视频质量。
使用ss参数一定要在-i之前,如果写在-i之后,ffmpeg会理解为起始点是作用于输出文件。
ffmpeg -i video.mp4 -metadata:s:v rotate="90" -c:v copy -c:a copy out.mp4
不改变视频和音频的质量将视频翻转90度。把横屏变竖屏。
ffmpeg -f x11grab -r 30 -i :0.0 -f alsa -i hw:0,0 -acodec aac -vcodec libx264 out.mkv
使用FFmpeg录像,该命令在Linux上有效。每秒30帧,音频格式使用 aac,视频格式使用h264,输出mkv格式。
vcodec 与 c:v 参数一样,指定视频编码,如:libx264,libx265
acodec 与 c:a 参数一样,指定音频编码,如:aac,mp4,flac
FFmpeg还有很多其他用法,比如调整码率,帧数等。使用 ffmpeg --help 可以看到全部参数说明。
FFmpeg默认使用CPU编码。执行ffmpeg命令时,资源管理器可以看到CPU使用率升高。
如果使用GPU运算,转换速度能成倍提高,特别是转换h265编码视频。
查看ffmpeg支持视频编码格式:
ffmpeg -codecs
找到 hevc ,也就是h265编码:
如果使用h264编码,使用 h264_qsv / h264_nvenc 。
ffmpeg -i ./video.mp4 -c:v hevc_qsv ./out.mp4
使用GPU编码,运行以上ffmpeg命令,可以看到GPU占用率升高。
使用GPU加速视频转换速度快了很多,我仅使用核显速度也比CPU转码也能快数倍。
ffprobe ./video.mp4
查看视频文件信息。
从输出信息可以看到该视频文件是使用h264编码,分辨率1280x720,视频平均码率921kbps,24帧。视频的音频使用aac编码,采样率44100Hz,码率128kpbs。
ffprobe -v error -show_streams -print_format json ./video.mp4
使用json格式输出视频信息。
ffplay ./video.mp4
播放视频文件。这时会弹出一个播放器。
ffplay命令还有很多控制参数。不过我觉得用处不大,毕竟图形化播放器更好用,功能也更强大。
使用FFmpeg命令,我们可以用程序或脚本完成视频自动转换。也可以让我们开发的系统拥有视频转码,或读取视频信息的功能。以Java示例:
public static int doWaitFor(Process process) {
InputStream in=null;
InputStream err=null;
int exitValue=-1; // returned to caller when p is finished
try {
in=process.getInputStream();
err=process.getErrorStream();
boolean finished=false; // Set to true when p is finished
while (!finished) {
try {
while (in.available() > 0) {
// Print the output of our system call
Character c=new Character((char) in.read());
System.out.print(c);
}
while (err.available() > 0) {
// Print the output of our system call
Character c=new Character((char) err.read());
System.out.print(c);
}
// Ask the process for its exitValue. If the process
// is not finished, an IllegalThreadStateException
// is thrown. If it is finished, we fall through and
// the variable finished is set to true.
exitValue=process.exitValue();
finished=true;
} catch (IllegalThreadStateException e) {
// Process is not finished yet;
// Sleep a little to save on CPU cycles
Thread.currentThread().sleep(500);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (in !=null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (err !=null) {
try {
err.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return exitValue;
}
Java调用外部命令使用 Runtime.getRuntime().exec(command) 。
在使用调用ffmpeg命令时,必须要读取执行命令输出流中的内容,程序才不会阻塞。否则缓冲读满后,进程会卡住。
视频转换会非常耗时,取决于硬件性能。在实际应用中,我们也可以开启线程去处理。
FFmpeg还提供C调用,公共库集成。以上方法并不是最优解决方案,仅提供一种参考。
除非注明,否则均为"攻城狮·正"原创文章,请注明出处。
本文链接:https://engr-z.com/422.html
着手淘拉新和用户体量的增加,CDN图片资源的访问量也随之增加。我们知道访问量增加,会带来带宽的增加,服务器成本也随之增加。同时新增的用户,喜好各不相同,为了满足不同用户的喜好,商家会修改主图样式来吸引消费者。如何缓解用户增长带来的带宽压力和满足商家和用户的多样化需求呢?针对这两个问题,图片库和图片空间同学对客户端和服务端做了相应的改造来解决这些问题,主要的做法是H5HEIC化以及图片库磁盘缓存标准化。
? HEIC是什么
HEIF是一种图像容器格式,它所生成的图像文件相对较小,且图像质量也高于较早的JPEG标准。HEIF这种新的图像格式基于高效视频压缩格式(也称为HEVC或H.265),它通过使用更先进的压缩算法来实现图片的压缩存储。
从2018年开始手淘的native页面已经全面支持HEIC,为CDN侧节省了大量流量,优化了用户的图片体验。native页面可以HEIC化需要满足两个条件:
目前从统计来看淘内的图片40%已经使用了HEIC,为什么只有40%的量?一方面是因为手淘部分业务的图片不是放在图片空间做处理,比如有的业务使用TFS来做存储,另一方面是手淘使用的H5内核目前无法解码HEIC图片。说到这里需要简单介绍下手淘的图片的业务流程:
以上只是简单的示意,大体展现图片如何从商家流动到用户的,主要的中转便是图片空间它可以对图片进行处理和转化。用户使用手淘客户端访问页面时,业务会将商品图片url传递给图片库,图片库会对传入的url做处理,按照图片空间的规则拼接上HEIC后缀,这样当url到达CDN时,如果有HEIC图片缓存直接返回,如果没有会请求图片空间的服务将原始图片转码成heic图片。以上是native的流程,我们还忽略了另一个流量来源H5,目前手淘H5容器无法使用HEIC解码器,所以没有进行HEIC化。
为什么今年可以做H5页面HEIC化了呢?主要是以下两个方面:
有同学可能会好奇,之前提到的图片空间是什么?图片空间可以看作是提供强大图片处理能力的服务。从上一小节的流程图可以看出CDN后面是图片空间,这里简单介绍下图片空间和CDN之间的关系。当有图片请求访问到CDN时,CDN会查找当前缓存中有没有这个请求需要的图片,如果有直接从CDN中返回,如果没有CDN会去请求图片空间处理原图给出符合要求的图片,然后再返回给CDN,同时CDN会对这张图片做缓存,当下次有相同的请求过来时就直接返回缓存的图片,不再回源到图片空间,缩短请求响应时间。
首先介绍下UC内核外接三方解码器能力,这个能力是如何实现的呢?简单来说就是提供实现UC规定接口的so文件(保证规定的函数符号会被正确导出),UC内核会使用dlopen打开so,同时获取接口函数的函数指针,当需要解码时直接使用函数指针直接调用即可。下面是大体的调用流程以及相关的接口定义:
简短介绍下上图蓝框的流程:
之前从事过PC开发的同学可能会熟悉这这种做法,PC插件化大多是利用dll(可以理解为Linux下的so)来实现,这在PC时代是常用做法,Python调用C++/C代码也可以通过封装为so进行调用。针对UC提供的这种能力,图片库对原有的HEIC解码器做了封装,实现了上面的接口规范,提供给UC调用,这样H5解码HEIC的问题就解决掉了。
真的这么顺利么?答案是No。手淘目前对so集成时的大小有限制,刚好HEIC的32位和64位so加起来将近4.5MB,这已经是严重超标了,是不可以接受的。
那该如何解决呢?架构组提供了远程加载so组件(上图中的远程下载),可以将so放在远程,不需要打进apk包,当需要的时候从远程下载,同时HEIC解码so是独立的没有依赖,直接dlopen打开就可以使用。这样我们的解码功能就顺利完成了,剩下的工作就需要Windvane同学添加相应的降级逻辑和监控逻辑提供必要的稳定性保障,到这里这个H5支持HEIC功能就完成了。
说了这么多从native支持HEIC到H5支持HEIC,收益是什么呢?有两个方面,一个是端上的收益,一个是服务端收益:
客户端
目前端上的计算能力已不是瓶颈,主要是网络的通信时间,图片体积越小,网络耗时越少,同时网络耗时的减少可以抵消端上解码耗时的增加,总体而言图片的加载性能会提高。同理对于H5页面也一样,网络耗时越少,页面性能也会有所提高。
服务端
对于服务端而言,图片的体积更小,占用的带宽也更小,单位时间内处理的请求增加,简单来说就是提高了QPS。
H5支持HEIC这个功能已经灰度了几个版本,后续会逐步全量,对于H5页而而言,页面性能也会得到提升。
我们可以先参考下native页面下HEIC图片和WEBP图片的下载时间和解码时间的对比数据:
数据说明:样本数在几十万级别,基本可以抹平图片尺寸带来的统计差异。
从上面的数据也可以表明,网络时间的优化可以抵消部分解码时间的增加,有的同学看到数据会有疑问,解码时间并没有增加反而有所优化,这主要是多媒体算法团队对HEIC解码做了优化,同时图片空间空间同学对HEIC的封装做了优化(优化的后的封装,仍然是符合HEIF文件标准的)。
? 图片库磁盘缓存标准化
用过Phenix图片库或者三方开源图片库的同学都知道,图片库会有三层缓存(内存、磁盘、网络),磁盘缓存一般是持久化的,除非超过磁盘缓存大小被LRU淘汰掉,为了满足图片空间的需求,图片库对磁盘缓存做了改造。大体流程如下:
简单来说图片库的磁盘缓存可以指定过期时间,过期后图片请求会打到后端。图片空间会在图片响应头里添加过期字段来控制本次请求到的图片在磁盘缓存中存在的时长。目前实现的缓存控制是在原先LRU基础上实现的,即首先会判断这张图片有没有被LRU淘汰掉,如果没有被淘汰掉会走到缓存控制逻辑,如果已经被LRU淘汰,保持原有逻辑。
有同学可能会疑惑这么做有什么意义的呢?之前LRU策略图片更新时间是不确定的,有可能很快就过期了也有可能要等几十小时才能过期,完全取决于用户访问的频次以及用户的操作习惯,过期时间字段可以精确到小时级别,让图片及时过期,请求到最新的图片。
? URL不变更新图片
看到这个标题很多同学可能会有疑惑,URL不变更新图片是什么意思?简单来说就是访问相同的图片url图片的内容可能不同,经过这么一解释有的同学可能更加疑惑,为什么要这么做?
带着这个疑问我们来解释为什么会有这样的功能,促销对手淘来说比较常见,商家也会抓住这个机会尽可能吸引消费者去下单,提高成交量。图片作为手淘商品的主要信息载体,有活动的时候商家为了能够传递更多的信息给消费者,商家会频繁修改商品主图的促销样式和信息来吸引消费者去点击,更多的点击意味这更高的流量,从而带来更高的成交量。商家通过图片空间修改商品主图,图片空间会将修改后的主图URL更新到商品服务,但是这给商品服务带来了挑战,手淘承载着成千上万商家,如果促销期间大量商家去更新商品主图URL,对商品服务带来的压力不可小觑(不止主图更新会调用商品服务,其他业务也会去调用),因此在大促期间为了保证商品服务的稳定性,会进行必要的限流。大体流程如下图:
这样商家在特定的时间是不能及时修改商品图的,这会导商家和消费者的体验下降,因为主图的促销信息不能及时更新,导致主图显示的优惠信息和实际购买的优惠信息有可能会有偏差。这该如何解决呢?活动期间商家改图后商品主图URL不变,图片空间会将修改的图片更新到CDN,不再去频繁刷商品服务,商品服务的压力也会减小,消费者的体验也得到了保障。修改后的流程如下图:
有同学可能会有疑问,为什么不是提升商品服务的性能呢?以下是我简单的分析,不一定准确:数据库的写性能是有限的,无论再怎么优化再怎么加机器,大量的并发过来总会达到瓶颈。有的同学可能会说,分布式、分库、一致性哈希,或许可以做也可以解决问题,可是大促是短期行为,做这么大的改造耗费大量的人力成本,但是对非大促,这样的改造没有收益,同时也会增加系统的复杂度。
通过这样小成本的改造,将一部分流量转移到CDN侧,减轻了商品服务的压力同时也能提升商家和消费者的体验,商家也可以随时更新商品主图。
说了这么多图片库做了什么?一开始介绍的图片库磁盘缓存标准化,大促期间图片空间会在下发图片的Response中带上过期时间字段,设置一个合理的过期时间,便于大促期间商品主图的磁盘缓存隔一段时间过期一次,过期后请求新的图片,这样用户看到的图片始终是最新的,虽做不到实时但也可以达到小时级,能够满足业务的诉求。
今年图片库的主要改动有两个方面:H5支持HEIC化以及图片库磁盘缓存标准化,这两个改造从本质上来说是将服务端的优化通过端上整合触达到用户。HEIC图片native端在2018年就已经开始支持,但是由于H5容器UC内核当时没有HEIC解码能力,所以H5页面没有使用HEIC,今年随着UC对外提供了三方解码插件的功能,利用这个契机将H5页面进行HEIC化。图片库磁盘缓存标准化。
ediaHuman Video Converter是一款视频格式转换工具,可以帮助用户进行视频格式的转换,软件支持各种视频格式,轻松进行视频之间的互换,软件甚至还支持4K格式的转换,在转换过程中不会对视频的画质造成损坏,让用户在转换后也能享受到高清的视频内容。
软件介绍
MediaHuman Video Converter中文版是一款优秀的视频转换工具,支持将您电脑中或者下载的视频文件进行轻松转换,可以轻松转换任何视频格式,包括:音频视频交错(AVI),数字视频,DVD视频等。支持多个格式选择,可以转换4K MOV格式,也可以转换4K MKV、H.265、 HEVC、HD等类型的格式。
来源:http://www.3h3.com/soft/218168.html
*请认真填写需求信息,我们会在24小时内与您取得联系。