FFmpeg way to explore https:https://cdn.v2ex.com/navatar/e205/ee2a/910_normal.png?m=1589098075 https:https://cdn.v2ex.com/navatar/e205/ee2a/910_large.png?m=1589098075 2025-10-22T05:50:43Z Copyright © 2010-2018, V2EX FFmpeg 的实时性太糟糕了 tag:www.v2ex.com,2025-10-20:/t/1167069 2025-10-20T08:35:08Z 2025-10-22T05:50:43Z FH0 member/FH0 在用 FFmpeg RTP 传输 H.264 ,本来想着发一个帧就能收到一个帧,但测试老是反馈延迟高,我就自己测试了一下。

结果发现要接收 n 个帧,必须发送 n + 2 个帧,难顶。下面的例子之所以能收到两个是因为第二个超时了,我也不懂为什么超时就能收到第二个包。

看来得参考 RTP 自己造轮子了。

10-20 16:27:34.582 I sdp: v=0 o=- 0 0 IN IP4 127.0.0.1 s=No Name c=IN IP4 239.0.0.1 t=0 0 a=tool:libavformat 61.1.100 m=video 16384 RTP/AVP 96 a=rtpmap:96 H264/90000 a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z2QAHqzZQKAv+XARAAADAAEAAAMAMg8WLZY=,aOvjyyLA; profile-level-id=64001E 10-20 16:27:34.583 I send packet, pts: 0 10-20 16:27:34.600 I send packet, pts: 16666 10-20 16:27:34.617 I send packet, pts: 33332 10-20 16:27:34.617 I pkt pts: -9223372036854775808 10-20 16:27:44.629 I pkt pts: 1500 
]]>
早就听说过 ffmpeg,但是一直不知道有多牛 tag:www.v2ex.com,2025-05-13:/t/1131548 2025-05-13T13:55:23Z 2025-05-15T18:35:12Z airchaoz member/airchaoz 我对 ffmpeg 的印象就是一个开源音视频编解码程序,对其影响力认识较少。能给我这个门外汉讲讲到底有多牛吗

]]>
使用 FFmpeg 和 GPU 实现最简“图片+无损音频=视频”的方法 tag:www.v2ex.com,2025-03-27:/t/1121476 2025-03-27T04:47:37Z 2025-03-28T15:24:35Z MOranonline member/MOranonline

需求:搜集到的无损音乐太占空间,决定传到 B 站网盘。但 pr 导出太太太耗时,于是使用 FFmepeg 的 GPU 加速

前置条件清单
1.支持 NVENC 的 NVIDIA 显卡 确认是否支持 NVENC: 在 CMD 中执行:

nvidia-smi 

或通过 NVIDIA 官方列表 查询您的显卡型号。
2.更新到最新 NVIDIA 显卡驱动
3.支持 h264_nvenc 的 FFmpeg 版本

ffmpeg -encoders | findstr "h264_nvenc" 

如果输出中有 h264_nvenc,则支持。


开始:
1.将 FFmpeg 的 bin 目录加入环境变量
2.输入

ffmpeg -hwaccel cuda -threads 24 -loop 1 -i "picture.png" -i "music.flac" -vf "hwupload" -c:v h264_nvenc -preset 0 -cq 23 -rc constqp -c:a flac -shortest "output.mkv" 

解析:


批量处理:
视频按顺序数字重命名(如 video1.mp4, video2.mp4 等),且需要与对应的图片(如 pic1.png, pic2.png

1.每个视频关联一张图片

@echo off set "input_dir=.\videos" # 视频存放目录(如已重命名的 video1.mp4 ) set "image_dir=.\images" # 图片存放目录(需要同名的 pic1.png 等) set "output_dir=.\outputs" # 输出目录 for %%a in ("%input_dir%\*.mp4") do ( set "video_file=%%~nxa" set "prefix=%%~na" ffmpeg -hwaccel cuda -threads 24 -i "%%a" -i "%image_dir%\pic%%~na.png" ^ # 注意:这里的图片名格式可自定义(如 pic1.png 需替换为 pic##匹配你的命名) -filter_complex "[0:v]scale=trunc(iw/2)*2:trunc(ih/2)*2[vid]; [vid][1:v] overlay=10:10" ^ # 图片叠加在左上角( 10 像素偏移) -c:v h264_nvenc -preset 0 -cq 23 -rc constqp ^ -c:a copy ^ # 音频直接复制(加速处理) "%output_dir%\output_%%~na.mkv" ) 

2.所有视频使用同一张背景图片

@echo off set "input_dir=.\videos" # 视频目录 set "image_file=.\background.png" # 固定背景图片路径 set "output_dir=.\outputs" for %%a in ("%input_dir%\*.mp4") do ( ffmpeg -hwaccel cuda -threads 24 -i "%%a" -loop 1 -i "%image_file%" ^ # 循环播放图片 -filter_complex "[0:v]scale=trunc(iw/2)*2:trunc(ih/2)*2[vid]; [1:v]scale=trunc(iw/2)*2:trunc(ih/2)*2[img]; [vid][img] overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" ^ # 图片居中叠加 -c:v h264_nvenc -preset 0 -cq 23 -rc constqp ^ -c:a copy "%output_dir%\output_%%~na.mkv" ) 

3.注意事项

# 输入视频目录: videos/ ├── video1.mp4 ├── video2.mp4 └── video3.mp4 # 输入图片目录(场景 1 ): images/ ├── pic1.png ├── pic2.png └── pic3.png # 输出目录: outputs/ ├── output_video1.mkv ├── output_video2.mkv └── output_video3.mkv 

5.自动化

(1) 保存为批处理文件( Windows )

# 保存为 batch_process.bat ,双击运行即可。 

(2) 可视化进度条(可选)

echo Processing videos: FOR /L %i IN (1,1,50) DO ( echo %i%% ping localhost -n 1 >nul ) 

然后可以快速完成批量视频与图片的合成处理,传到 B 站网盘。如需进一步定制(如动态图片透明度、图片/视频尺寸调整、不同叠加效果、音轨混音等)自行添加命令
使用开源的 B 站音频播放器电梓播放器
然后完美音乐软件 get☆ daze

]]> FFmpegKit has been officially retired. There will be no further ffmpeg-kit releases. tag:www.v2ex.com,2025-01-11:/t/1104441 2025-01-11T22:53:47Z 2025-01-12T18:03:14Z chenliang0571 member/chenliang0571 不知道为什么,连发不到第三方包平台的二进制文件都不保留。

https://github.com/arthenica/ffmpeg-kit

FFmpegKit has been officially retired. There will be no further ffmpeg-kit releases.

All previously released ffmpeg-kit binaries will be removed according to the following schedule.

FFmpegKit Version Available Until
Less than 6.0 February 1st, 2025
6.0 April 1st, 2025
]]>
有没有精通 ffmpeg 的大佬帮我看下这个视频是怎么制作的 tag:www.v2ex.com,2025-01-10:/t/1104123 2025-01-10T05:06:17Z 2025-01-10T09:19:15Z litaomn member/litaomn 视频时长 5 秒,但是播放 1 秒自动结束,后面 4 秒自动截断了,应该是用 ffmpeg 经过处理的,想知道原理,可以付费. 视频地址:https://share.feijipan.com/s/GaE97j6z

]]>
使用 FFmpeg 试图做个人用的转码点播服务端, 但 mpegts 多个切片间音频偶尔不连续? tag:www.v2ex.com,2025-01-02:/t/1102154 2025-01-02T16:16:00Z 2025-01-02T20:16:00Z lslqtz member/lslqtz 最近试着写了一份简单的个人用途的转码点播服务端, 完成了之前的想法, 它能把当前工作目录下的视频转为 m3u 切片用于点播. 主要是由于部分 BDMV 视频码率过高, 很难远程点播 NAS 上的内容. Jellyfin 等媒体库方案不在考虑范围.

为了实现浏览器 seek 的效果, 选择由服务端通过 PTS 时间点和 timeBase 来根据关键帧提前生成切片范围, 在请求对应切片后实时转码到 mpegts (并通过浏览器预缓冲避免播放卡顿).

但无论如何调节, 似乎偶尔都会出现音频不连续的问题, 转储后发现目标切片似乎时间和请求长度不完全一致, 调节多次参数仍未解决此问题 (为使切片有足够起始长度只测试到 muxdelay 方法可用, -ss/-t 放于输入之后似乎也无果, 包括 -start_at_zero 等的替代也都尝试过, 使用 hls 或 segment 的话较难控制自由点播进度).

由于 nodejs 服务端较难调用 FFmpeg API, 是用的 命令+管道 的方式. 在这种情况下, 有方法可以解决或规避此问题吗?

