tsai82118 发表于 2022-12-19 13:46:32

請教關於內嵌縮圖之FFmpeg語法問題

本帖最后由 tsai82118 于 2022-12-19 13:48 编辑

各位大佬們好,小弟剛剛上手使用FFmpeg的命令行語法進行影片轉檔作業,有些問題想要請教大佬

我了解FFmpeg會自動選擇Audio stream、Video stream以及Text-based Subtitle stream,但是不會自動選擇data stream或者attachment stream

但是假設我目前有一個MKV封裝的檔案,有內嵌了一個WebP格式的thumbnail縮圖,使用FFprobe得出如下資料
ENCODER : Lavf59.27.100
    Duration: 00:01:00.08, start: -0.007000, bitrate: 17865 kb/s
Stream #0:0(eng): Video: vp9 (Profile 0), yuv420p(tv, bt709), 3840x2160, SAR 1:1 DAR 16:9, 59.94 fps, 59.94 tbr, 1k tbn (default)
    Metadata:
    DURATION : 00:01:00.073000000
Stream #0:1(eng): Audio: opus, 48000 Hz, stereo, fltp (default)
    Metadata:
    DURATION : 00:01:00.081000000
Stream #0:2: Attachment: none
    Metadata:
    filename : cover.webp
    mimetype : image/webp
Unsupported codec with id 0 for input stream 2可以確認資料流#0:2就是Attachment stream,是WebP格式的內嵌縮圖。

我需要使用什麼語法才能讓FFmpeg在把這個MKV轉成MP4的時候一起把WebP的內嵌縮圖一起轉成JPEG然後也一起內嵌在最後的MP4裡面呢?

我嘗試使用 -map 0 把所有資料流通通打包,語法如下
"ffmpeg.exe" -i INPUT.mkv -map 0 OUTPUT.mp4但是似乎缺少要求FFmpeg將WebP轉檔的語法,所以FFmpeg直接跟我說選擇的容器MP4並不能接受WebP的內嵌縮圖
   Stream #0:0 -> #0:0 (vp9 (native) -> h264 (libx264))
   Stream #0:1 -> #0:1 (opus (native) -> aac (aac_mf))
   Stream #0:2 -> #0:2 (copy)請各位大佬若是方便,可以幫我看看能不能解決,因為網路上面的示範語法全部都是拿一個圖檔再mux進去的

難道我會需要先把MKV裡面的內嵌縮圖先導出然後再轉檔成JPEG然後再用FFmpeg把轉好MP4的檔再把縮圖mux進去嗎?

謝謝各位大佬的幫忙


StarRingChild 发表于 2022-12-19 16:23:50

你这 VP9 + Opus + WebP 就没一个 MP4 能封装的了的,全都得转码,可别瞎折腾了。
你这估计就是 YouTube 的视频,下载的时候选对应的编码和封装格式多省事

tsai82118 发表于 2022-12-19 22:03:29

本帖最后由 tsai82118 于 2022-12-19 22:05 编辑

確實需要轉碼,Video stream還有Audio stream目前都沒問題


就是不知道這個內嵌縮圖的語法到底該怎麼下才能讓FFmpeg幫我轉好以後一起壓到MP4裡面

Video stream還有Audio stream的語法我想說不影響所以就簡略了,全部大概是這樣

"C:\Program Files\ffmpeg-5.1.2-full_build-shared\bin\ffmpeg.exe" -loglevel repeat+level+info -hwaccel auto -i "C:\Users\User\Downloads\INPUT.mkv" -map 0:v -c:v libx264 -tune film -preset slow -profile:v high444 -crf 17 -x264opts opencl -x264-params opencl=true -vf "scale=w=-2:h=1080:in_h_chr_pos=0:in_v_chr_pos=0:sws_flags=spline+accurate_rnd+full_chroma_int+bitexact:sws_dither=x_dither:dst_range=1, colorspace=space=bt709:trc=bt709:primaries=bt709:range=pc" -movflags +write_colr+faststart -pix_fmt yuv444p10le -map 0:a -af aresample=48000:resampler=soxr:precision=28:swr_flags=res:dither_method=shibata -c:a aac_mf -cutoff 18000 -b:a 320k -map 0:s? -map 0:t "C:\Users\User\Downloads\OUTPUT.mp4"


