Fah*_*tha 7 dvd ffmpeg burning
将视频文件刻录到 DVD 的标准 Unixy 命令行方法如下(假设)
# 1. First use ffmpeg to convert to an mpg file.
ffmpeg -i input.m4v -target ntsc-dvd output.mpg
# 2. now do the authoring
dvdauthor --title -o dvd -f output.mpg
dvdauthor -o dvd -T
Run Code Online (Sandbox Code Playgroud)
注意:--title
设置 DVD 的标题,-T
设置目录。在以上两个命令中,-o 开关都引用了一个目录,而不是实际的 dvd。
# 3. roll the .mpg file into an ISO file
genisoimage -dvd-video -o dvdimage.iso dvd
Run Code Online (Sandbox Code Playgroud)
最后,将生成的 iso 文件刻录到空白 DVD。我使用 Brasero,这是可靠的。
但是,此方法不适用于非标准纵横比。DVD 格式在指定可接受的纵横比方面非常严格。如果 dvdauthor 说类似的话,你就会知道你是否有这个问题
WARN: unknown mpeg2 aspect ratio 1
Run Code Online (Sandbox Code Playgroud)
修改此方法以处理非标准纵横比的好方法是什么?
更新:感谢 Anthony 非常彻底和明确的答案。我希望这对那些试图为这个令人烦恼的问题寻找答案的人有用。我不知道网络上对此有任何其他明确的解释。
基本方法是为您的视频添加黑色边框,使其适合 DVD 允许的宽高比之一。
TLDR:跳到结论。
不过,首先,我需要定义几个不同的东西:
以上三者之间存在简单的数学关系:SAR × PAR = DAR。例如,720:480 * 8:9 = 4:3。那将是以全分辨率放在 DVD 上的 4:3 显示视频。
模拟电视没有像素。相反,它有一个不断变化的信号。该信号的某个部分应该被投影到显示器的每一行上,然后有一个非活动时间来允许,例如,移动到下一行。但是,不同的电视会显示每条线的数量略有不同,并且在电视的整个使用寿命期间,甚至在电视预热时都会有所不同。
DVD 说不要使用最左边和最右边的 8 个像素。所以在 720 中,应该使用 704。每边的 8 个像素应该用黑色填充。指定的 PAR 是这个 10:11。
当然,习惯了数字设备的人会觉得这很傻(用适合礼貌的公司的话)。许多商业 DVD 发行版实际上使用所有 720 像素,有些期望 10:11 PAR,有些期望 8:9。[或类似的 16:9 DAR]。大多数硬件 DVD 播放器使用 10:11,当然这也取决于电视设置。
如果您从希望显示每个像素的视频开始,您可能希望将其调整为 704x480 (SAR 22:15),并带有 8 像素黑条。如果被切掉的边没问题,那么您可以使用完整的 720x480。无论哪种方式,您都需要根据需要缩放视频以获得 10:11(4:3 的 DAR)或 40:33(16:9 的 DAR)的 PAR,如果小于完整的 720x480 帧,则添加黑色酒吧。
谢天谢地,ffmpeg
可以做到这一点。在非官方的 ffmpeg 支持论坛上,ks_kalvan 提供了一个 ffmpeg 视频过滤器链,用于针对 16:9 DAR:
-filter:v "scale='w=min(720,trunc((480*33/40*dar)/2+0.5)*2):h=min(480,trunc((720*40/33/dar)/2+0.5)*2)',pad='w=720:h=480:x=(ow-iw)/2:y=(oh-ih)/2',setsar='r=40/33'"
Run Code Online (Sandbox Code Playgroud)
注意有三个过滤器有:scale
,pad
,和setsar
。我们将依次从最后开始,因为最后的那些是最简单的。
最后一个过滤器令人困惑,直到您检查文档 (`man ffmpeg-filter) 并找到删除的这条咒骂行:““setsar”过滤器设置过滤器输出视频的样本(又名像素)纵横比。” 所以这实际上是将 PAR 设置为 40:33,这是我们在上面所说的我们想要使用的值。
该pad
过滤器添加黑色边框。文档告诉我们ow是输出宽度(即 720,距w=720
零件),哦,输出高度(即,距h=480
零件480 )。iw和ih分别是输入宽度和高度。ow - iw因此是我们添加到宽度上的像素数(类似地oh - ih表示高度);除以 2 将一半放在图片的每一侧。换句话说,我们将图片居中。
该scale
过滤器调整视频。该w=
选项指定新的/输出宽度,h=
选项指定高度。同样,它是一个表达式,但更复杂。宽度和高度的公式是一样的,只是高度和宽度互换了。让我们检查宽度 ( w=
) 公式:
函数和运算符记录在man ffmpeg-util
. 对于正数,trunc(x+0.5)
是将四舍五入到最近整数的技巧,这是 ffmpeg 没有的。
在这个trunc(x+0.5)
技巧的基础上,我们有trunc(x/2+0.5)*2
. x/2 给了我们一半 x,当然;截断然后将其四舍五入到最接近的整数。加倍然后给我们最接近的偶数。
我将使用 «W»,其中实际命令使用 720。这是以像素为单位的最终输出宽度。同样,«H» 而不是 480(最终输出高度)。而不是 40/33,«PAR»,因为这是目标像素纵横比。而PAR?¹是PAR的倒数,即33/40。
dar
是一个 ffmpeg 变量。它是输入视频的 DAR。
理解这一点的关键是中间的计算,我们有一个计算,即 «H» × dar ÷ «PAR»。请记住,dar 是原始视频的显示 w/h。因此,将目标宽度(以像素为单位)乘以 dar 可以得出如果我们缩放视频以具有目标高度 «H» 和方形像素的宽度。除以 PAR 然后将其转换为我们实际使用的非方形像素的宽度。
-filter:v "scale='w=min(720,trunc((480*33/40*dar)/2+0.5)*2):h=min(480,trunc((720*40/33/dar)/2+0.5)*2)',pad='w=720:h=480:x=(ow-iw)/2:y=(oh-ih)/2',setsar='r=40/33'"
Run Code Online (Sandbox Code Playgroud)
示例:假设您拍摄了一个 1280 x 720 像素的视频,显示宽高比为 16:9。从中间开始:
这是完整的可用宽度(即,不包括 8px 的不可用区域),正如我们对 16:9 显示器上的 16:9 视频所期望的那样。
当我们在高度上做它时,我们得到 490,这要归功于 min() 保持为 480。但实际上,这表明我们可能想在那里使用 704(可用宽度)而不是 720,这正是480. 所以看起来那里有一个小错误,导致一个微小的(可能是难以察觉的)失真。我相信这在下面是固定的。
min(«W», # take the minimum [lesser of] target width and...
trunc( # the truncation of (round to integer towards 0)
(«H»*«PAR?¹»*dar) # calculate the wanted output width, see note above
/ 2 + 0.5) * 2 # and get the nearest even number to that
))
Run Code Online (Sandbox Code Playgroud)
注意:较旧的 ffmpeg 没有-filter:v
. 您可以尝试-vf
(未经测试),或者更好的是从ffmpeg.org下载新的静态构建。