服务端的完整代码, 其中相关的代码如下:

 let args = [ '-ss', startTimeStr, '-t', durationTimeStr, '-accurate_seek', '-i', videoPath, '-map', '0:v:0', '-c:v', encoder, '-b:v', String(bitrate), '-bsf:v', 'h264_mp4toannexb', '-avoid_negative_ts', 'make_zero', '-start_at_zero', '-muxdelay', delayTimeStr, '-muxpreload', delayTimeStr, '-f', 'mpegts', 'pipe:1' ]; 

请求方法:
m3u: http://127.0.0.1:8082/video/rttPlaylist?videoPath=1.mkv
segment: http://127.0.0.1:8002/video/rttSegment?videoPath=1.mkv&start=0.0000&duration=4.0000

(BTW: 其实大部分是 Gemini 写的.)

]]>
求助大佬们, FFmpeg 指令拉实时流转推的正确姿势到底是什么? tag:www.v2ex.com,2025-01-02:/t/1101957 2025-01-02T03:33:38Z 2025-01-02T06:19:37Z zapper member/zapper 大佬们好,我用

ffmpeg -re -rtsp_transport tcp -stimeout 5000000 -i rtsp://xxxx -c:v libx264 -f flv rtmp://xxx 

上面这个指令,在一切正常的时候没有问题,但是当输入的 RTSP 中断了一会,这个推流就会处于一个跑飞了的状态,不再推送有效数据,并且进程也没有终止; 然后我网上搜说用rw_timeout参数可破,可是我将指令修改为

ffmpeg -re -rtsp_transport tcp -rw_timeout 5000000 -stimeout 5000000 -i rtsp://xxxx -c:v libx264 -f flv rtmp://xxx 

可是整个指令根本跑不起来。提示-rw_timeout不存在,除非输入换成 RTMP ,但是加了这个参数其实也不好使。 由于输出的地址不是我们自己管控的,所以不像保存文件一样能定期检测文件大小是否变化来判断是不是应该 kill 掉进程,所以要怎么才能在他没数据传输的时候干掉他,或者能通过配置参数让他自己退?

先谢谢大佬们

]]>
在几乎不损失画质的前提下,怎么用 ffmpeg 把 h.264 格式的视频转换成 h.265 格式的? tag:www.v2ex.com,2025-01-01:/t/1101767 2025-01-01T05:51:56Z 2025-01-02T08:20:05Z wniming member/wniming linux 平台,显卡是 uhd770 ,渲染节点是 /dev/dri/renderD128 ,输入文件的路径是 /tmp/h264.mp4 ,输出文件路径是 /tmp/hevc.mp4 ,有大佬能给个能直接用的命令吗?

转换的目的是为了减小文件的大小

]]>
我又来询问 ffmpeg 问题了!这次是硬件加速! tag:www.v2ex.com,2024-12-28:/t/1100954 2024-12-28T12:02:58Z 2024-12-28T16:47:48Z jeddida member/jeddida 书接上次,大佬们建议我用硬件加速,我现在换了 AMD 的显卡,并且成功在我的 Linux 安装了 ffmpeg 。 我运行:ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -i input.mp4 -vf format=yuv420p,hwupload -c:v h264_vaapi -b:v 1000k output.mp4

可硬件加速,CPU 占用率很低。 但是我在我的 c++代码里使用来创建:int ret = av_hwdevice_ctx_create = (&hw_device_ctx,AV_HWDEVICE_TYPE_VAAPI,"/dev/dri/renderD128");

我打印了 ret:-12 ,我查阅了资料是因为无法创建内存空间导致的。

忘了说,我用的是 qtcreator ,我在 qt 的 pro 文件了引入了-lavcodec -lavformat -lavutil -lswscale ,在不用硬件加速的时候可以看到视频,也可以播放,但是用了 vaapi 那个加速就会打印-12

我查阅资料可能是没有引入 libva 和 libva-drm 。

有没有大佬了解过这些! 跪谢!困扰我一周了!(我没法尝试是因为公司电脑关了,这周末难受的我啊,解决不了问题我都睡不好)

]]>
大佬们, nodejs 和 Python 做类似 jellyfin 实时转码是不是只能用 ffmpeg 实现了 tag:www.v2ex.com,2024-12-26:/t/1100488 2024-12-26T09:01:31Z 2024-12-26T13:48:16Z zhengfan2016 member/zhengfan2016 有大佬开发过 ffmpeg 吗?用 c++调用 ffmpeg API 解码视频流 CPU 占用率高,求解决办法 tag:www.v2ex.com,2024-12-25:/t/1100292 2024-12-25T12:24:59Z 2024-12-25T23:39:03Z jeddida member/jeddida 刚接触 ffmpeg 想着写一个播放器玩玩,但是 CPU 占用率一直高,有没有大佬知道怎么回事。没有显卡。

我测试一个视频的时候还行,视频数量上到了 16 个就开始花屏+卡顿了。

]]>
ffmpeg 视频录制切分问题请教 tag:www.v2ex.com,2024-12-10:/t/1096466 2024-12-10T08:26:13Z 2024-12-10T10:13:31Z mianhk member/mianhk 当前使用 ffmpeg 录制 Ubuntu 屏幕,使用 avi 格式,录制的过程需要每隔 10 分钟切分一个 2 分钟的视频,但是经常录了一段时间后,视频切分就有报错,但是等录制完成后,用同样的命令切割却没有报错,有大佬知道原因的吗? 录制命令:

ffmpeg -f alsa -i hw:1,0 -f x11grab -s 1920x1080 -i :0.0 -async 1 ubuntu.avi 
]]>
通过 ffmpeg 压缩视频很慢 时间敏感的需求该怎么设置参数呢? tag:www.v2ex.com,2024-12-05:/t/1095204 2024-12-05T04:20:26Z 2024-12-05T20:26:25Z v423 member/v423 前端上传的时候需要预压缩 希望 1 分钟的视频压缩时间能控制在 1 分钟以内, 同时保证画面清晰不能有马赛克, 压缩后视频在 720p 以上 码率 2000k 以上

现在的方案是通过 ffmpeg.wasm 压缩, 官方测试结果比原生 ffmpeg 慢 10-20 倍

项目中测试只要涉及画面转码都是严重超过 1 分钟 退而求其次尝试维持视频流只减帧, 但是维持原视频流需要 copy 参数, 此时无法通过-r 设置参数, filter 只是过滤器无法压缩视频体积

昨天找了一下午没找到可用的参数, 只能请教大佬了

参数如下

const args = [ "-i", "input.mov", "-preset", "ultrafast", "-c:a", "copy", "-c:v", "copy", "-r", "24", "output.mp4" ] 
]]>
ffmpeg 处理后视频时长问题 tag:www.v2ex.com,2024-11-20:/t/1091285 2024-11-20T10:37:25Z 2024-11-20T18:55:37Z henix member/henix 用 ffmpeg -t 将一个 10s 的视频剪裁到 3s 后,播放时长没问题,但是放进 concat 过滤器,这个视频片段占用的长度仍为原长度 10s ,后面 7s 表现为最后一帧静止画面。尝试了各种方法都不行,还望大神赐教。

问题详细描述:

1. 用完全重编码的方法将一个 10s 的视频转换为 3.971s 并去掉音频:

ffmpeg -t 3.971 -i "加载.mp4" -c:v libx264 -tune animation -crf 1 -an loading.mp4

ffprobe 结果文件 loading.mp4 如下:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'loading.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf61.7.100 Duration: 00:00:03.98, start: 0.000000, bitrate: 49072 kb/s Stream #0:0[0x1](eng): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080, 49068 kb/s, 60 fps, 60 tbr, 15360 tbn (default) Metadata: handler_name : ?Mainconcept Video Media Handler vendor_id : [0][0][0][0] encoder : Lavc61.19.100 libx264 

疑点:时长为 3.98 ,已经不精确?

原始视频的 ffprobe ,是不是原始视频有什么不正常:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '加载.mp4': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: mp42mp41 creation_time : 2022-03-26T12:31:39.000000Z Duration: 00:00:10.00, start: 0.000000, bitrate: 9763 kb/s Stream #0:0[0x1](eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080, 9395 kb/s, 60 fps, 60 tbr, 60k tbn (default) Metadata: creation_time : 2022-03-26T12:31:39.000000Z handler_name : ?Mainconcept Video Media Handler vendor_id : [0][0][0][0] encoder : AVC Coding Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 317 kb/s (default) Metadata: creation_time : 2022-03-26T12:31:40.000000Z handler_name : #Mainconcept MP4 Sound Media Handler vendor_id : [0][0][0][0] 

