网站首页 > java教程 正文
随着自媒体兴起,许多人会自拍视频或者找视频素材裁剪,配上背景音乐或解说,加上各种特效边框,处理后再生成新的视频文件,发布到各大平台。生成的原始视频文件都很大,我们需要转换格式或者压缩大小,便于上传或者在其他如手机等设备上分享。
FFmpeg 介绍
FFmpeg是一款开源免费的多媒体视频处理工具,功能包括视频采集功能、视频格式转换、视频抓图、给视频加水印等。它提供了录制、转换以及流化音视频的完整解决方案。
FFmpeg项目在开源界的影响力也是数一数二的。几乎你所见到的视频转换软件或播放器中用到的功能或编码/解码都基于FFmpeg。它采用LGPL或GPL许可证,曾今国内某些知名播放器使用FFmpeg源码未声明,被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解压后有三个可执行文件:
- 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 可以看到全部参数说明。
GPU加速
FFmpeg默认使用CPU编码。执行ffmpeg命令时,资源管理器可以看到CPU使用率升高。
如果使用GPU运算,转换速度能成倍提高,特别是转换h265编码视频。
查看ffmpeg支持视频编码格式:
ffmpeg -codecs
找到 hevc ,也就是h265编码:
- hevc_qsv:intel核显
- hevc_nvenc:nvidia显卡
- hevc_amf:amd显卡
如果使用h264编码,使用 h264_qsv / h264_nvenc 。
ffmpeg -i ./video.mp4 -c:v hevc_qsv ./out.mp4
使用GPU编码,运行以上ffmpeg命令,可以看到GPU占用率升高。
使用GPU加速视频转换速度快了很多,我仅使用核显速度也比CPU转码也能快数倍。
ffprobe命令
ffprobe ./video.mp4
查看视频文件信息。
从输出信息可以看到该视频文件是使用h264编码,分辨率1280x720,视频平均码率921kbps,24帧。视频的音频使用aac编码,采样率44100Hz,码率128kpbs。
ffprobe -v error -show_streams -print_format json ./video.mp4
使用json格式输出视频信息。
ffplay命令
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
猜你喜欢
- 2025-01-21 有视频才有真相 两款录屏软件推荐
- 2025-01-21 第十三章:Java图形用户界面编程
- 2025-01-21 全新版Jetpack进阶提升,系统性落地短视频App|超清完结无秘
- 2025-01-21 如何实现在线视频播放?
- 2025-01-21 Java 中的屏幕共享
- 2025-01-21 用 Java 语言,写一个植物大战僵尸简易版
- 2025-01-21 JavaCV的摄像头实战之五:推流(我的直播梦)
- 2025-01-21 西瓜视频稳定性治理体系建设一:Tailor 原理及实践
- 2025-01-21 “易语言”基础知识——编写一个MP3播放器
- 2025-01-21 Spring Boot + Minio 去掉电影网站视频广告:基于 M3U8播放地址
你 发表评论:
欢迎- 最近发表
-
- 多种负载均衡算法及其Java代码实现
- 输入www.baidu.com背后经历了啥?说清楚这个,已经超过90%的人了
- 优化MySQL:为什么你应该用 UNSIGNED INT 存储IP地址
- 实模式下CPU如何获取数据及指令(实模式寻址方式)
- java基础都在这了,小主们拿去吧(java基础是指什么)
- 盘点爬虫语言为何选择Python而不是Java
- 搭载Dubbo+Zookeeper踩了这么多坑,我终于决定写下这篇
- 网络协议之TCP/IP协议(面试必考内容) - javaEE初阶 - 细节狂魔
- 深夜报警!10亿次请求暴击,如何用Redis找出最热IP?
- VPN技术(IPsec/L2TP/SSLVPN/PPTP)学习笔记
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)