tsai82118 发表于 2022-12-20 10:18:10

更新一下語法,前面那個語法沒有辦法把帶內嵌ASS字幕的MKV轉成內嵌字幕的MP4



嘗試過的正確語法如下
"C:\Program Files\ffmpeg-5.1.2-full_build-shared\bin\ffmpeg.exe" -loglevel repeat+level+info -hwaccel auto -i "C:\Users\User\Downloads\INPUT.mkv" -map 0:v -c:v libx264 -tune film -preset slow -profile:v high444 -crf 17 -x264opts opencl -x264-params opencl=true -vf "scale=w=-2:h='min(1080,ih)':in_h_chr_pos=0:in_v_chr_pos=0:sws_flags=spline+accurate_rnd+full_chroma_int+bitexact:sws_dither=x_dither:dst_range=1, colorspace=space=bt709:trc=bt709:primaries=bt709:range=pc" -movflags +write_colr+faststart -pix_fmt yuv444p10le -map 0:a -af aresample=48000:resampler=soxr:precision=28:swr_flags=res:dither_method=shibata -c:a aac_mf -cutoff 18000 -b:a 320k -map 0:s? -c:s mov_text -disposition:s:0 forced "C:\Users\User\Downloads\OUTPUT.mp4"有參考過yt-dlp的轉換縮圖格式的語法,轉成JPEG的話是類似如下 (Unix語法)
To .jpg: for i in *.webp; do ffmpeg -i "${i}" -q:v 1 -bsf:v mjpeg2jpeg "${i%.webp}.jpg"; done轉成PNG的話是類似如下 (Unix語法)
To .png: for i in *.webp; do ffmpeg -i "${i}" "${i%.webp}.png"; done但是如果直接引入在 -map 0:t? -c:t 後面的話無法執行


LittlePox 发表于 2022-12-20 12:15:50

本帖最后由 LittlePox 于 2022-12-20 12:17 编辑

ffmpeg使用的三个原则:
1. 如果你已经掌握其他工具可以做成这件事,不要去从零学习如何用ffmpeg;
2. 如果你可以通过多次调用ffmpeg达成目标,不要强行追求一行命令解决;
3. 如果混搭其他工具可以轻易解决问题,就不要头铁全部用ffmpeg解决。

学ffmpeg最常见的就是:钻研三天,编码三分钟,然后再也无用的知识在三小时后忘得一干二净。其实其他工具看似拙劣,三十分钟也足够你解决问题。


難道我會需要先把MKV裡面的內嵌縮圖先導出然後再轉檔成JPEG然後再用FFmpeg把轉好MP4的檔再把縮圖mux進去嗎?你是不是一定要这么做我说不好,但我是你的话,从一开始我就会这么做)

hirari_133 发表于 2023-1-27 12:36:46

本帖最后由 hirari_133 于 2023-1-27 12:38 编辑

不知道楼主解决了没有……感觉就像版主大大所说的,最好还是结合多种工具来实现这个目标。看楼主贴的代码,似乎是在 Linux 下操作?那 Shell 脚本写起来应该没什么问题。

测试环境:
Windows 10.0.19042.928 (20H2)
mkvinfo 73.0.0
mkvextract 73.0.0
ffprobe 5.1
magick 7.1.0-50 Q16-HDRI
ffmpeg 5.1
首先,可以用 MKVToolNix 来将图片附件提取出来,用其提供的 2 个命令行工具:mkvinfo 和 mkvextract,举例如下:

1. 假设我有一个名叫 01.mkv 的资源(其实是假面骑士黑日的 WebDL……),先查看其信息:

mkvinfo "C:\Users\User\Downloads\01.mkv"
2. 其返回的信息是:

+ EBML 头
|+ EBML 版本: 1
|+ EBML 读取版本: 1
|+ EBML ID 最大长度: 4
|+ EBML 大小最大长度: 8
|+ 文档类型: matroska
|+ 文档类型版本: 4
|+ 文档类型读取版本: 2
+ 剪辑: 大小 2252036409
|+ 定位头 (子条目将被跳过)
|+ EBML void: 大小 4012
|+ 剪辑信息
| + 时间戳缩放: 1000000
| + 混流应用程序: libebml v1.4.0 + libmatroska v1.6.2
| + 写入应用程序: mkvmerge v50.0.0 ('Awakenings') 64-bit
| + 时长: 00:41:52.128000000
| + 日期: 2022-10-27 15:09:24 UTC
| + 剪辑 UID: 0xa1 0x9a 0x7d 0xf6 0x29 0xee 0x12 0x76 0x9b 0xe3 0xbc 0x61 0x5b 0x10 0x14 0xaf
|+ 轨道
| + 轨道
|+ 轨道编号: 1 (mkvmerge & mkvextract 的轨道 ID: 0)
|+ 轨道 UID: 2483175821002277453
|+ 轨道类型: 视频
|+ 「紧缩」 标记: 0
|+ 编码格式 ID: V_MPEG4/ISO/AVC
|+ 编解码器私有数据: 大小 57 (H.264 档次: High @L4.0)
|+ 默认帧时长: 00:00:00.041708333 (对应视频轨的 23.976 帧/场每秒)
|+ 语言: und
|+ 语言 (IETF BCP 47): und
|+ 视频轨道
|   + 像素宽度: 1920
|   + 像素高度: 800
|   + 显示宽度: 1920
|   + 显示高度: 800
|   + 视频颜色信息
|    + 颜色矩阵系数: 1
|    + 颜色转换: 1
|    + 颜色基准: 1
| + 轨道
|+ 轨道编号: 2 (mkvmerge & mkvextract 的轨道 ID: 1)
|+ 轨道 UID: 8225765899614835249
|+ 轨道类型: 音频
|+ 编码格式 ID: A_EAC3
|+ 默认帧时长: 00:00:00.032000000 (对应视频轨的 31.250 帧/场每秒)
|+ 语言: jpn
|+ 语言 (IETF BCP 47): ja
|+ 音频轨
|   + 采样率: 48000
|   + 声道数: 6
| + 轨道
|+ 轨道编号: 3 (mkvmerge & mkvextract 的轨道 ID: 2)
|+ 轨道 UID: 454148574349024789
|+ 轨道类型: 字幕
|+ 「紧缩」 标记: 0
|+ 编码格式 ID: S_TEXT/UTF8
|+ 语言 (IETF BCP 47): en
| + 轨道
|+ 轨道编号: 4 (mkvmerge & mkvextract 的轨道 ID: 3)
|+ 轨道 UID: 15443355490271562602
|+ 轨道类型: 字幕
|+ 「默认轨」 标记: 0
|+ 「紧缩」 标记: 0
|+ 编码格式 ID: S_TEXT/UTF8
|+ 语言: chi
|+ 语言 (IETF BCP 47): zh
|+ EBML void: 大小 1169
|+ 附件
| + 附件
|+ 文件名: cover.png
|+ MIME 类型: image/png
|+ 文件数据: 大小 6322688
|+ 文件 UID: 16981705118869214229
|+ 簇
3. 可以看到封面图片是作为附件存在的,而且只有 1 个附件。为了对比,再用 ffprobe 看一下,ffprobe "C:\Users\User\Downloads\01.mkv",返回如下:

Input #0, matroska,webm, from '.\01.mkv':
Metadata:
    encoder         : libebml v1.4.0 + libmatroska v1.6.2
    creation_time   : 2022-10-27T15:09:24.000000Z