2. 将一个 webm 视频 overlay 到上述视频上,并加入音频,且音视频都重编码:

疑点:webm 视频的时长显示为 N/A ,但实际为 3.5s 左右

用了 -filter_complex chromakey,scale;overlay

结果的 ffprobe 如下:

Input #0, matroska,webm, from 'opening.mkv': Metadata: COMPATIBLE_BRANDS: isomiso2avc1mp41 MAJOR_BRAND : isom MINOR_VERSION : 512 ENCODER : Lavf61.7.100 Duration: 00:00:03.98, start: 0.000000, bitrate: 70572 kb/s Stream #0:0: Video: h264 (High 4:4:4 Predictive), yuv420p(tv, bt709, progressive), 1920x1080, 60 fps, 60 tbr, 1k tbn Metadata: ENCODER : Lavc61.19.100 libx264 DURATION : 00:00:03.984000000 Stream #0:1: Audio: flac, 44100 Hz, stereo, s16 Metadata: ENCODER : Lavc61.19.100 flac DURATION : 00:00:03.970000000 

这一步结果视频长度 3.984s

3. 将上一步的结果用 concat 加到另外两个视频流的中间:

-filter_complex "[10:v]trim=0:3.97[t10v]", "[10:a]atrim=0:3.97[t10a]", "[fv1t][fa1t][t10v][t10a][fv2t][fa2t]cOncat=3:1:1", 

其中 "[10]" 代表上一步结果的视频流和音频流,已经用 trim 处理

结果:在生成的文件中,这一段的实际占用时间为 10s ,而不是我需要的 3.971s ,后面 7s 是最后一帧静止画面和静音。

]]>
请教一个关于 ffmpeg 的问题 tag:www.v2ex.com,2024-11-18:/t/1090588 2024-11-18T10:26:55Z 2024-11-19T02:59:00Z xyzos member/xyzos 前提:在 windows/linux 上,使用同样一个 ffmpeg 静态编译的可执行文件,对同样一个 h264 编码的 mp4 文件解码,解码命令如下: (1) .\ffmpeg.exe -hwaccel cuda -i E:\tmp\1080p_60_10M.mp4 -f null - 解码帧率为 fps=780 (2) .\ffmpeg.exe -i E:\tmp\1080p_60_10M.mp4 -f null - 解码帧率为 fps=1617

(1) 解码结果:

 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'E:\tmp\1080p_60_10M.mp4': 

Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf60.3.100 Duration: 00:01:36.67, start: 0.000000, bitrate: 10533 kb/s Stream #0:00x1: Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 10528 kb/s, 60 fps, 60 tbr, 15360 tbn (default) Metadata: handler_name : VideoHandler vendor_id : [0][0][0][0] encoder : Lavc60.3.100 libx264 Stream mapping: Stream #0:0 -> #0:0 (h264 (native) -> wrapped_avframe (native)) Press [q] to stop, [?] for help Output #0, null, to 'pipe:': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf60.22.101 Stream #0:0(und): Video: wrapped_avframe, nv12(progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 60 fps, 60 tbn (default) Metadata: handler_name : VideoHandler vendor_id : [0][0][0][0] encoder : Lavc60.40.100 wrapped_avframe [out#0/null @ 0000017e54639b80] video:2719KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown frame= 5800 fps=780 q=-0.0 Lsize=N/A time=00:01:36.66 bitrate=N/A speed= 13x

(2) 解码结果: Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'E:\tmp\1080p_60_10M.mp4': 

Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf60.3.100 Duration: 00:01:36.67, start: 0.000000, bitrate: 10533 kb/s Stream #0:00x1: Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 10528 kb/s, 60 fps, 60 tbr, 15360 tbn (default) Metadata: handler_name : VideoHandler vendor_id : [0][0][0][0] encoder : Lavc60.3.100 libx264 Stream mapping: Stream #0:0 -> #0:0 (h264 (native) -> wrapped_avframe (native)) Press [q] to stop, [?] for help Output #0, null, to 'pipe:': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf60.22.101 Stream #0:0(und): Video: wrapped_avframe, yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 60 fps, 60 tbn (default) Metadata: handler_name : VideoHandler vendor_id : [0][0][0][0] encoder : Lavc60.40.100 wrapped_avframe [out#0/null @ 000001f2b2f29c00] video:2719KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown frame= 5800 fps=1617 q=-0.0 Lsize=N/A time=00:01:36.66 bitrate=N/A speed=26.9x

问题:指定了 -hwaccel cuda 参数进行解码的 fps 要比不指定这个参数进行解码的帧率少了一倍,自己的主机是 nvidia 显卡,这个可能是什么原因?

]]>
如何下载官方的 ffmpeg 二进制发布 tag:www.v2ex.com,2024-11-17:/t/1090239 2024-11-17T04:07:07Z 2024-11-17T08:17:11Z zhwguest member/zhwguest 首先找到 ffmpeg 的官方网站: https://www.ffmpeg.org/

然后根据自己的 os 和 arch 找到相应的入口图标;

点击图标,然后提示跳转到第三方网站进行下载?

这是什么魔幻操作?

]]>
视频模板替换图片,有偿 tag:www.v2ex.com,2024-08-27:/t/1068110 2024-08-27T04:38:37Z 2024-09-02T06:14:16Z crazystory member/crazystory 研究了一星期,搞不定了,有偿请大佬帮忙解决下。以下是需求

剪映制作 10 秒的模板视频,轮换 4 张图,具有蒙版和转场特效。需要通过 ffmpeg 在保留蒙版和转场的前提下替换图片

vx YW55ZWZlbmdqaW5nbGluZw==

]]>
ffmpeg 过滤器 xfade 自定义动画的研究 tag:www.v2ex.com,2024-07-03:/t/1054559 2024-07-03T07:42:51Z 2024-07-03T10:43:36Z jifengg member/jifengg 本文无任何推广,请放心阅读。
本文无任何推广,请放心阅读。
本文无任何推广,请放心阅读。

前前言

hello ,兄弟们,我又来分享我的 ffmpeg 脚本啦。
上次分享了一个使用 ffmpeg ,将多张图片转换成类似幻灯片的视频,支持多种转场效果,说过在研究自定义效果,目前有点小成果,于是有了本文。

本次没有新增脚本,而是增强了ffmpeg.img2video.js,预置了一些自定义效果,并支持自己添加效果。

以下的都是本次的技术分享。如果你不感兴趣,可以直接到 GitHub 更新脚本。

开源地址

GitHub 地址:https://github.com/jifengg/ffmpeg-script

前言

使用xfade过滤器做视频转场切换效果,本身 ffmpeg 已经提供了 56 种效果,能满足大部分需求。不过,更复杂的过渡效果(例如翻页)还没有。
根据文档,使用 transition=custom+expr ,可以实现自定义的效果。但是,官方文档并没有对expr如何编写做详细说明,也没有 google 到。
因此,对其进行了一番研究,尝试实现了几种效果。简单做一个使用教程,希望能够帮助到有需要的人。

效果预览(点击查看视频,视频均小于 1MB )

水滴

https://github.com/jifengg/ffmpeg-script/assets/17020523/b3cec5b1-d747-46bd-aae1-924289aaddce

百叶窗

https://github.com/jifengg/ffmpeg-script/assets/17020523/1bef9ae3-41c3-4747-ae41-9056ae4e6892

简易翻页

https://github.com/jifengg/ffmpeg-script/assets/17020523/30c810a1-7522-4829-8450-4602c8203853

ffmpeg 官方 wiki

https://trac.ffmpeg.org/wiki/Xfade

ffmpeg 官方文档翻译

以下翻译自FFmpeg xfade 官方文档

xfade 将淡入淡出从一个输入视频流应用到另一个输入视频流。淡入淡出将持续指定的时间。 两个输入必须是恒定帧速率,并且具有相同的分辨率、像素格式、帧速率和时间基准。 该过滤器接受以下选项: transition 'custom' [忽略] duration 设置交叉淡入淡出持续时间(以秒为单位)。范围为 0 至 60 秒。默认持续时间为 1 秒。 offset 设置相对于第一个输入流的交叉淡入淡出开始时间(以秒为单位)。默认偏移量为 0 。 expr 设置自定义过渡效果的表达式。 表达式可以使用以下变量和函数: X Y 当前样本的坐标。 W H 图像的宽度和高度。 P 过渡效果的进展。 [译注] 过渡开始时,P=1.0 ,过渡结束时,P=0.0 。 PLANE 目前正在处理的平面。 [译注] 这里的平面,其实就是指像素格式的分量。 [译注] 取值范围由输入流的像素格式 pix_fmt 决定,如 yuv420p ,则取值范围是 0 ,1 ,2 ;如 rgba ,则取值范围是 0 ,1 ,2 ,3 。 A 返回第一个输入流在当前位置和平面的值。 B 返回第二个输入流在当前位置和平面的值。 a0(x,y) a1(x,y) a2(x,y) a3(x,y) 返回第一个输入的第一/第二/第三/第四个分量的 位置 (x,y) 处的像素的值。 [译注] 例如,像素格式是 yuv420p ,a0 返回的是 Y 分量。a1 返回的是 U 分量。a2 返回的是 V 分量。没有 a3 b0(x,y) b1(x,y) b2(x,y) b3(x,y) 返回第二个输入的第一/第二/第三/第四个分量的 位置 (x,y) 处的像素的值。 

