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

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

  •  
  •   MOranonline · 26 天前 · 3061 次点击

    需求:搜集到的无损音乐太占空间,决定传到 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  
       26 天前
    emm 上传到 B 站的视频不是还会压缩一遍吗?用这种方式保存无损音频并不是很可行啊
    MOranonline
        2
    MOranonline  
    OP
       26 天前
    @butanediol2d 对√,问题是全存电脑里也扛不住啊。B 站音频压的不是特别狠,听的其实也还算可以。传国外去的话,我拒绝全时段科学上网。这是我当前想到的最优解馁。
    主要是有许多音频是音乐分享站油管 twitch 等乱七八糟的来源,不然就用落雪音乐之类的软件了。
    jisuowei
        3
    jisuowei  
       26 天前
    本人盲测过,听不出 flac/mp3 的区别,所以直接 ffmpeg: flac -> mp3 √,空间根本用不完
    cnbatch
        4
    cnbatch  
       26 天前
    买个 16T 机械硬盘,随便存
    wyntalgeer
        5
    wyntalgeer  
       26 天前   ❤️ 1
    1.Pr 也有 GPU 加速。
    2.ffmpeg 的 GPU 加速比 Pr 的 cpu 模式好一点,但仍是有损,你数据进了 GPU 就是浮点数了,怎么可能无损
    akatale
        6
    akatale  
       26 天前
    @butanediol2d b 站压缩视频,但目的是听歌,画面就是一张图片无所谓,投稿选择 hi-res 无损保音频就行
    jifengg
        7
    jifengg  
       26 天前
    这种简单需求其实可以不用 gpu ,用 cpu 足够了。
    在你的`-loop 1`后面加上`-r 1`
    表示输入图片按照 1 fps 循环,默认是 25fps ,这将提速将近 25 倍。
    你还可以试验一下,用 `-r 1/10`,可以提高 250 倍理论值,不过你最好看看传到 b 站有没有问题。
    stabc
        8
    stabc  
       26 天前
    无损音乐传 b 站不就变成有损了么
    mxalbert1996
        9
    mxalbert1996  
       26 天前   ❤️ 1
    ffmpeg 的默认 fps 是 25 ,对于静态视频来说太高了,你完全可以指定 -r 1 来设置 1fps 甚至更低,这样不仅能节约编码时间还能节省大小。
    然后你音频本来就已经是 flac 了,完全可以指定 -c:a copy 来直接复制音轨,节省重新编码音频的时间。
    MOranonline
        10
    MOranonline  
    OP
       26 天前
    @jifengg 有些音频是一个半小时的纯音循环 cpu 要跑半个多小时。另外,感谢。
    MOranonline
        11
    MOranonline  
    OP
       26 天前
    @mxalbert1996 感谢
    ashuai
        12
    ashuai  
       26 天前
    这些无损传 b 站没有版本问题么?
    ashuai
        13
    ashuai  
       26 天前
    打错了。。。没有版权问题吗?
    watermeter
        14
    watermeter  
       26 天前 via Android
    你让 b 站给你有损压缩一遍为什么不直接保存有损压缩的呢
    Greendays
        15
    Greendays  
       26 天前
    我现在都是直接听 aac 格式的音乐了,确实不太能听出无损和有损的区别,除非对比着听。楼主的脚本挺好的,也是个丰富生活的办法。
    samnya
        16
    samnya  
       26 天前   ❤️ 1
    这不就是一图流嘛,应该十几年前就有这么做的了,也是用 ffmpeg 节省渲染时间。应该可以把 I 帧间隔时间拉得特别长,让视频部分更省空间
    yazinnnn0
        17
    yazinnnn0  
       26 天前
    没必要转成视频, 静态图就用-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
       26 天前
    @watermeter 音频从电脑中传出后,手机和平板也能共享歌单了。
    MOranonline
        19
    MOranonline  
    OP
       26 天前
    @yazinnnn0 感谢
    phew
        20
    phew  
       26 天前
    好多年前的操作了,小丸工具箱→一图流,最后生成出来就是 flv 格式,基本就是图片+音频的大小
    phew
        21
    phew  
       26 天前
    @phew 另外……哔哩哔哩其实是可以直接传音频的……它有一个哔哩哔哩音乐
    ryd994
        22
    ryd994  
       26 天前 via Android
    @jisuowei mp3 已经过时啦,现在用 AAC 。AAC 比 mp3 的码率更低,但是音质更好。
    cnbatch
        23
    cnbatch  
       26 天前
    诶,既然许多音乐来源于油管、twitch 等平台,它们的音频本身就是有损的吧( AAC 之类),怎么会是 flac
    jisuowei
        24
    jisuowei  
       26 天前
    @ryd994 那我现在 mp3 -> aac 是不是已经晚了,还得用 flac -> aac 再来一遍?
    MOranonline
        25
    MOranonline  
    OP
       26 天前
    @cnbatch 后悔加上“无损”二字了,我的主要意思其实是下载下来的音频不压缩传输,不是音频本身无损。下载的时候下载工具是可以转码的嘛,我看着 flac 顺眼就全转成 flac 了(**操作)(主要我也不知道原音频格式,它只让选下载后的格式)
    sunnysab
        26
    sunnysab  
       26 天前
    去年上半年收集了 800G 的无损,但是因为格式太乱没有整理,然后吃灰了一年……(捂脸)
    SenseHu
        27
    SenseHu  
       24 天前
    8T 的硬盘又不很贵, 传平台不怕哪天给你下架或者删了么
    codehz
        28
    codehz  
       24 天前
    我都是传 YT Music 的,免费有 10000 首可以传,虽然会压缩,但从 CD 转过去的听不出差别
    iorilu
        29
    iorilu  
       23 天前
    b 站有哪些大量音乐的号推荐下阿 ,我也有着需求, 现在纯音乐都要会员了, 难找
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4963 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 03:45 · PVG 11:45 · LAX 20:45 · JFK 23:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.