找回密码
 立即注册
查看: 3506|回复: 6

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

1

主题

2

回帖

0

VC币

新手上路

Rank: 1

积分
123
tsai82118 发表于 2022-12-19 13:46:32 | 显示全部楼层 |阅读模式
本帖最后由 tsai82118 于 2022-12-19 13:48 编辑

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

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

但是假設我目前有一個MKV封裝的檔案,有內嵌了一個WebP格式的thumbnail縮圖,使用FFprobe得出如下資料
  1. ENCODER : Lavf59.27.100
  2.     Duration: 00:01:00.08, start: -0.007000, bitrate: 17865 kb/s
  3.   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)
  4.     Metadata:
  5.     DURATION : 00:01:00.073000000
  6.   Stream #0:1(eng): Audio: opus, 48000 Hz, stereo, fltp (default)
  7.     Metadata:
  8.     DURATION : 00:01:00.081000000
  9.   Stream #0:2: Attachment: none
  10.     Metadata:
  11.     filename : cover.webp
  12.     mimetype : image/webp
  13. Unsupported codec with id 0 for input stream 2
复制代码
可以確認資料流#0:2就是Attachment stream,是WebP格式的內嵌縮圖。

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

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

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

謝謝各位大佬的幫忙


回复

使用道具 举报

16

主题

293

回帖

504

VC币

白金会员

Rank: 12Rank: 12Rank: 12

积分
55631
StarRingChild 发表于 2022-12-19 16:23:50 | 显示全部楼层
你这 VP9 + Opus + WebP 就没一个 MP4 能封装的了的,全都得转码,可别瞎折腾了。
你这估计就是 YouTube 的视频,下载的时候选对应的编码和封装格式多省事
回复

使用道具 举报

1

主题

2

回帖

0

VC币

新手上路

Rank: 1

积分
123
tsai82118  楼主| 发表于 2022-12-19 22:03:29 | 显示全部楼层
本帖最后由 tsai82118 于 2022-12-19 22:05 编辑

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


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

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

  1. "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"
复制代码



回复

使用道具 举报

1

主题

2

回帖

0

VC币

新手上路

Rank: 1

积分
123
tsai82118  楼主| 发表于 2022-12-20 10:18:10 | 显示全部楼层
更新一下語法,前面那個語法沒有辦法把帶內嵌ASS字幕的MKV轉成內嵌字幕的MP4



嘗試過的正確語法如下
  1. "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語法)
  1. To .jpg: for i in *.webp; do ffmpeg -i "${i}" -q:v 1 -bsf:v mjpeg2jpeg "${i%.webp}.jpg"; done
复制代码
轉成PNG的話是類似如下 (Unix語法)
  1. To .png: for i in *.webp; do ffmpeg -i "${i}" "${i%.webp}.png"; done
复制代码
但是如果直接引入在 -map 0:t? -c:t 後面的話無法執行


回复

使用道具 举报

29

主题

520

回帖

1016万

VC币

超级版主

Rank: 28Rank: 28Rank: 28Rank: 28Rank: 28Rank: 28Rank: 28

积分
10303646

论坛管理组

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進去嗎?
你是不是一定要这么做我说不好,但我是你的话,从一开始我就会这么做)

回复

使用道具 举报

1

主题

2

回帖

0

VC币

注册会员

Rank: 2

积分
1382
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 个命令行工具:mkvinfomkvextract,举例如下:

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

  1. mkvinfo "C:\Users\User\Downloads\01.mkv"
复制代码

2. 其返回的信息是:

  1. + EBML 头
  2. |+ EBML 版本: 1
  3. |+ EBML 读取版本: 1
  4. |+ EBML ID 最大长度: 4
  5. |+ EBML 大小最大长度: 8
  6. |+ 文档类型: matroska
  7. |+ 文档类型版本: 4
  8. |+ 文档类型读取版本: 2
  9. + 剪辑: 大小 2252036409
  10. |+ 定位头 (子条目将被跳过)
  11. |+ EBML void: 大小 4012
  12. |+ 剪辑信息
  13. | + 时间戳缩放: 1000000
  14. | + 混流应用程序: libebml v1.4.0 + libmatroska v1.6.2
  15. | + 写入应用程序: mkvmerge v50.0.0 ('Awakenings') 64-bit
  16. | + 时长: 00:41:52.128000000
  17. | + 日期: 2022-10-27 15:09:24 UTC
  18. | + 剪辑 UID: 0xa1 0x9a 0x7d 0xf6 0x29 0xee 0x12 0x76 0x9b 0xe3 0xbc 0x61 0x5b 0x10 0x14 0xaf
  19. |+ 轨道
  20. | + 轨道
  21. |  + 轨道编号: 1 (mkvmerge & mkvextract 的轨道 ID: 0)
  22. |  + 轨道 UID: 2483175821002277453
  23. |  + 轨道类型: 视频
  24. |  + 「紧缩」 标记: 0
  25. |  + 编码格式 ID: V_MPEG4/ISO/AVC
  26. |  + 编解码器私有数据: 大小 57 (H.264 档次: High @L4.0)
  27. |  + 默认帧时长: 00:00:00.041708333 (对应视频轨的 23.976 帧/场每秒)
  28. |  + 语言: und
  29. |  + 语言 (IETF BCP 47): und
  30. |  + 视频轨道
  31. |   + 像素宽度: 1920
  32. |   + 像素高度: 800
  33. |   + 显示宽度: 1920
  34. |   + 显示高度: 800
  35. |   + 视频颜色信息
  36. |    + 颜色矩阵系数: 1
  37. |    + 颜色转换: 1
  38. |    + 颜色基准: 1
  39. | + 轨道
  40. |  + 轨道编号: 2 (mkvmerge & mkvextract 的轨道 ID: 1)
  41. |  + 轨道 UID: 8225765899614835249
  42. |  + 轨道类型: 音频
  43. |  + 编码格式 ID: A_EAC3
  44. |  + 默认帧时长: 00:00:00.032000000 (对应视频轨的 31.250 帧/场每秒)
  45. |  + 语言: jpn
  46. |  + 语言 (IETF BCP 47): ja
  47. |  + 音频轨
  48. |   + 采样率: 48000
  49. |   + 声道数: 6
  50. | + 轨道
  51. |  + 轨道编号: 3 (mkvmerge & mkvextract 的轨道 ID: 2)
  52. |  + 轨道 UID: 454148574349024789
  53. |  + 轨道类型: 字幕
  54. |  + 「紧缩」 标记: 0
  55. |  + 编码格式 ID: S_TEXT/UTF8
  56. |  + 语言 (IETF BCP 47): en
  57. | + 轨道
  58. |  + 轨道编号: 4 (mkvmerge & mkvextract 的轨道 ID: 3)
  59. |  + 轨道 UID: 15443355490271562602
  60. |  + 轨道类型: 字幕
  61. |  + 「默认轨」 标记: 0
  62. |  + 「紧缩」 标记: 0
  63. |  + 编码格式 ID: S_TEXT/UTF8
  64. |  + 语言: chi
  65. |  + 语言 (IETF BCP 47): zh
  66. |+ EBML void: 大小 1169
  67. |+ 附件
  68. | + 附件
  69. |  + 文件名: cover.png
  70. |  + MIME 类型: image/png
  71. |  + 文件数据: 大小 6322688
  72. |  + 文件 UID: 16981705118869214229
  73. |+ 簇
复制代码

3. 可以看到封面图片是作为附件存在的,而且只有 1 个附件。为了对比,再用 ffprobe 看一下,ffprobe "C:\Users\User\Downloads\01.mkv",返回如下:

  1. Input #0, matroska,webm, from '.\01.mkv':
  2.   Metadata:
  3.     encoder         : libebml v1.4.0 + libmatroska v1.6.2
  4.     creation_time   : 2022-10-27T15:09:24.000000Z
  5.   Duration: 00:41:52.13, start: 0.000000, bitrate: 7171 kb/s
  6.   Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x800 [SAR 1:1 DAR 12:5], 23.98 fps, 23.98 tbr, 1k tbn (default)
  7.     Metadata:
  8.       BPS-eng         : 6509571
  9.       DURATION-eng    : 00:41:52.093000000
  10.       NUMBER_OF_FRAMES-eng: 60230
  11.       NUMBER_OF_BYTES-eng: 2044081252
  12.       _STATISTICS_WRITING_APP-eng: mkvmerge v50.0.0 ('Awakenings') 64-bit
  13.       _STATISTICS_WRITING_DATE_UTC-eng: 2022-10-27 15:09:24
  14.       _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
  15.   Stream #0:1(jpn): Audio: eac3, 48000 Hz, 5.1(side), fltp, 640 kb/s (default)
  16.     Metadata:
  17.       BPS-eng         : 640000
  18.       DURATION-eng    : 00:41:52.128000000
  19.       NUMBER_OF_FRAMES-eng: 78504
  20.       NUMBER_OF_BYTES-eng: 200970240
  21.       _STATISTICS_WRITING_APP-eng: mkvmerge v50.0.0 ('Awakenings') 64-bit
  22.       _STATISTICS_WRITING_DATE_UTC-eng: 2022-10-27 15:09:24
  23.       _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
  24.   Stream #0:2(eng): Subtitle: subrip (default)
  25.     Metadata:
  26.       BPS-eng         : 35
  27.       DURATION-eng    : 00:41:48.548000000
  28.       NUMBER_OF_FRAMES-eng: 392
  29.       NUMBER_OF_BYTES-eng: 11257
  30.       _STATISTICS_WRITING_APP-eng: mkvmerge v50.0.0 ('Awakenings') 64-bit
  31.       _STATISTICS_WRITING_DATE_UTC-eng: 2022-10-27 15:09:24
  32.       _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
  33.   Stream #0:3(chi): Subtitle: subrip
  34.     Metadata:
  35.       BPS-eng         : 34
  36.       DURATION-eng    : 00:41:48.548000000
  37.       NUMBER_OF_FRAMES-eng: 423
  38.       NUMBER_OF_BYTES-eng: 10875
  39.       _STATISTICS_WRITING_APP-eng: mkvmerge v50.0.0 ('Awakenings') 64-bit
  40.       _STATISTICS_WRITING_DATE_UTC-eng: 2022-10-27 15:09:24
  41.       _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
  42.   Stream #0:4: Video: png, rgb24(pc), 2560x1920 [SAR 3780:3780 DAR 4:3], 90k tbr, 90k tbn (attached pic)
  43.     Metadata:
  44.       filename        : cover.png
  45.       mimetype        : image/png
复制代码

4. 可以看到封面图片被当作了 Stream 4,现在先用 mkvextract 来提取这个封面图片:

  1. mkvextract "C:\Users\User\Downloads\01.mkv" attachments 1:"C:\Users\User\Downloads\cover.png"
复制代码

5. 不过楼主的是 WebP 格式的图片,那建议用 ImageMagick 来转换一下,我印象中 FFmpeg 不太能处理图片来着……语法示例如下:

  1. magick convert "C:\Users\User\Downloads\cover.webp" "C:\Users\User\Downloads\cover.png"
复制代码

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

  1. 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 的信息:

  1. Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '.\sample.mp4':
  2.   Metadata:
  3.     major_brand     : isom
  4.     minor_version   : 512
  5.     compatible_brands: isomiso2avc1mp41
  6.     encoder         : Lavf59.16.100
  7.     comment         : Wed, 03.08.2022 12:15:14
  8.   Duration: 00:00:26.43, start: 0.000000, bitrate: 8611 kb/s
  9.   Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1920x1080, 8600 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
  10.     Metadata:
  11.       handler_name    : VideoHandler
  12.       vendor_id       : [0][0][0][0]
  13.   Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 2 kb/s (default)
  14.     Metadata:
  15.       handler_name    : SoundHandler
  16.       vendor_id       : [0][0][0][0]
复制代码

2. 其次是 sample_withcover.mp4 的信息:

  1. [mov,mp4,m4a,3gp,3g2,mj2 @ 000002495e52a940] stream 0, timescale not set
  2. Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '.\sample_withcover.mp4':
  3.   Metadata:
  4.     major_brand     : isom
  5.     minor_version   : 512
  6.     compatible_brands: isomiso2avc1mp41
  7.     encoder         : Lavf59.27.100
  8.     comment         : Wed, 03.08.2022 12:15:14
  9.   Duration: 00:00:26.43, start: 0.000000, bitrate: 9083 kb/s
  10.   Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1920x1080, 8600 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
  11.     Metadata:
  12.       handler_name    : VideoHandler
  13.       vendor_id       : [0][0][0][0]
  14.   Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 2 kb/s (default)
  15.     Metadata:
  16.       handler_name    : SoundHandler
  17.       vendor_id       : [0][0][0][0]
  18.   Stream #0:2[0x0]: Video: png, rgb24(pc), 1290x725 [SAR 13779:13779 DAR 258:145], 90k tbr, 90k tbn (attached pic)
复制代码

如果要批量处理的话,用脚本把这些工具组合起来调用就可以了~

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

2023-01-27 11 07 55.png

各工具官网:

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

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

镇楼

镇楼


回复

使用道具 举报

45

主题

523

回帖

126

VC币

至尊会员

Rank: 16Rank: 16Rank: 16Rank: 16

积分
164838
dtlnor 发表于 2023-1-28 03:10:58 | 显示全部楼层
前面说得对,如果你要mp4, 你为什么要用ffmpeg操作而不是从一开始在下载的时候就解决他呢()
比如这样
  1. yt-dlp %addr% --embed-thumbnail --format "(bestvideo[ext=webm][height>1080]+bestaudio[ext=webm]/bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio/best)[protocol^=http]"
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表