Duration: 00:41:52.13, start: 0.000000, bitrate: 7171 kb/s
Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x800 , 23.98 fps, 23.98 tbr, 1k tbn (default)
    Metadata:
      BPS-eng         : 6509571
      DURATION-eng    : 00:41:52.093000000
      NUMBER_OF_FRAMES-eng: 60230
      NUMBER_OF_BYTES-eng: 2044081252
      _STATISTICS_WRITING_APP-eng: mkvmerge v50.0.0 ('Awakenings') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2022-10-27 15:09:24
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:1(jpn): Audio: eac3, 48000 Hz, 5.1(side), fltp, 640 kb/s (default)
    Metadata:
      BPS-eng         : 640000
      DURATION-eng    : 00:41:52.128000000
      NUMBER_OF_FRAMES-eng: 78504
      NUMBER_OF_BYTES-eng: 200970240
      _STATISTICS_WRITING_APP-eng: mkvmerge v50.0.0 ('Awakenings') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2022-10-27 15:09:24
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:2(eng): Subtitle: subrip (default)
    Metadata:
      BPS-eng         : 35
      DURATION-eng    : 00:41:48.548000000
      NUMBER_OF_FRAMES-eng: 392
      NUMBER_OF_BYTES-eng: 11257
      _STATISTICS_WRITING_APP-eng: mkvmerge v50.0.0 ('Awakenings') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2022-10-27 15:09:24
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:3(chi): Subtitle: subrip
    Metadata:
      BPS-eng         : 34
      DURATION-eng    : 00:41:48.548000000
      NUMBER_OF_FRAMES-eng: 423
      NUMBER_OF_BYTES-eng: 10875
      _STATISTICS_WRITING_APP-eng: mkvmerge v50.0.0 ('Awakenings') 64-bit
      _STATISTICS_WRITING_DATE_UTC-eng: 2022-10-27 15:09:24
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Stream #0:4: Video: png, rgb24(pc), 2560x1920 , 90k tbr, 90k tbn (attached pic)
    Metadata:
      filename      : cover.png
      mimetype      : image/png
4. 可以看到封面图片被当作了 Stream 4,现在先用 mkvextract 来提取这个封面图片:

mkvextract "C:\Users\User\Downloads\01.mkv" attachments 1:"C:\Users\User\Downloads\cover.png"
5. 不过楼主的是 WebP 格式的图片,那建议用 ImageMagick 来转换一下,我印象中 FFmpeg 不太能处理图片来着……语法示例如下:

magick convert "C:\Users\User\Downloads\cover.webp" "C:\Users\User\Downloads\cover.png"
6. 这里为什么举例转换成 PNG 而非 JPG 后面会说明……接下来就是将封面封入 MP4 了(假设楼主已经得到了除了封面以外、其他都已经处理好了的 sample.mp4,位于桌面上):

ffmpeg -i "C:\Users\User\Desktop\sample.mp4" -i "C:\Users\User\Downloads\cover.png" -map 0 -c copy -map 1 -c:v:1 png -disposition:v:1 attached_pic "sample_withcover.mp4"
7. 上述这段代码来自 ffmpeg 官网,从这个链接(https://www.ffmpeg.org/ffmpeg.html#Main-options)进去,搜索「attached_pic」即可看到,不过官网目前(2023-01-27)给出的代码有点问题,会报错,我调整了一下参数顺序就好了。同时经过测试,只能附加 PNG,修改语句附加 JPG 会提示「Unknown encoder 'jpg'」。

这个 sample.mp4 是我自己渲染的一段视频,不是之前的 01.mkv,通过 ffprobe 可以看到如下信息:

1. 首先是 sample.mp4 的信息:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '.\sample.mp4':
Metadata:
    major_brand   : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.16.100
    comment         : Wed, 03.08.2022 12:15:14
Duration: 00:00:26.43, start: 0.000000, bitrate: 8611 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1920x1080, 8600 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       :
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 2 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       :
2. 其次是 sample_withcover.mp4 的信息:

stream 0, timescale not set
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '.\sample_withcover.mp4':
Metadata:
    major_brand   : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.27.100
    comment         : Wed, 03.08.2022 12:15:14
Duration: 00:00:26.43, start: 0.000000, bitrate: 9083 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1920x1080, 8600 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       :
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 2 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       :
Stream #0:2: Video: png, rgb24(pc), 1290x725 , 90k tbr, 90k tbn (attached pic)
如果要批量处理的话,用脚本把这些工具组合起来调用就可以了~

最后附上一张在 Windows 资源管理器下的效果图吧:



各工具官网:

1. https://mkvtoolnix.download/downloads.html
2. https://imagemagick.org/script/download.php
3. https://www.ffmpeg.org/download.html

哦,对了,封面图片是我随手找的(PID 75126666):



dtlnor 发表于 2023-1-28 03:10:58

前面说得对,如果你要mp4, 你为什么要用ffmpeg操作而不是从一开始在下载的时候就解决他呢()
比如这样
yt-dlp %addr% --embed-thumbnail --format "(bestvideo+bestaudio/bestvideo+bestaudio/bestvideo+bestaudio/best)"
页: [1]
查看完整版本: 請教關於內嵌縮圖之FFmpeg語法問題