百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 优雅编程 > 正文

FFMPEG 视频分割和合并

sinye56 2024-11-26 08:31 1 浏览 0 评论

FFMPEG 视频分割和合并

一、分割

ffmpeg -ss 00:00:00 -t 00:00:30 -i test.mp4 -vcodec copy -acodec copy output.mp4

  • -ss 指定从什么时间开始
  • -t 指定需要截取多长时间
  • -i 指定输入文件这个命令就是从00秒开始裁剪到00+30=30秒结束,总共30秒的视频。这个命令执行很快,因为只是原始数据的拷贝,中间没有什么编码和解码的过程。执行这个命令后你能得到output.mp4这个输出文件。你可以用视频播放软件播放这个视频看看。可能有些视频裁剪后的效果,如期望一致,00秒开始,30秒结束,总共30秒的视频,但是有些视频裁剪后你会发现可能开始和结束都不是很准确,有可能是从00秒开始,33秒结束。这是为什么呢?因为这些视频里30秒处地方刚好不是关键帧,而ffmpeg会在你输入的时间点附近圆整到最接近的关键帧处,然后做接下来的事情。如果你不懂什么是关键帧,没关系,这也不影响你使用这个命令。

如果你的项目里要求很严格,一定要到确定的时间。那么就要用另外一种方式。

上面的造成那样的原因是所选的时间不是关键帧,那如果我们将输入的视频先转换成所有的帧都为关键帧的视频,其实就是将所有的帧的编码方式转为帧内编码(不理解帧内编码也没关系,你就当没看见它,接着往下看),这个问题就有解了。ffmpeg也可以帮我们完成这个事情。

ffmpeg -i INPUT -sameq -intra OUTPUT

-i 输入,后面是空格,紧跟着就是输入视频文件;

INPUT 输入文件;

-sameq 表示保持同样的视频质量;

-intra, 帧内编码;

OUTPUT 输出文件名。

如:

ffmpeg -i ./MyVideo.mpg -sameq -intra ./temp.mpg

这个命令的结果文件就是./temp.mpg.这个文件的视频和./MyVideo.mpg是一样的,但是你会发现这个文件会比./MyVideo.mpg大很多倍,原因就是转换前一般采用的帧间编码,转换后变成了帧内编码。这里我们说是一般,原因是有些视频文件本身就采用了帧内编码。经过这样的处理后,我们就可以精确的剪切视频了。

注意:上面的命令在新版本中已经废弃,可以参考下面的命令

ffmpeg -i output.mp4 -strict -2 -qscale 0 -intra keyoutput.mp4

使用ffmpeg进行flv分片

ffmpeg -y -i d:/xxx.mp4 -vcodec copy -an -f segment -segment_time 120 -bsf:v h264_mp4toannexb -segment_list d:/segment/out.csv d:/segment/%d.flv

使用FFmpeg命令进行hls切片

ffmpeg -i video2.mp4 -force_key_frames "expr:gte(t,n_forced*1)" -strict -2 -c:a aac -c:v libx264 -hls_time 1 -f hls out.m3u8

其中,参数-force_key_frames "expr:gte(t,n_forced*1)"表示强制每1秒一个关键帧

参数-strict -2是为了使用aac音频编码

执行完上述命令后,我们可以在生成的m3u8文件中看到生成的ts文件时长已经变为1秒了,如下图所示:

ffmpeg -y -ss start -t duratio -accurate_seek -i filename codec copy -avoid_negative_ts 1

二、合并

//截取从头开始的30s

ffmpeg -ss 00:00:00 -t 00:00:30 -i keyoutput.mp4 -vcodec copy -acodec copy split.mp4

//截取从30s开始的30s

ffmpeg -ss 00:00:30 -t 00:00:30 -i keyoutput.mp4 -vcodec copy -acodec copy split1.mp4

//进行视频的合并

ffmpeg -f concat -i list.txt -c copy concat.mp4

方法一:FFmpeg concat 协议

对于 MPEG 格式的视频,可以直接连接:

ffmpeg -i "concat:input1.mpg|input2.mpg|input3.mpg" -c copy output.mpg

对于非 MPEG 格式容器,但是是 MPEG 编码器(H.264、DivX、XviD、MPEG4、MPEG2、AAC、MP2、MP3 等),可以包装进 TS 格式的容器再合并。在新浪视频,有很多视频使用 H.264 编码器,可以采用这个方法

ffmpeg -i input1.flv -c copy -bsf:v h264_mp4toannexb -f mpegts input1.ts

ffmpeg -i input2.flv -c copy -bsf:v h264_mp4toannexb -f mpegts input2.ts