理解 P

一般来说,ffmpeg 中支持时间轴编辑的过滤器,都有tn参数可以用在表达式中,其中t表示时间秒,n表示帧数。
但是 xfade 里却是用的 P ,它不是tn。如果你理解错了,会发现自定义效果完全没效。
因为,它表示的是过渡效果的进度,而且,重要的是,它是个递减的数。

理解 X,Y,W,H

X,Y 表示坐标,是指“当前正在计算表达式的像素的坐标”,按照我们要实现的效果,决定该像素对应的颜色码。

W,H 是图像的宽高,这个在整个渐变过程是保持不变的。

理解 PLANE,A,B,a0(x,y),...,b0(x,y),...

a0(x,y)表示第一个视频坐标 x,y 处的像素的第一个分量值。 PLANE 表示当前是计算的第几个分量值。 A 是一个简写,当 PLANE=0 时,A=a0(X,Y); PLANE=1 时,A=a1(X,Y); PLANE=2 时,A=a2(X,Y);以此类推。 b 和 B 同 a 和 A 。

注意,无法通过类似a(plane,x,y)的方法来获得指定坐标指定分量的值,因此在像素有位移的时候,表达式会比较长。如if(eq(PLANE,0),a0(X,Y),if(eq(PLANE,1),a1(X,Y),if(eq(PLANE,2),a2(X,Y),0)))

理解 expr

xfadeexpr,返回一个值,但是这个值是什么含义呢,一般人看文档很难理解。
300x200 的输入源为例,假设其像素格式是 yuv420p ,则其分量个数是 3 。( ffmpeg 支持的像素格式及格式信息,可以通过ffmpeg -pix_fmts查看)。 像素点是60000个,每一帧的像素分量总数就是60000*3=18 万个。
那么,过渡开始的第一帧,ffmpeg 会遍历每个像素点的每个分量,分别调用expr,并设置 X,Y,PLANE 等值。总共调用18 万次获得对应的值,来完成第一帧的渲染。 如果我们希望每一帧就是显示第一个视频的画面,那么可以写expr=A即可。A表示的就是第一个视频当前像素当前分量的值。

尝试 1 ,实现渐隐渐显效果

如果我们希望实现第一个视频渐渐变透明,第二个视频由透明渐渐显现,类似xfade默认的效果fade,那么可以写expr='A*P+B*(1-P)'
因为 P 是从 1.0 线性变成 0.0 的。所以一开始 P=1 ,表达式计算结果=A,看到的就是只有第一个视频画面,到一半时,P=0.5 ,结果=0.5A+0.5B,画面就是两个视频分别半透明叠加在一起。最后 P=0.0 时,结果=B,就只剩下第二个视频的画面了。

尝试 2 ,实现擦除效果

同样的,如果我们希望实现一个从右往左擦除的效果(图片引用自https://trac.ffmpeg.org/wiki/Xfade):
wipeleft

分析一下,分割线在画面水平线上的位置 X ,除以宽度 W ,其实就是等于 P ,于是,我们可以让分割线左边的显示画面 A ,右边的显示画面 B 。 expr='if(lt(X/W,P),A,B)':当X/W<P的时候,说明 X 在分割线左边,于是显示 A ,否则显示 B 。

分割线上显示 A 还是 B ,影响不大。这里是显示了 B ,如果要显示 A ,可以用lte代替lt

尝试 3 ,实现推走效果

从上面两个例子你大概能理解 expr 要返回什么内容了。我们接着第三个例子。 如果我们希望实现的是一个从右往左推走的效果:
slideleft

你会发现,变得更复杂了。你可以先暂停试试自己能否写出来。

为什么更复杂了?以坐标(0,0)为例,他显示的像素时刻都在变化(因为画面在往左移动)。
例如,在 P=0.8 的时候,它(0,0)应该是视频 A X=W*0.2,Y=0 坐标处的像素值。(这里需要好好理解,参考下图帮忙理解)

image

X/W>P的地方,应该显示视频 B 的画面,其坐标转换关系是(X-P*W,Y)。
注意,此时你没法再用值AB了,因为它们是坐标(X,Y)的分量,而我们要在(X,Y)处显示别的坐标的像素,这个我们在上面理解 PLANE,A,B,a0(x,y),...,b0(x,y),...的地方说过了。

那么这个表达式要怎么写呢?

expr='if(lt(X/W,P),^ if(eq(PLANE,0),a0(X+(1-P)*W,Y),^ if(eq(PLANE,1),a1(X+(1-P)*W,Y),^ if(eq(PLANE,2),a2(X+(1-P)*W,Y),0)))^ ,^ if(eq(PLANE,0),b0(X-P*W,Y),^ if(eq(PLANE,1),b1(X-P*W,Y),^ if(eq(PLANE,2),b2(X-P*W,Y),0)))^ )' 

我测试的时候用的是 windows 的 bat 脚本,为了方便理解和修改,用^进行了换行。注意不要有空格,否则会报错。
测试的时候用的是 yuv420p 像素格式,因此表达式没有用到 a3 ,如果是用了 4 个分量的像素格式需要把 a3 按照上面的格式加进去。

其中,分割线左边显示视频 A 的画面,且 x 坐标左移了(1-P)*W 个像素,因此其 x 坐标表达式是X+(1-P)*W
右边显示视频 B 的画面,且 x 坐标右移到了分割线右边,因此其 x 坐标表达式是X-P*W
因为是水平移动,所以 y 坐标保持Y即可。

于是,随着 P 从 1.0 渐变到 0.0 ,视频 A 就像被视频 B 从右边推到了左边,完成了一个过渡效果。

小结

现在,你已经了解了 expr 要怎么编写来实现过渡效果了。我还实现了一些其它效果,包括示例里的,你可以在 GitHub 上查看

性能

在 windows 下创建 2 个 bat 文件,分别输入测试命令:

@echo off @REM 使用 custom 实现 slideleft 效果 ffmpeg -y -hide_banner ^ -f lavfi -i "pal100bars=r=1/1000" ^ -f lavfi -i "colorchart=r=1/1000" ^ -filter_complex ^ [0:v]format=yuv420p,scale=960:480,fps=25,trim=duration=40[v1];^ [1:v]format=yuv420p,scale=960:480,fps=25,trim=duration=40.04[v2];^ [v1][v2]xfade=duration=40:offset=0:transition=custom:^ expr='if(lt(X/W,P),^ if(eq(PLANE,0),a0(X+(1-P)*W,Y),^ if(eq(PLANE,1),a1(X+(1-P)*W,Y),^ if(eq(PLANE,2),a2(X+(1-P)*W,Y),0)))^ ,^ if(eq(PLANE,0),b0(X-P*W,Y),^ if(eq(PLANE,1),b1(X-P*W,Y),^ if(eq(PLANE,2),b2(X-P*W,Y),0)))^ )' ^ -crf 23 -c:v h264 -pix_fmt yuv420p -movflags +faststart -r 25 -aspect 960:480 ^ out1.mp4 
@echo off @REM 使用内置的 slideleft 效果 ffmpeg -y -hide_banner ^ -f lavfi -i "pal100bars=r=1/1000" ^ -f lavfi -i "colorchart=r=1/1000" ^ -filter_complex ^ [0:v]format=yuv420p,scale=960:480,fps=25,trim=duration=40[v1];^ [1:v]format=yuv420p,scale=960:480,fps=25,trim=duration=40.04[v2];^ [v1][v2]xfade=duration=40:offset=0:transition=slideleft ^ -crf 23 -c:v h264 -pix_fmt yuv420p -movflags +faststart -r 25 -aspect 960:480 ^ out2.mp4 

这里使用的动画时长是 40 秒,可以自行修改成 0~60 秒。
在我电脑上运行,耗时分别是:自定义17.514 秒,内置1.605 秒
可以看出,使用自定义的效果,远比内置效果更耗时。原因我们在“理解 expr”有提过,因为每一帧需要调用 expr 次数=960×480×3=1,382,400 。一百多万次。而且是纯 CPU 运算,因此效率自然底下。

好在一般的过场时长是 3 、4 秒左右,影响还在可接受范围内。

如果你在寻找更高效的自定义效果,可以考虑使用xfade_opencl过滤器,或者自行编译 ffmpeg ,加入gl-transition过滤器。

其它转场过滤器

xfade_opencl

要使用xfade_opencl,需要编译的时候加入--enable-opencl,且运行的机器有支持 opencl 的设备(一般指显卡)。
要查看当前机器有哪些 opencl 的设备,可以运行以下命令:

ffmpeg -v debug -init_hw_device opencl 

打印出类似信息:

[AVHWDeviceContext @ 0000027894f28400] 1 OpenCL platforms found. [AVHWDeviceContext @ 0000027894f28400] 1 OpenCL devices found on platform "NVIDIA CUDA". [AVHWDeviceContext @ 0000027894f28400] 0.0: NVIDIA CUDA / NVIDIA GeForce RTX ***** 

其中0.0就是可用的 opencl 设备编号,在 ffmpeg 命令中指定使用该设备:

ffmpeg -y -hide_banner -init_hw_device opencl=ocldev:0.0 -filter_hw_device ocldev ^ -f lavfi -r 25 -t 40 -i "pal100bars" ^ -f lavfi -r 25 -t 40.04 -i "colorchart" ^ -filter_complex ^ [0:v]format=yuv420p,scale=960:480,hwupload[v0];^ [1:v]format=yuv420p,scale=960:480,hwupload[v1];^ [v0][v1]xfade_opencl=duration=40:offset=0:transition=slideleft,hwdownload,format=yuv420p ^ -c:v h264_nvenc -pix_fmt yuv420p -movflags +faststart -r 25 -aspect 960:480 ^ out3.mp4 

性能比自定义 xfade 效果好很多,唯一要求就是需要支持 opencl 的设备(一般指显卡)。
且,xfade_opencl也是支持自定义效果的,官方文档
内置的几个效果的源码可以查看 GitHub 上 ffmpeg 的源码:https://github.com/FFmpeg/FFmpeg/blob/master/libavfilter/opencl/xfade.cl

gl-transition

gl-transitions是由开发者 Gilles Lamothe 创建的,它封装了大量的 GPU 加速过渡效果,包括但不限于溶解、推拉、旋转等多种类型。这些过渡效果可以轻松地整合到你的图形应用程序中,无论你是开发游戏、视频编辑软件还是实验性的艺术项目。
它使用 OpenGL 进行加速,因此,也需要支持 OpenGL 的设备(一般指显卡)。
它不是 ffmpeg 专属的,但是可以做为一个过滤器添加到 ffmpeg 中。参考这个 GitHub 项目transitive-bullshit/ffmpeg-gl-transition。 编译后,你将可以使用其官网上的所有效果,当然也可以自己编写自定义的效果。

性能方面,因为我没有自行编译测试,所以无法给出具体数据。

它使用 GLSL 语言编写,如果你看了上面 OpenCL 的部分,你会发现它们有很多共同点。
甚至,我在编写xfade自定义表达式的时候,也参考了它的 GLSL 代码。比如效果预览中的水滴,就是参考了WaterDrop

结语

不知道是 ffmpeg 官方觉得 xfade 的 expr 编写太过容易,还是觉得性能不行不建议使用,反正官方文档及 wiki 都没有示例,也没有提及如何编写。
我自己基本上是自己看着文档猜测、尝试,慢慢的摸索出来一些门道。想着网上没有一个类似的教程,于是变写了这个文章。
如果你发现文章哪里有问题,欢迎指出,大家共同进步。

本文存档:https://github.com/jifengg/ffmpeg-script/blob/main/docs/ffmpeg.xfade.md

]]>
关于我在 fcp 导入视频时出现的无法解决的问题,请求各位 ffmpeg 大佬的帮忙 tag:www.v2ex.com,2024-06-06:/t/1047493 2024-06-06T13:30:59Z 2024-06-06T14:39:09Z ruoqin member/ruoqin (虽然说是 fcp 的问题,但归根到底还是视频编码的问题,熟悉 ffmpeg 的朋友做熟悉不过视频编码了)

