快捷导航
 
查看: 3437|回复: 0

FFmpeg音视频转换工具

[复制链接]

39

主题

0

回帖

0

积分

8K盟主

Rank: 9Rank: 9Rank: 9

积分
0

最佳新人活跃会员热心会员推广达人宣传达人灌水之王突出贡献优秀版主荣誉管理论坛元老

QQ
发表于 2024-4-18 19:58:27 | 显示全部楼层 |阅读模式 IP:湖南湘西土家族苗族自治州
-
软件名称:FFmpeg
操作系统:Windows系统
软件类别:图像视频处理软件
软件大小:22.15M
下载地址:点击访问
提取码:登录查看
FFmpeg用于录制、转换和流式传输音频和视频的完整的跨平台解决方案
屏幕截图 2024-04-18 195412.png
简易教程1:
[Bash shell] 纯文本查看 复制代码
#安装
ffmpeg是一款处理视频的软件,包含常用的转码,截图等功能。

转码部分包含转换成我们常用的mp4格式,m3u8格式,m3u8+key格式。m3u8直播格式等

官网:[url=https://ffmpeg.org/]https://ffmpeg.org/[/url]

安装方法很简单,以windows为例,下载ffmpeg放到任意文件夹里即可。需要注意的就是如果需要用到加密key的m3u8,则需要将ffmpeg添加到环境变量中。

比如您将ffmpeg安装在D盘下,添加到环境变量中的路径应该为:D:\ffmpeg\bin,关于怎么添加环境变量,请自行搜索教程

如果不安装到环境变量,则使用时需要点击系统>运行,输入cmd,调出cmd窗口,输入d:(回车),输入 cd ffmpeg(回车),下面就可以执行下面的命令进行转码操作

#ffmpeg的简单使用
一:将input.avi转换成output.mp4:

ffmpeg -i input.avi output.mp4

二:增加一些要求:

ffmpeg -threads 4 -i input.avi -ab 32 -flags +loop  -vol 200 -vf yadif input.mp4

-ab:设置比特率

-vol:音量提高到200%

三:转码时修改尺寸:

ffmpeg  -i input.avi -s 640x320 input.mp4

四:将视频转成m3u8点播文件

ffmpeg.exe -i input.avi -strict -2  -hls_time 10 -hls_list_size 0 -c:v libx264 -c:a aac -f hls input.m3u8

-hls_time 10:每个ts文件10秒左右。这个会根据具体情况,尽量维系在10秒一个ts

-hls_list_size 0:m3u8索引里保留所有的ts路径

五:将视频转成加密的m3u8点播文件

ffmpeg -i input.mp4 -c copy -bsf:v h264_mp4toannexb -hls_time 10 -hls_list_size 0 -hls_key_info_file key_info input.m3u8

key_info需要替换成自己的路径,因为需要加密,所以需要准备二个文件一个是:key.key,一个是key_info。详细的不在这里作介绍,如果有兴趣可以看视频实际了解详细使用方法。

六:截图:

ffmpeg -ss 00:02:06 -i input.mp4 -f image2 -y poster.jpg

-ss:截图的时间点

七:连续截图:

ffmpeg -y -i input.mp4 -vf "fps=1/2,scale=iw/4:-1,tile=10x10" -an %d.png

fps=1/2:每2秒截一张图,如果是每秒截一张的话应该是fps=1

scale:所截图片大小,上面的代码是设置宽为原始的1/4大小,高度自动,相当于iw/4:ih/4,也可以设置成固定值如120:80

tile:网格化,自动将100张图合并成一张大图

八:连续截图的另外一个方法

ffmpeg -i my_dream.mp4 -vf fps=1/2 -q:v 2 -s 120x67 preview/%d.png

fps=1/2:每2秒截一张图,如果是每秒截一张的话应该是fps=1

-s:尺寸

这种方式截出来的是小图,需要自己再拼合。
-----------------------------------------------
MP4=>m3u8 15秒
./ffmpeg -i ./input.mp4 -c:v libx264 -c:a aac -strict -2 -f hls -hls_list_size 0 -hls_time 15 ./onput/output.m3u8
MP4=>m3u8 2秒 完整 -hls_list_size 0
./ffmpeg.exe -i ./2.mp4 -force_key_frames "expr:gte(t,n_forced*2)" -strict -2 -c:a aac -c:v libx264 -hls_time 2 -f hls -hls_list_size 0 ./onput/index.m3u8
简易教程2:
[Bash shell] 纯文本查看 复制代码
FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。它提供了录制、转换以及流化音视频的完整解决方案。

一、MP4 转 M3U8
M3U8 是 Unicode 版本的 M3U,用 UTF-8 编码。”M3U” 和 “M3U8” 文件都是苹果公司使用的 HTTP Live Streaming(HLS) 协议格式的基础,这种协议格式可以在 iPhone 和 Macbook 等设备播放。

简单来说,m3u8是一个视频格式,就是将一个视频分成很多的小部分,这样方便视频的加载。

1、操作简单,但效率低
ffmpeg -i input.mp4 -c:v libx264 -c:a aac -strict -2 -f hls -hls_list_size 2 -hls_time 15 output.m3u8
生成的效果是:

将 input.mp4 视频文件每 15 秒生成一个 ts 文件,最后生成一个 m3u8 文件,m3u8 文件是 ts 的索引文件。

我们直接用 VLC media player 等播放软件是可以直接打开 m3u8 文件,像播放 mp4 一样。

默认的每片长度为 2 秒,m3u8 文件中默认只保存最新的 5 条片的信息,导致最后播放的时候只能播最后的一小部分(直播的时候特别注意)。
-hls_time n 设置每片的长度,默认值为 2,单位为秒。
-hls_list_size n 设置播放列表保存的最多条目,设置为 0 会保存有所片信息,默认值为5。
-hls_wrap n 设置多少片之后开始覆盖,如果设置为0则不会覆盖,默认值为0。这个选项能够避免在磁盘上存储过多的 片,而且能够限制写入磁盘的最多的片的数量。
-hls_start_number n 设置播放列表中 sequence number 的值为 number,默认值为 0。
注意:播放列表的 sequence number 对每个 segment 来说都必须是唯一的,而且它不能和片的文件名(当使用 wrap 选项时,文件名有可能会重复使用)混淆。

2、效率优化版,提升效率
TS 文件是一种媒体的扩展名,它是日本高清摄像机拍摄下进行的封装格式。MPEG2-TS(Transport Stream“传输流”;又称TS、TP、MPEG-TS 或 M2T)是用于音效、图像与数据的通信协定,最早应用于DVD的实时传送节目。MPEG2-TS格式的特点就是要求从视频流的任一片段开始都是可以独立解码的。

# 1.视频整体转码ts
ffmpeg -y -i music.mp4  -vcodec copy -acodec copy -vbsf h264_mp4toannexb out\music.ts
# 2. ts 文件切片
ffmpeg -i music.ts -c copy -map 0 -f segment -segment_list out\music.m3u8 -segment_time 10 out\15s_%3d.ts
3、hls_time 切片时间不准确的问题
播放 m3u8 的 ts 切片,必须要完整的下载一个 ts 切片,才能够播放,设置hls_time 的时间间隔越短越好( 根据实际情况来 ),实际过程中设置切片时间间隔为 2 秒,调用如下指令:

ffmpeg -i test.mp4 -c:v libx264 -c:a aac -strict -2 -f hls -hls_time 2 index.m3u8
但没有按照参数输入,进行切片。

原因:

ts 文件的切割,还跟原文件视频的 GOP 大小有关系(也就是两个 I 帧之间的时间间隔),因为任何一个 ts 分片第一帧必须是I帧,否则无法最快播放,并且第一帧不是 I 帧,对于播放器也是没有任何的意义,直接被播放器扔掉。任何一个视频流必须在获取到第一个I帧才能成功解码出图片。虽然指定了 1 秒切割一个 ts 文件,实际上,由于原视频流可能好几秒才有一个 I 帧,所以必须等到下一个 I 帧,才会重新开始切片。

解决:

既然知道要1秒产生一个ts分片,那就必须产生切片的过程中,强制一秒中产生一个关键帧。

设置关键帧间隔,设置间隔为 2 秒的参数如下:-force_key_frames "expr:gte(t,n_forced*2)“

完整指令如:

ffmpeg -i test.mp4 -force_key_frames "expr:gte(t,n_forced*2)" -strict -2 -c:a aac -c:v libx264 -hls_time 2 -f hls index.m3u8
本文福利, 免费领取C++音视频学习资料包、技术视频/代码,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,编解码,推拉流,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

 

4、m3u8 格式解析
完整的 m3u8 文件有三部分:

index.m3u8,保存视频的基本信息和分段文件顺序;
key,如果视频加密,保存密钥;
data文件,其他都是视频的数据文件。
具体内容解析:

#EXTM3U,是文件开始
#EXT-X-VERSION,标识HLS的协议版本号;
#EXT-X-TARGETDURATION,表示每个视频分段最大的时长(单位秒);
#EXT-X-MEDIA-SEQUENCE,表示播放列表第一个 URL 片段文件的序列号;
#EXT-X-PLAYLIST-TYPE,表明流媒体类型;
#EXT-X-KEY,加密方式,这里加密方式为AES-128,同时指定IV,在解密时需要;
#EXTINF,表示其后 URL 指定的媒体片段时长(单位为秒)。
二、播放演示


HLS 的工作原理是把整个流分成一个个小的基于 HTTP 的文件来下载,每次只下载一些。

当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率。

在开始一个流媒体会话时,客户端会下载一个包含元数据的 extended M3U (m3u8) playlist文件,用于寻找可用的媒体流。

HLS 只请求基本的 HTTP 报文,与实时传输协议(RTP)不同,HLS 可以穿过任何允许 HTTP 数据通过的防火墙或者代理服务器。

它也很容易使用内容分发网络来传输媒体流。

三、m3u8(ts) 合并为 MP4
远程文件
ffmpeg -i “[url=https://xushanxiang.com/demo/ffmpeg/hls265/output.m3u8]https://xushanxiang.com/demo/ffmpeg/hls265/output.m3u8[/url]” -vcodec copy -acodec copy -absf aac_adtstoasc output.mp4
本地文件
1、打开 cmd

2、输入指令,按照文件的实际路径合并

合并成 ts文件 copy /b  F:\f\*.ts  E:\f\new.ts

合并成 MP4 文件 copy /b  F:\f\*.ts  E:\f\new.MP4

而通过 ffmpeg 命令如下:

直接转:
ffmpeg -i new.ts -c copy -map 0:v -map 0:a output.mp4

指定音频流(一般用这个):
ffmpeg -i new.ts -c copy -map 0:v -map 0:a -bsf:a aac_adtstoasc output.mp4

重编码视频:
ffmpeg -y -i new.ts -c:v libx264 -c:a copy -bsf:a aac_adtstoasc output.mp4

php实现代码
$url = 'https://******.m3u8?Expires=1585381145&OSSAccessKeyId=******&Signature=******';
 
$ts_content = file_get_contents($url);
$ts_content = explode(',', $ts_content);
$ts_file = array();
 
foreach ($ts_content as $key => $value) {
    if($key == 0) continue;
    $value = trim($value);
    $ts_file[] = substr($value, 0, strpos($value, '.ts') + 3);
}
 
$url_prefix = substr($url, 0, strpos($url, '.m3u8'));
$url_prefix = substr($url, 0, strrpos($url, '/') + 1);
$file_content = '';
 
foreach ($ts_file as $key => $value) {
    $file_content .= file_get_contents($url_prefix . $value);
}
 
file_put_contents('tmp_out.ts', $file_content);
 
// FFMPEG_PATH 是你自己解压ffmpeg的bin路径,例如我的是F:/ffmpeg/bin/
exec(FFMPEG_PATH . "ffmpeg -i tmp_out.ts tmp_out.mp4");
实例1:
[Bash shell] 纯文本查看 复制代码
@echo off
dir /b .\input >1.txt
for /f "delims=." %%i in (1.txt) do (
echo 开始切片
rem PAUSE
set FFMPEG_PATH="D:\SSL_TOOLS\ffmpeg\bin\ffmpeg.exe"
md %%i
.\ffmpeg.exe -i .\input\%%i.mp4 -c:v libx264 -c:a aac -strict -2 -f hls -hls_list_size 0 -hls_time 20 .\%%i\%%i.m3u8
echo 切片完成
rem PAUSE
)
del 1.txt
实例2:
[Bash shell] 纯文本查看 复制代码
@echo off
:qiepian
setlocal
set FFMPEG_PATH="D:\SSL_TOOLS\ffmpeg\bin\ffmpeg.exe"
set /p INPUT_FILE="文件名称:"
md %INPUT_FILE%
set /p DURATION="切片秒数:"
%FFMPEG_PATH% -i ./%INPUT_FILE%.mp4 -c:v libx264 -c:a aac -strict -2 -f hls -hls_list_size 0 -hls_time %DURATION% ./%INPUT_FILE%/%INPUT_FILE%.m3u8
echo 切片完成
endlocal
PAUSE
goto qiepian
实例3:
[AppleScript] 纯文本查看 复制代码
@echo off
:qiepian
setlocal
set FFMPEG_PATH="D:\SSL_TOOLS\ffmpeg\bin\ffmpeg.exe"
set /p INPUT_FILE="文件名称:"
md %INPUT_FILE%
set /p DURATION="切片秒数:"
%FFMPEG_PATH% -i ./%INPUT_FILE%.rmvb -c:v libx264 -c:a aac -strict -2 -f hls -hls_list_size 0 -hls_time %DURATION% ./%INPUT_FILE%/%INPUT_FILE%.m3u8
echo 切片完成
endlocal
PAUSE
goto qiepian
实例4:
[AppleScript] 纯文本查看 复制代码
@echo off
:qiepian
setlocal
set FFMPEG_PATH="D:\SSL_TOOLS\ffmpeg\bin\ffmpeg.exe"
set /p INPUT_FILE="文件名称:"
%FFMPEG_PATH% -i ./%INPUT_FILE%.rmvb ./%INPUT_FILE%.mp4
echo 转换完成
endlocal
PAUSE
goto qiepian
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

本站微信公众号

关注微信公众号

扫码关注

抵制不良游戏,拒绝盗版游戏。注意自我保护,谨防受骗上当。适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。
| Archiver | 手机版 | 小黑屋 | 道具 | 

Powered by Discuz! X3.4  湘ICP备2024045241号-1   技术支持:DZFUNS

8k联盟网络工作室  湘ICP备2024045241号-1 © 8K联盟