ffmpeg -i input3.flv -c copy -bsf:v h264_mp4toannexb -f mpegts input3.ts

ffmpeg -i "concat:input1.ts|input2.ts|input3.ts" -c copy -bsf:a aac_adtstoasc -movflags +faststart output.mp4

保存 QuickTime/MP4 格式容器的时候,建议加上 -movflags +faststart。这样分享文件给别人的时候可以边下边看。

方法二:FFmpeg concat 分离器

这种方法成功率很高,也是最好的,但是需要 FFmpeg 1.1 以上版本。先创建一个文本文件filelist.txt:

file 'input1.mkv'

file 'input2.mkv'

file 'input3.mkv'

然后:

ffmpeg -f concat -i filelist.txt -c copy output.mkv

注意:

1、使用 FFmpeg concat 分离器时,如果文件名有奇怪的字符,要在 filelist.txt 中转义。

2、 测试中发现,产生文件的后缀(如果非常见视频格式可能会导致失败,对于非视频格式可以选择mp4),可能对文件格式产生影响。所以需要注意使用正确的后缀。

3、filelist.txt中文件'input1.mkv'在windows下必须带分号才能合并成功,Linux下可以不用分号。最好是都带上分号。

4、如果后台合并,ffmpeg 后台运行无法判断什么时候合并完成。通过生成日志文件,查找相关日志信息即可。

4.1后台运行 nohup ffmpeg -f concat -i filelist.txt -c copy output.mkv 1>xxx.log 2>&1 &

4.2从xxx.log日志文件中查找相关信息(搜索文件名和subtitle)。

5、同步运行,不打印日志。带下面参数,比如:-loglevel quiet 或 -v quiet

6、ffmpeg视频剪切时长不正确

在windows下使用ffmpeg以下命令剪切视频时,发现剪切后的时长都会比设置的时长长

ffmpeg -ss 00:10 -t 30 -i 0.mp4 -c copy 2.mp4

以上的命令是从10s开始剪30s时长的视频,不过实际出来的时长32s左右

原因:-c copy就是没有重新编码,直接裁剪视频,这样会出现一个问题:如果不重编码的分割视频,就需要对准视频的关键帧分割,比如视频的关键帧在8s处,而你是从10s开始分割,分割就会调整在8s处,这样剪切出来的视频就会比想要的长了

解决方法:目前我的解决方法就是重新编码视频,去掉-c copy就行了,不过重新编码有点耗时间。


三、常用命令如下

// 去掉视频中的音频

ffmpeg -i input.mp4 -vcodec copy -an output.mp4

// -an: 去掉音频;-vcodec:视频选项,一般后面加copy表示拷贝

// 提取视频中的音频

ffmpeg -i input.mp4 -acodec copy -vn output.mp3

// -vn: 去掉视频;-acodec: 音频选项, 一般后面加copy表示拷贝

// 音视频合成

ffmpeg -y –i input.mp4 –i input.mp3 –vcodec copy –acodec copy output.mp4

// -y 覆盖输出文件

//剪切视频

ffmpeg -ss 0:1:30 -t 0:0:20 -i input.mp4 -vcodec copy -acodec copy output.mp4

// -ss 开始时间; -t 持续时间

// 视频截图

ffmpeg –i test.mp4 –f image2 -t 0.001 -s 320x240 image-%3d.jpg

// -s 设置分辨率; -f 强迫采用格式fmt;

// 视频分解为图片

ffmpeg –i test.mp4 –r 1 –f image2 image-%3d.jpg

// -r 指定截屏频率

// 将图片合成视频

ffmpeg -f image2 -i image%d.jpg output.mp4

//视频拼接

ffmpeg -f concat -i filelist.txt -c copy output.mp4

// 将视频转为gif

ffmpeg -i input.mp4 -ss 0:0:30 -t 10 -s 320x240 -pix_fmt rgb24 output.gif

// -pix_fmt 指定编码

// 将视频前30帧转为gif

ffmpeg -i input.mp4 -vframes 30 -f gif output.gif

// 旋转视频

ffmpeg -i input.mp4 -vf rotate=PI/2 output.mp4

// 缩放视频

ffmpeg -i input.mp4 -vf scale=iw/2:-1 output.mp4

// iw 是输入的宽度, iw/2就是一半;-1 为保持宽高比

//视频变速

ffmpeg -i input.mp4 -filter:v setpts=0.5*PTS output.mp4

//音频变速

ffmpeg -i input.mp3 -filter:a atempo=2.0 output.mp3

//音视频同时变速,但是音视频为互倒关系

ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" output.mp4


// 视频添加水印