本人在用系统 macos sonama 14.5 fcp 版本为 10.6.5 已知 fcp 支持导入 hevc 视频,图证 https://imgse.com/i/pkY4h9S 使用了两个相同内容的素材,分别为两位压制者进行的压制,其中上图可以正常导入 fcp ,下图并不可以 https://imgse.com/i/pkY47Bn https://imgse.com/i/pkY45cQ 本人琢磨了半天也不明白,感觉应该和 hevc 问题不大,可能是其他项的问题 我又拿了一个完全不一样的视频进行了证明,该视频可正常导入 fcp ,mediainfo 如图 https://imgse.com/i/pkY5pu9

如果您有头绪,麻烦请告诉我,我感激不谢!

]]>
go + ffmpeg pipe 怎么确定当前转码操作已经结束,可以停了 tag:www.v2ex.com,2024-05-27:/t/1044186 2024-05-27T01:46:18Z 2024-05-27T02:38:34Z dzdh member/dzdh 伪代码如下:

func main() { url := "http://a.mp4" args := strings.Split("ffmpeg -y -i pipe:0 -f mpegts pipe:1", " ") ctx, cancel := context.WithCancel(context.Background()) cmd := exec.CommandContext(ctx, args[0], args[1:]...) pipe0, _ := cmd.StdinPipe() pipe1, _ := cmd.StdoutPipe() cmd.Start() go func () { cmd.Wait() } go func () { file := os.Openfile.... io.Copy(file, pipe1) } io.Copy(pipe0, http.resp.body) } 

问题是,write 完成了,但是我不确定转码完成了没。去监听 stderr 吗?看 stderr 的已完成转码时长是不是等于预期?

]]>
给人声视频加入背景声音,如何做到自动调整背景的音量 tag:www.v2ex.com,2024-05-21:/t/1042677 2024-05-21T08:21:33Z 2024-05-21T09:21:33Z cnleoyang member/cnleoyang
目前尝试了 filter_complex amerge ,但没有实现期待的效果。请教大家这样的 ffmpeg 命令可以怎样写,谢谢。 ]]>
使用 ffmpeg 用 aes 加密 m3u8 文件的疑惑 tag:www.v2ex.com,2024-04-15:/t/1032560 2024-04-15T03:20:18Z 2024-04-15T07:01:39Z rqxiao member/rqxiao 使用 ffmpeg 用 aes 加密 m3u8 文件流程

1.准备加密密钥

openssl rand 16 > enc.key

2.生成 IV

3 创建 enc.info 文件

然后利用 ffmpeg 进行加密 ffmpeg -y
-i test.mp4
-hls_time 9
-hls_key_info_file enc.info
-hls_playlist_type vod
-hls_segment_filename "index%d.ts"
playlist.m3u8

结果是播放器不能直接打 ts 文件开播放。达到了对 ts 文件加密的效果?

但是假设前端去实现播放视频的功能时,不还是要向后端获取 m3u8 文件吗,因为 m3u8 文件里有着秘钥 。只要获取到 m3u8 文件就能播放了。也就是说只要能够获取到 m3u8 文件就能播放加密的 ts 文件,那如果通过抓包工具获取到 m3u8 地址,那 ts 加密不是没用了吗

]]>
把歌曲压缩至 7 kbps, FFmpeg 之父发布音频压缩工具 TSAC tag:www.v2ex.com,2024-04-09:/t/1030949 2024-04-09T05:37:16Z 2024-04-10T18:06:05Z DTCPSS member/DTCPSS https://bellard.org/tsac/
FFmpeg 之父 Fabrice Bellard 发布音频压缩工具 TSAC 。
对于 44.1 kHz 的音频,可压缩至 5.5 kb/s (单声道)或 7.5 kb/s (立体声)。
可将一首 3.5 分钟的立体声乐曲压缩至 192 KiB 。

讨论:
https://hydrogenaud.io/index.php/topic,125765 ]]>
求助使用 ffmpeg 压缩.mov 视频输出后丢失元数据问题如何解决 tag:www.v2ex.com,2023-11-13:/t/991416 2023-11-13T03:52:42Z 2023-11-13T04:01:35Z qingf member/qingf 由于 iPhone 之前拍摄的 4k60fps 视频体积比较大,希望用电脑压缩后放在 icloud 方便以后随时观看,希望仅是压缩视频体积,保留之前的拍摄时间、经纬度、手机型号等元数据。

在网上搜索一番后,整了个 ffmpeg 工具命令,探索下来,压缩的功能没有问题挺 ok 的,但是在保留元数据的地方总是卡壳,输出的视频带不上原来的经纬度等信息。

环境是 mac ,命令如下,已经添加了网上说的 map_metadata 和 movflags 两个参数,但是输出的文件中还是没有元数据

ffmpeg -i input.mov -c:v copy -c:a copy -map_metadata 0 -movflags use_metadata_tags output.mp4 

尝试使用了 hevc 和 h264 好像也都不行,有老哥可以帮忙指导一下的,感激不尽

]]>
homebrew 安装的 fmpeg 转码速度比较慢?直接编译可以提高速度吗? tag:www.v2ex.com,2023-10-24:/t/984847 2023-10-24T03:35:27Z 2023-10-24T11:58:10Z 1dian01 member/1dian01 使用 nodejs 调用和在 macos 终端里直接调用 ffmpeg 转 m3u8,两者花费时间相差巨大 tag:www.v2ex.com,2023-09-15:/t/974227 2023-09-15T11:15:00Z 2023-09-15T11:23:49Z nathanleeinph member/nathanleeinph 对于同一个 m3u8 及其 ts 资源,体积为 2.8g 左右,文件数 2760 个

使用 macOS 自带终端运行:ffmpeg -i ./index.m3u8 -c copy test.mp4 和在 nodejs 里使用“fluent-ffmpeg”这个库(依然是使用‘/opt/homebrew/Cellar/ffmpeg/6.0/bin/ffmpeg’)处理

终端处理仅仅需要 30 秒不到

而 nodejs 运行则需要 21 分钟

我是 nodejs 小白,执行命令的方式是在 vscode 这个编辑器里的终端执行 node ./foo.js

有人了解这个巨大差异产生的原因吗?

我推测是不是 vscode 或者 nodejs 只使用了单线程的关系??

]]>
FFmpeg 如何录屏时排除录制指定的某个窗口 tag:www.v2ex.com,2023-07-04:/t/954076 2023-07-04T10:08:29Z 2023-07-04T16:23:26Z JasonQin member/JasonQin 就像某些屏幕共享软件一样,录制整个屏幕的同时最上层还有操作录屏关闭之类的 UI ,这个是不会被录制进去的,如何实现这种功能,我查了 FFmpeg 的 gdigrab 只能选 desktop 或者 title 指定录制某一个窗口,没有排除功能,请教一下这种是如何实现的。

]]>
ffmpeg 最近大版本发布为啥这么快 tag:www.v2ex.com,2023-06-20:/t/950202 2023-06-20T01:48:21Z 2023-06-20T00:48:21Z datadump member/datadump
是接口还是架构发生重大改变?

有木有懂的兄弟说下。谢谢了 ]]>
ffmpeg 如何加快解码速度?算力不变的情况下,不在乎解码质量 tag:www.v2ex.com,2023-06-12:/t/947857 2023-06-12T00:41:03Z 2023-06-14T10:40:18Z 1054850490 member/1054850490 `
如上述代码所示,如何在同等算力条件下,加快“解码”速度,注意,这里不是编码,是解码,而且据我测试,12490F 对比 3080 的解码器也快不过 CPU ,这是因为视频文件需要在显存和内存之间频繁交换,反而导致解码变慢了。虽然在 av01 以及 8K 的情况下比不过显卡的解码,但是 6 核的 12490f 已经是比 3080 的解码器快了,(虽然 3080 支持双路,单路性能限制一半,暂且按下不表),所以让我换显卡解码加快这个提议已经 pass 了

我为什么要这样做是因为,我需要一帧一帧拆开看看视频有没有损坏,因为我用下载器下载的视频合成的时候总是出现破损的视频文件,而用重封装查损并不适用于大多场景,所以还是回到最稳的一帧一帧的拆包看,可是这个方案还是太慢了,如果升级机器也不太现实,只能是寻求歪路子,我看到某些解码器可以通过降低解码质量从而让低配机器也可以流畅播放高质量视频的时候就在想,我是否也可以按照这个方法来?我问过 GPT ,但是 GPT 给出的答案是让我降低分辨率,也就是-s 1280p-720p 选项,但是这样其实更慢了,我觉得更像是重编码了一样,虽然降低了分辨率,可是中间一定是有一个再转码的过程导致吃的损耗更多了 ]]>
FFmpeg 怎么支持 segment_size 选项? tag:www.v2ex.com,2023-04-19:/t/933845 2023-04-19T13:32:14Z 2023-04-20T05:19:26Z icoming member/icoming 用来限定文件分段大小的这个选项

ChatGPT 说从 4.1 版本( 2018 年 11 月发布的)开始有这选项,但是我在官网下载的编译好的没有这个选项啊

然后我就想自己编译,Git clone 源码后,按照 ChatGPT 说的配置添加 segment 支持后编译安装,结果还是没有这个选项

./configure --enable-gpl --enable-libx264 --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx --enable-libx265 --enable-libaom --enable-version3 --enable-libfdk-aac --enable-nonfree --enable-muxer=segment 

到底 FFmpeg 有没有这个选项???

]]>
为什么 ffmpeg 的体积会这么大?多复杂的算法编译后也不会有几十 MB 吧? tag:www.v2ex.com,2023-03-25:/t/927148 2023-03-25T10:49:12Z 2023-03-26T21:33:09Z LLaMA member/LLaMA FFmpeg 使用 debug_ts 打印全过程的 pts tag:www.v2ex.com,2023-03-15:/t/924379 2023-03-15T18:44:46Z 2023-03-15T18:41:46Z loken2020 member/loken2020 简介:音视频开发的一个烦恼的点,是时间总是不对。这时候你可以打开 debug_ts 选项,查看 demuxer , 解码,编码,muxer 过程中的 pts 的信息
https://ffmpeg.xianwaizhiyin.net/ffmpeg/debug_ts.html ]]>
ffmpeg 如何更快速的查询视频的"缺帧" tag:www.v2ex.com,2023-02-25:/t/919129 2023-02-25T07:32:56Z 2023-02-25T19:50:09Z 1054850490 member/1054850490 ```
ffmpeg -v 16 -stats -hwaccel cuda -i 1.mkv -map v -fps_mode cfr -stats_period "0.05" -f null -
```
我来讲一下原理,其他不重要,主要是`-fps_mode cfr`,这个命令可以在遇到时间戳对不上的情况下补帧,虽然是补帧,但是这个补并不是我们想象中的那个补运动帧,而是将当前的帧当做下一帧继续播放。

我们先来看看官方文档的描述


我来举例,当一部视频帧数为 30 帧的时候,当你设定了 60 帧输出的时候,是不是每一秒都缺了一半?这时候这个命令就会自动的把不够的帧自动补上,但是这补帧,更像是隔行扫描的视频转到逐行扫描上播放使用的"去隔行处理"。

另一种案例就是我的案例了,大家经常下载文件的时候都遇到过不完整的情况吧?比如臭名昭著的"百度云盘",下载没带校检,如果是视频还好,因为视频缺了中间部分并不影响播放,如果是文件直接就宣告整个文件的死刑了,压缩包更不用说了,所以我的问题就是下载视频的过程中,由于网络波动的影响经常导致文件不完整,而我就是想要找出到底哪个视频文件不完整。
视频的元数据里,开头就描述了该视频该采用多少帧率播放,列如一部视频自己元数据描述了帧数是 30F ,但是视频的中间数据丢失了,就会导致下图中的后果

绿色竖线左右空白的地方就是"缺帧"的部分,当使用以上命令进行补帧的时候,就会出现“dup”参数,dup 后面的数字参数就是指补了多少帧

图中可以看到这个视频缺了 853 帧,借助这个方法,间接的观察视频的完整性,这个方法也适用于 115 以及百度云下载的视频文件不完整的筛选
但是这个方法缺点就是,太慢了,太太太慢了!!!!我本机配置是 12490f+1660ti ,但是我显卡的编码器还没我的 CPU 快,以下是我的测速

speed 就是速度,越高越好,可以看到 GPU 明显不如 CPU ,这又是为什么呢,我用 potplayer 硬解 1660ti 8K 片源很轻松,但是 12490f 解码 8K 有点吃力了,我又看到官方文档的一篇解释

感觉是我有某些地方没设置好导致的差异,因为我用 ffmpeg 硬解的时候发现只占用了 50%-60%左右,根本没吃满。
以上所述完了,我的需求就是让这个过程,更加的“省时间”,毕竟这个间接观察大法还是太耗算力,如果能稍微优化一下也好,我现在检索 2T 的视频的时候,通常都需要 5 天左右的时间才检索完,这速度实在是太慢了,我在想,就是能不能降低解码的质量换取速度,毕竟我也看不着这个画面,不知道能不能降低他的解码算力需求让我速度提升

下面提供一个损坏的视频样片,供你尝试
https://drive.google.com/file/d/1TDbxYD0vri0D8aIJ6a1OSY2abE9tc6Lk/view?usp=share_link ]]>
如何将 AVS3 8KHDR 视频转码为 HEVC 8KHDR 视频? tag:www.v2ex.com,2023-01-20:/t/910059 2023-01-20T09:15:14Z 2023-01-20T09:33:50Z starryloki member/starryloki
ffmpeg -i input.ts -max_muxing_queue_size 999999 -pix_fmt yuv420p10le -c:v libx265 -x265-params "profile=main10:high-tier=true:colorprim=bt2020:transfer=smpte2084:colormatrix=bt2020nc" -c:a copy output.mkv

随后运行提示 “[mpegts @ 000002098fdd71c0] Could not find codec parameters for stream 0 (Video: avs3 (libuavs3d) ([212][0][0][0] / 0x00D4), yuv420p10le): unspecified size
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options”

后续报错 "[buffer @ 00000209ac41c040] Unable to parse option value "0x0" as image size
[buffer @ 00000209ac41c040] Error setting option video_size to value 0x0.
[graph 0 input from stream 0:0 @ 00000209909a7bc0] Error applying options to the filter.
Error reinitializing filters!
Error while filtering: Invalid argument
Finishing stream 0:0 without any data written to it."

这个视频使用 MPC-HC 播放器可以正常播放,ffmpeg 的解码器有 libuavs3d ,请问应该如何正确解码这个视频? ]]>
请教大佬们,在线网站抓到 m3u8 能播放,但是用 ffmpeg 下载的时候 “403 forbidden” 或者 “Output file #0 does not contain any stream” 应该怎么解决 tag:www.v2ex.com,2023-01-03:/t/906182 2023-01-03T02:24:45Z 2023-01-03T18:35:41Z rrubick member/rrubick 有的网站能正常下,有的就会报错。

使用命令如下: ffmpeg -i url -c copy output.mp4

]]>
FFmpeg 使用 qsv 加速失败 tag:www.v2ex.com,2022-11-13:/t/894947 2022-11-13T13:13:09Z 2022-12-01T23:46:06Z wapollo9 member/wapollo9 ffmpeg 命令如下

ffmpeg -y -c:v h264_qsv -i input.mp4 -c:v hevc_qsv -low_power 1 output.mp4 

输出的错误信息如下

[hevc_qsv @ 0x562ef30a0480] Selected ratecontrol mode is unsupported [hevc_qsv @ 0x562ef30a0480] some encoding parameters are not supported by the QSV runtime. Please double check the input parameters. Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height [aac @ 0x562ef34099c0] Qavg: 65536.000 [aac @ 0x562ef34099c0] 2 frames left in the queue on closing Conversion failed! 

vainfo 输出如下

Trying display: wayland Trying display: x11 error: can't connect to X server! Trying display: drm vainfo: VA-API version: 1.16 (libva 2.16.0) vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 22.4.4 () vainfo: Supported profile and entrypoints VAProfileNone : VAEntrypointVideoProc VAProfileNone : VAEntrypointStats VAProfileMPEG2Simple : VAEntrypointVLD VAProfileMPEG2Main : VAEntrypointVLD VAProfileH264Main : VAEntrypointVLD VAProfileH264Main : VAEntrypointEncSliceLP VAProfileH264High : VAEntrypointVLD VAProfileH264High : VAEntrypointEncSliceLP VAProfileVC1Simple : VAEntrypointVLD VAProfileVC1Main : VAEntrypointVLD VAProfileVC1Advanced : VAEntrypointVLD VAProfileJPEGBaseline : VAEntrypointVLD VAProfileJPEGBaseline : VAEntrypointEncPicture VAProfileH264ConstrainedBaseline: VAEntrypointVLD VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP VAProfileVP8Version0_3 : VAEntrypointVLD VAProfileHEVCMain : VAEntrypointVLD VAProfileHEVCMain : VAEntrypointEncSliceLP VAProfileHEVCMain10 : VAEntrypointVLD VAProfileHEVCMain10 : VAEntrypointEncSliceLP VAProfileVP9Profile0 : VAEntrypointVLD VAProfileVP9Profile1 : VAEntrypointVLD VAProfileVP9Profile2 : VAEntrypointVLD VAProfileVP9Profile3 : VAEntrypointVLD VAProfileHEVCMain422_10 : VAEntrypointVLD VAProfileHEVCMain444 : VAEntrypointVLD VAProfileHEVCMain444 : VAEntrypointEncSliceLP VAProfileHEVCMain444_10 : VAEntrypointVLD VAProfileHEVCMain444_10 : VAEntrypointEncSliceLP 

CPU 和 GPU 分别如下

CPU: Intel Celeron N5105 (4) @ 2.900GHz GPU: Intel JasperLake [UHD Graphics] 

谢谢各位了

]]>
使用 ffmepg 把图片和长音频转换为视频的时候,视频和音频的时间对不上,声音也减少了一半 tag:www.v2ex.com,2022-11-11:/t/894507 2022-11-11T07:55:59Z 2022-11-12T06:01:58Z naldo0193 member/naldo0193 待合成的图片只有一张,音频长 7 小时左右 输出的视频,开头少几秒,输出视频和原音频声量少了一半。

命令如下: ffmpeg.exe -r 10 -loop 1 -i 5197.jpg -i audio5197.wav -c:v libx264 -x264-params keyint=1:scenecut=0 -c:a aac -b:a 32k -pix_fmt yuvj420p -shortest out.mp4

]]>
FFmpeg 解码器如何识别码流格式变了? tag:www.v2ex.com,2022-11-02:/t/892099 2022-11-02T07:03:07Z 2022-11-02T17:03:55Z JusticeLanding member/JusticeLanding 目前,小弟在做基于 ffplay 的播放器,目前碰到个问题。

有这么个场景,服务端那边跟播放器一个 ts 链接里,有可能碰到 264 数据后面直接紧跟着 265 的数据。

而播放器不知道码流切换了,264 的 AVCodec 碰到 265 的数据,当然就报错,导致播放器卡住。

现在在想,如何不修改服务端的情况,264 解码器识别出切 265 了,还有 265 解码器识别出切 264 了。

尝试在 libavcodec 里的 h2645_parse.c 里把错误识别,抛出去,但是可能小弟对 ffmepg 还不够熟悉,有些正常解码 264 的情况也会有解码失败的报错。

所以,有大神能指导下吗?想要直接去拦截比特数据,找起始码 0001 ,识别 264 、265 ,但是这好像要 ffmpeg 很底层,稍上层拿到的都是 pkt ,frame 。这也太难了

]]>
ffmpeg 提取音频中有声部分并单独生成文件 tag:www.v2ex.com,2022-11-02:/t/891984 2022-11-02T02:10:27Z 2022-11-02T02:32:23Z PuppetFrost member/PuppetFrost 目前的音频波形是这样: https://imgur.com/a/L86Y5aX
红框内为静音部分。
现在想要将其中每个有声音的部分,都单独提取出来生成文件。也就是说,客服人员(客户)说的每句话都单独生成一个独立的 wav 文件,自己尝试了下 silencedetect 无果,请问各位大佬 ffmpeg 可以做到这一点么? ]]>
ffplay 如何并行下载 m3u8 tag:www.v2ex.com,2022-10-28:/t/890601 2022-10-28T02:21:55Z 2022-10-28T02:21:55Z JusticeLanding member/JusticeLanding 小弟目前基于 ffplay 自己做一个播放器,现在想做 32 倍速快放,播的是 m3u8 ,10 秒一个 ts 分片,去掉 sleep ,只解码 I 帧,最多能 20 倍速。

达不到 32 倍速,于是查找瓶颈在哪。

试了非 10 秒分片的 ts ,这个 ts 包含 30 分钟的视频,这种情况能够达到 60 倍速。

所以瓶颈应该是 m3u8 里面每隔 10 秒,重新连 ts ,这个过程很耗时。

ffmpeg 好像有个 multiple_requests 的参数,可以复用一个链接,在 avformat_open_input 之前调用 av_dict_set_int(&opts, "multiple_requests", 1, 0) 可没看到效果。

哪位大佬指点下,有什么办法可破,谢谢!

]]>
如何用 ffmpeg 找到损坏的视频 50 块钱悬赏答案 tag:www.v2ex.com,2022-08-31:/t/876873 2022-08-31T20:58:30Z 2022-09-06T20:30:34Z 1054850490 member/1054850490
我用着 yt-dlp+aria2 下载着 youtube 视频,视频后处理是 ffmpeg ,因为下载的视频多大几万部,所以有个问题可能存在了很久但是一直没发现,就是有些视频损坏了,就是前面正常,但是后面其中某些段落播放花屏,但是我重新下载的时候又是好的,所以我猜测应该是合成 m3u8 的时候出现了错误,由于 aria2 的关系,下载的视频是分段下载的,而且一直是挂后台下载的,并没有日志,如果有小伙伴知道 yt-dlp 如何开启日志也可以告知。

我现在就是求如何从几万部视频中,自动化的识别出损坏的部分视频,我下面贴上损坏的视频下载链接,可以试一下

https://imgur.com/OXoRgP9
https://imgur.com/clQlBRZ


https://drive.google.com/file/d/1TDbxYD0vri0D8aIJ6a1OSY2abE9tc6Lk/view?usp=sharing
https://drive.google.com/file/d/1Z_kWFZp4YP5q16CixMv_RmlIWIXFTrzb/view?usp=sharing ]]>
ffmpeg 如何压缩 h.265 的视频不丢帧? tag:www.v2ex.com,2022-07-18:/t/866932 2022-07-18T02:55:44Z 2022-07-17T10:55:44Z yazoox member/yazoox 家里的两个摄像头,萤石的 C6C & C6CN ,使用群晖录像到 nas 硬盘里,即使我选择的是“标清”,但是体积还是太大了。一个摄像头,一天的视频就有 10G 左右,两个就是 20G 。

我尝试着下载了一个视频文件,大概 400MB 左右,然后用 ffmpeg 压缩了一下(压缩后的分辨率,我看了一下,能够接受)

ffmpeg -i c:\temp\1.mp4 -vf "scale=iw/4:ih/4" c:\temp\1-1.mp4 

体积能够缩小到 50MB 左右。但是,我发现压缩后的视频,拨放的时候,有的地方会“丢帧”,如图所示。命令行里面运行时,也会有一些错误提示,不清楚是什么原因造成的。

特来请教一下,有没有办法正常压缩不出错? ffmpeg 命令哪里用错了?

谢谢!

ffmpeg_PIC_20220714002.jpg ffmpeg_PIC_20220714003.jpg

]]>
有没有 win 下已编译好的 FLV 标准支持 H265 的 ffmpeg? tag:www.v2ex.com,2022-06-30:/t/863138 2022-06-30T02:58:41Z 2022-08-26T04:03:13Z icemanpro member/icemanpro 为什么有些视频体积这么大但是画质这么差? tag:www.v2ex.com,2022-06-23:/t/861714 2022-06-23T09:30:31Z 2022-06-23T17:33:20Z Awes0me member/Awes0me 比如这个,一集 1.7G ,1080p ,还以为是高清,点开看画质感觉是 480p ,是有人故意把体积和画面做大骗转存吗?

大明王朝 1566 2007.WEB-DL.Ep01.1080P.H264.AAC.mkv

jPpLV0.png

]]>
lalserver 流媒体(直播音视频网络传输)服务器 v0.30.1 2022.6.15 tag:www.v2ex.com,2022-06-16:/t/859987 2022-06-16T04:01:06Z 2022-06-16T00:01:06Z info521 member/info521 https://github.com/q191201771/lal/releases

[feat] HTTP-API:新增 start/stop_relay_pull 接口,支持 rtmp 和 rtsp ,支持设置超时时间,自动关闭,重试次数,rtsp 类型等参数


文档
https://pengrl.com/lal/#/ ]]>
[求助] mp4 录制,怎么才能不缓冲在内存中 tag:www.v2ex.com,2022-05-30:/t/856233 2022-05-30T07:36:26Z 2022-05-30T09:36:26Z JusticeLanding member/JusticeLanding 目前,小弟的手机播放器 app 有个视频录制功能,用 ffmpeg 库封装成 mp4 。

现在 ffmpeg 会先将录制的视频缓冲在内存中,等到停止录制,ffmpeg 在硬盘最开始写个 mp4 头部,然后把一整个内存里的视频数据写入硬盘,这样导致内存占用很大,而且还有 OOM 的风险。

所以想要找个能实时将录制的视频数据写入磁盘的办法。有没有大神指点一二?

]]>
ffmpeg 怎么处理 h265 切 h264 的直播流? tag:www.v2ex.com,2022-05-26:/t/855410 2022-05-26T04:23:03Z 2022-05-26T11:59:15Z JusticeLanding member/JusticeLanding 小弟在用 ffmpeg 做一个直播流的播放器,发现当直播流中 265 切成 264 ,播放器会卡死,查了下是 ffmpeg 的 265 封装器没法直接解析 264 的封装头部,于是找到解析报错的地方是在 ff_h2645_packet_split 里的 hevc_parse_nal_header 。 本以为把这个 ret 为负的报错抛上去就能解决了。 结果改完后,发现个别手机的正常 265 直播流也会 ret<0 ,这下不知道该怎么区分是编码格式切换引起还是个简单的 warning 了。 有大神能给点思路吗?

int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, void *logctx, int is_nalff, int nal_length_size, enum AVCodecID codec_id) { ...... if (codec_id == AV_CODEC_ID_HEVC) ret = hevc_parse_nal_header(nal, logctx); else ret = h264_parse_nal_header(nal, logctx); if (ret <= 0 || nal->size <= 0) { if (ret < 0) { av_log(logctx, AV_LOG_ERROR, "Invalid NAL unit %d, skipping.\n", nal->type); } pkt->nb_nals--; } ...... } 
]]>
为什么 ffmpeg 加不上 rotate 旋转参数 tag:www.v2ex.com,2022-04-20:/t/848180 2022-04-20T08:32:48Z 2022-04-20T15:58:48Z gtheone1 member/gtheone1
附上输出日志: https://netcut.cn/p/e321491f1686d4a5

这条执行之后,并没有旋转成功。因为 potplayer 播放过,ffprobe.exe 也播放过,画面并没有旋转

用 ffprobe -v quiet -print_format json -show_format -show_streams ,来查看转换后的视频的参数:

https://netcut.cn/p/2326a8e35c3a0e22

如上,没看见 rotate 参数被添加?按理说,不是会多出一行"rotate": "90" 吗? ]]>
关于 ffmpeg sdk 官方示例的问题 tag:www.v2ex.com,2022-03-27:/t/843234 2022-03-27T13:22:11Z 2022-03-27T15:39:29Z xQmQ member/xQmQ 初次使用 ffmpeg sdk 开发,如有莽撞,请各位见谅

因为毕设要求,需要 ffmpeg sdk 将 mp4 转封装切分为 m3u8 。从官方示例里拿 remuxing.c 编译尝试了一下,转封装切分倒是成功了,但是 m3u8 的 #EXT-X-MEDIA-SEQUENCE 标签不是从 0 开始,而是从 36 开始,到 40 结束(但是从 0.ts 到 40.ts 都切分出来了);#EXT-X-TARGETDURATION 标签为 5

我想请教一下,如何让它可以从 0 开始呢?切片的时间如何设置呢?

以下是代码 https://gist.github.com/xQmQ/3ce63bf6a234a5b4e28977c2debb35cd

编译 gcc -o remuxing remuxing.c -lavformat -lavcodec -lavutil

执行 ./remuxing input.mp4 output.m3u8

打印的输入文件和输出文件信息 https://gist.github.com/xQmQ/89c83d9da5611de03a4922d95f9f7668

]]>
ffmpeg 如何在合并视频的同时顺便调大音量 tag:www.v2ex.com,2022-02-19:/t/835111 2022-02-19T14:41:45Z 2022-05-23T00:12:32Z movq member/movq 我的需求是,合并两个视频(一个视频 A 放在左边,一个视频 B 放在右边),音频选择复制第一个视频的音频

 ffmpeg \ -i A.mp4 \ -i B.mp4 \ -filter_complex "[0:v]pad=iw*2:ih[v_wide];[v_wide][1:v]overlay=W/2:0[out_video]" \ -map "[out_video]" \ -c:v libx265 \ -crf 28 \ -map 0:a:0 \ -c:a copy -y \ ./C.mp4 

但是直接这么做,音量太小了,所以我又进行了一道步骤:把生成的视频 C ,进行音量提升的操作

 ffmpeg -i C.mp4 -af volume=20dB -c:v libx265 C_high_volume.mp4 

问题是,有没有办法把这两步合成为一步呢?(我觉得这样可以降低处理时间)

]]>
ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86