V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MOranonline
V2EX  ›  FFmpeg

使用 FFmpeg 和 GPU 实现最简“图片+无损音频=视频”的方法

  •  
  •   MOranonline · 4 天前 · 2530 次点击

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

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

    nvidia-smi
    

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

    • I think 1969 was second best.
    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"
    

    解析:

    • ffmpeg:开源命令行工具
    • -hwaccel cuda:启用 CUDA 硬件加速,利用 NVIDIA 显卡的 CUDA 核心来加速视频处理,从而提高处理效率。
    • -threads 24:设置处理时使用的线程数为 24 个,多线程加快处理速度,根据电脑配置增减。
    • -loop 1:使输入的图像循环播放,这里设置循环次数为 1 次,让图像持续显示。
    • -i "picture.png":指定输入文件为名为picture.png的图像文件。
    • -i "music.flac":指定输入文件为名为music.flac的音频文件。
    • -vf "hwupload":视频滤镜,将输入视频数据上传到硬件设备(这里与前面的硬件加速相关),以便后续在硬件上进行处理。
    • -c:v h264_nvenc:指定视频编码格式为 H.264 ,并使用 NVIDIA NVENC 编码器进行编码,利用 NVIDIA 显卡的编码能力来生成视频流。
    • -preset 0:设置编码预设,0 是最快但视频质量最差,可以按需提高。
    • -cq 23:设置恒定质量因子为 23 。恒定质量因子模式下,编码器会尝试保持输出视频质量恒定,通过调整码率来适应不同的场景复杂度。较低的 CQ 值通常意味着更高的质量,但可能产生更大的文件。
    • -rc constqp:指定使用恒定 QP (量化参数)模式进行编码,与-cq类似,用于控制视频质量。
    • -c:a flac:指定音频编码格式为 FLAC ,保持音频的原始编码格式不变
    • -shortest:使输出视频的时长与输入中最短的流的时长相同,即当音频和视频时长不同时,以最短的时长为准来生成输出视频,确保音频和视频同步结束。
    • "output.mkv":指定输出文件名为output.mkv,然后发到 B 站网盘就行了。

    批量处理:
    视频按顺序数字重命名(如 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.注意事项

    • 确保所有视频/图片格式被 FFmpeg 支持(jpg 格式图片需要额外命令转换)
    • 若视频名包含空格/符号,需用引号包裹路径:
    • 批处理脚本默认顺序执行,可通过多线程化进程(如 GNU Parallel )提速电脑包扛不住吧
      4.效果示例
    # 输入视频目录:
    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

    29 条回复    2025-03-30 15:35:17 +08:00
    butanediol2d
        1
    butanediol2d  
       4 天前
    emm 上传到 B 站的视频不是还会压缩一遍吗?用这种方式保存无损音频并不是很可行啊
    MOranonline
        2
    MOranonline  
    OP
       4 天前
    @butanediol2d 对√,问题是全存电脑里也扛不住啊。B 站音频压的不是特别狠,听的其实也还算可以。传国外去的话,我拒绝全时段科学上网。这是我当前想到的最优解馁。
    主要是有许多音频是音乐分享站油管 twitch 等乱七八糟的来源,不然就用落雪音乐之类的软件了。
    jisuowei
        3
    jisuowei  
       4 天前
    本人盲测过,听不出 flac/mp3 的区别,所以直接 ffmpeg: flac -> mp3 √,空间根本用不完
    cnbatch
        4
    cnbatch  
       4 天前
    买个 16T 机械硬盘,随便存
    wyntalgeer
        5
    wyntalgeer  
       4 天前   ❤️ 1
    1.Pr 也有 GPU 加速。
    2.ffmpeg 的 GPU 加速比 Pr 的 cpu 模式好一点,但仍是有损,你数据进了 GPU 就是浮点数了,怎么可能无损
    akatale
        6
    akatale  
       4 天前
    @butanediol2d b 站压缩视频,但目的是听歌,画面就是一张图片无所谓,投稿选择 hi-res 无损保音频就行
    jifengg
        7
    jifengg  
       4 天前
    这种简单需求其实可以不用 gpu ,用 cpu 足够了。
    在你的`-loop 1`后面加上`-r 1`
    表示输入图片按照 1 fps 循环,默认是 25fps ,这将提速将近 25 倍。
    你还可以试验一下,用 `-r 1/10`,可以提高 250 倍理论值,不过你最好看看传到 b 站有没有问题。
    stabc
        8
    stabc  
       4 天前
    无损音乐传 b 站不就变成有损了么
    mxalbert1996
        9
    mxalbert1996  
       3 天前   ❤️ 1
    ffmpeg 的默认 fps 是 25 ,对于静态视频来说太高了,你完全可以指定 -r 1 来设置 1fps 甚至更低,这样不仅能节约编码时间还能节省大小。
    然后你音频本来就已经是 flac 了,完全可以指定 -c:a copy 来直接复制音轨,节省重新编码音频的时间。
    MOranonline
        10
    MOranonline  
    OP
       3 天前
    @jifengg 有些音频是一个半小时的纯音循环 cpu 要跑半个多小时。另外,感谢。
    MOranonline
        11
    MOranonline  
    OP
       3 天前
    @mxalbert1996 感谢
    ashuai
        12
    ashuai  
       3 天前
    这些无损传 b 站没有版本问题么?
    ashuai
        13
    ashuai  
       3 天前
    打错了。。。没有版权问题吗?
    watermeter
        14
    watermeter  
       3 天前 via Android
    你让 b 站给你有损压缩一遍为什么不直接保存有损压缩的呢
    Greendays
        15
    Greendays  
       3 天前
    我现在都是直接听 aac 格式的音乐了,确实不太能听出无损和有损的区别,除非对比着听。楼主的脚本挺好的,也是个丰富生活的办法。
    samnya
        16
    samnya  
       3 天前   ❤️ 1
    这不就是一图流嘛,应该十几年前就有这么做的了,也是用 ffmpeg 节省渲染时间。应该可以把 I 帧间隔时间拉得特别长,让视频部分更省空间
    yazinnnn0
        17
    yazinnnn0  
       3 天前
    没必要转成视频, 静态图就用-c:v mjpeg 编码成图片就行, 除非你要把歌词/字幕硬编码到图像里

    比如

    ffmpeg -i 封面图.jpg -i 2.主人笑的话我也开心.mp3 -i ./2.主人笑的话我也开心.mp3.vtt -c:v mjpeg -vf scale=1280:-1 -c:a libopus -b:a 192k -to 665.600000 -disposition:a:0 default -disposition:s:0 default 2.主人笑的话我也开心.mkv
    MOranonline
        18
    MOranonline  
    OP
       3 天前
    @watermeter 音频从电脑中传出后,手机和平板也能共享歌单了。
    MOranonline
        19
    MOranonline  
    OP
       3 天前
    @yazinnnn0 感谢
    phew
        20
    phew  
       3 天前
    好多年前的操作了,小丸工具箱→一图流,最后生成出来就是 flv 格式,基本就是图片+音频的大小
    phew
        21
    phew  
       3 天前
    @phew 另外……哔哩哔哩其实是可以直接传音频的……它有一个哔哩哔哩音乐
    ryd994
        22
    ryd994  
       3 天前 via Android
    @jisuowei mp3 已经过时啦,现在用 AAC 。AAC 比 mp3 的码率更低,但是音质更好。
    cnbatch
        23
    cnbatch  
       3 天前
    诶,既然许多音乐来源于油管、twitch 等平台,它们的音频本身就是有损的吧( AAC 之类),怎么会是 flac
    jisuowei
        24
    jisuowei  
       3 天前
    @ryd994 那我现在 mp3 -> aac 是不是已经晚了,还得用 flac -> aac 再来一遍?
    MOranonline
        25
    MOranonline  
    OP
       3 天前
    @cnbatch 后悔加上“无损”二字了,我的主要意思其实是下载下来的音频不压缩传输,不是音频本身无损。下载的时候下载工具是可以转码的嘛,我看着 flac 顺眼就全转成 flac 了(**操作)(主要我也不知道原音频格式,它只让选下载后的格式)
    sunnysab
        26
    sunnysab  
       3 天前
    去年上半年收集了 800G 的无损,但是因为格式太乱没有整理,然后吃灰了一年……(捂脸)
    SenseHu
        27
    SenseHu  
       1 天前
    8T 的硬盘又不很贵, 传平台不怕哪天给你下架或者删了么
    codehz
        28
    codehz  
       1 天前
    我都是传 YT Music 的,免费有 10000 首可以传,虽然会压缩,但从 CD 转过去的听不出差别
    iorilu
        29
    iorilu  
       23 小时 40 分钟前
    b 站有哪些大量音乐的号推荐下阿 ,我也有着需求, 现在纯音乐都要会员了, 难找
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5120 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 07:15 · PVG 15:15 · LAX 00:15 · JFK 03:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.