ffmpeg -i input.mp4 -i logo.jpg -filter_complex [0:v][1:v]overlay=main_w-overlay_w-10:main_h-overlay_h-10[out] -map [out] -map 0:a -codec:acopy output.mp4

// main_w-overlay_w-10 视频的宽度-水印的宽度-水印边距;

// 截取视频局部

ffmpeg -i in.mp4 -filter:v "crop=out_w:out_h:x:y" out.mp4

// 截取部分视频,从[80,60]的位置开始,截取宽200,高100的视频

ffmpeg -i in.mp4 -filter:v "crop=80:60:200:100" -c:a copy out.mp4

// 截取右下角的四分之一

ffmpeg -i in.mp4 -filter:v "crop=in_w/2:in_h/2:in_w/2:in_h/2" -c:a copy out.mp4

// 截去底部40像素高度

ffmpeg -i in.mp4 -filter:v "crop=in_w:in_h-40" -c:a copy out.mp4

视频图片互转

视频转JPEG

ffmpeg-itest.flv-r 1 -fimage2image-%3d.jpeg

视频转gif

ffmpeg-iout.mp4-ss 00:00:00-t 10 out.gif

图片转视频

ffmpeg-fimage2-iimage-%3d.jpegimages.mp4

直播相关

推流

ffmpeg -re -iout.mp4 -c copy -f flv rtmp://server/live/streamName

拉流保存

ffmpeg -i rtmp://server/live/streamName -c copy dump.flv

转流

ffmpeg -i rtmp://server/live/originalStream -c:a copy -c:v copy -f flv rtmp://server/live/h264Stream

实时推流

ffmpeg -framerate 15 -f avfoundation -i"1" -s 1280x720 -c:v libx264 -f flv rtmp://localhost:1935/live/room

ffplay

播放YUV 数据

ffplay-pix_fmtnv12-s 192x144 1.yuv

播放YUV中的 Y平面

ffplay -pix_fmt nv21 -s 640x480 -vfextractplanes='y' 1.yuv

参数说明:

-vcodec xvid 使用xvid压缩

-s 320x240 指定分辨率

-r fps 设置帧频 缺省25

-b <比特率> 指定压缩比特

-acodec aac 设定声音编码

-ac <数值> 设定声道数,1就是单声道,2就是立体声

-ar <采样率> 设定声音采样率,PSP只认24000

-ab <比特率> 设定声音比特率

-vol <百分比> 设定音量

-y(覆盖输出文件

-t duration 设置纪录时间 hh:mm:ss[.xxx]格式的记录时间也支持

-ss position 搜索到指定的时间 [-]hh:mm:ss[.xxx]的格式也支持

-title string 设置标题

-author string 设置作者

-copyright string 设置版权

-hq 激活高质量设置

-aspect aspect 设置横纵比 4:3 16:9 或 1.3333 1.7777

-croptop size 设置顶部切除带大小 像素单位

-cropbottom size -cropleft size -cropright size

-padtop size 设置顶部补齐的大小 像素单位

-padbottom size -padleft size -padright size -padcolor color 设置补齐条颜色(hex,6个16进制的数,红:绿:兰排列,比如 000000代表黑色)

-bt tolerance 设置视频码率容忍度kbit/s

-maxrate bitrate设置最大视频码率容忍度

-minrate bitreate 设置最小视频码率容忍度

-bufsize size 设置码率控制缓冲区大小

-vcodec codec 强制使用codec编解码方式。 如果用copy表示原始编解码数据必须被拷贝。

-sameq 使用同样视频质量作为源(VBR)

-pass n 选择处理遍数(1或者2)。两遍编码非常有用。第一遍生成统计信息,第二遍生成精确的请求的码率

-passlogfile file 选择两遍的纪录文件名为file

-map file:stream 设置输入流映射

-debug 打印特定调试信息

四、ffmpeg 后台运行,输出重定向,记录log和把文件输出到终端

1.后台运行nohup

nohup ffmpeg -report -fflags nobuffer -probesize 50 -analyzeduration 100 -i rtmp://127.0.0.1/live/test -f hls -c copy -hls_flags delete_segments -hls_time 1 -hls_list_size 3 -hls_segment_filename output-%05d.ts table521.m3u8 1>/dev/null 2>&1 &

nohup的介绍参照这篇文章https://mp.weixin.qq.com/s/nyT-FPdIUdJUiUCYVGEnTg

1 代表标准输出

2 代表标准错误

1>/dev/null 把标准输出导入到null设备,也就是消失不见,如果要重定向到某个文件,可以1>1.txt

2>&1 把标准错误也导入到标准输出同样的地方

-report 把ffmpeg命令行和终端的输出(标准和错误)都记录到以program-YYYYMMDD-HHMMSS.log命名的文件中,log文件会在ffmpeg所在的目录中生成,可以设置log等级和long文件名,便于查找运行很长时间才出现的错误。

2.输出到终端

ffmpeg -i rtmp://live.hkstv.hk.lxdns.com/live/hks -an -c:v copy -bsf:v h264_mp4toannexb -f h264 -y - >666 2>777

>666 省略了1,原本是1>666

666文件中 timeout 0, ret=1 是我在libavformat库里打印的log

可知,库打印的log属于标准输出,而ffmpeg.c 打印的属于标准出错,可以用2>&1指定标准出错也打印到标准输出

- >两个字符之间是有空格的,- 表示把输出的视频文件(不属于标准输出)输出到终端,如果想把输出到终端的视频流通过管道保存到文件,可以用如下指令

ffmpeg -i rtmp://live.hkstv.hk.lxdns.com/live/hks -an -c copy -bsf:v h264_mp4toannexb -f h264 - | cat - > output.h264

相关推荐

linux安装FTP

1、在nkftp目录下安装ftp,进入到nkftp里面[root@localhostbin]#cd/data/nkftp执行安装命令:[root@localhostnkftp]#rpm-i...

LINUX下搭建FTP服务器

FTP服务器介绍FTP是FileTransferProtocol(文件传输协议)的英文简称,而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(App...

Linux下如何进行FTP设置

目录:一、Redhat/CentOS安装vsftp软件二、Ubuntu/Debian安装vsftp软件一、Redhat/CentOS安装vsftp软件1.更新yum源yumupdate-y2.安...

推荐使用集串口 SSH远程登录和FTP传输三合一工具MobaXterm

来源:百问网作者:韦东山本文字数:1216,阅读时长:4分钟在以前的资料里,串口和SSH远程登使用SecureCRT,window与ubuntu数据传输使用filezilla,窗口切换来切换去,麻烦也...

如何搭建FTP服务器(Linux系统)

上次说了Windows操作系统下搭建的FTP服务器,那有朋友问我,说买的XX轻量应用服务器都是属于Linux的操作系统,我该如何为搭建FTP服务器呢?...

Linux 命令 ncftp(文件传输)——想玩转linux就请一直看下去

我是IT悟道,点击右上方“关注”,每天分享IT、科技、数码方面的干货。Linuxncftp命令...

如何用 ftp 实现一键上传

简介ftp是Internet标准文件传输协议的用户界面,它允许用户与远程网络站点之间传输文件...

Linux安装ftp

1安装vsftpd组件安装完后,有/etc/vsftpd/vsftpd.conf文件,是vsftp的配置文件。[root@bogon~]#yum-yinstallvsftpd2添加一个...

一天一点点:linux - ftp命令

linuxftp命令设置文件系统相关功能。FTP是ARPANet的标准文件传输协议,该网络就是现今Internet的前身。语法ftp[-dignv][主机名称或IP地址]参数:-d详细显示指令执...

Centos 7 搭建FTP

目录安装软件以及启动服务添加防火墙规则关闭selinuxftp配置常用常用参数详解特殊参数配置文件没有的参数也可以添加到配置中1.安装软件以及启动服务yuminstall-yvsftpdsys...

【Linux】Linux中ftp命令,没有你想的那么简单

本文介绍了Linux中FTP命令的基本用法,包括连接与登录远程服务器,以及解析了FTP协议中五个最常用的操作命令的使用和解析过程。同时,提供了一个包含常用FTP操作命令的表格,供读者参考。通过熟练掌握...

linux 命令行操作ftp

以下是linuxftp命令参数的详解。FTP>!从ftp子系统退出到外壳?FTP>?显示ftp命令说明??和help相同?格式:?[command]说明:[com...

多学习才能多赚钱之:linux如何使用ftp

linux如何使用ftp步骤1:建立FTP连接想要连接FTP服务器,在命令上中先输入ftp然后空格跟上FTP服务器的域名'domain.com'或者IP地址例如:ftpdom...

linux常用网络操作方法:ftp命令使用方法

常用网络操作方法Linux提供了一组强有力的网络命令来为用户服务,这些工具能够帮助用户登录到远程计算机上、传输文件和执行远程命令等。本节介绍下列几个常用的有关网络操作的命令:ftp传输文件tel...

Linux 5.15有望合并Memory Folios方案 内核构建速度可提升7%

甲骨文公司的长期内核开发人员MatthewWilcox已经研究了“内存对开区”概念相当长的一段时间,这可以改善Linux的内存管理,使其具有更大的效率。例如,使用内存对开的基准测试表明,内核的构建速...

取消回复欢迎 发表评论: