我有这个代码:
track1=$(mkvmerge -I sample.mkv | sed -ne '/^Track ID [0-9]*: audio ([^)]*).* language:eng.*/ { s/^[^0-9]*\([0-9]*\):.*/\1/;H }; $ { g;s/[^0-9]/,/g;s/^,//;p }' | cut -c1)
它将检索与语言英语匹配的 1 个曲目。
我想制作一个脚本来比较相同语言的音轨,并找到质量最高的。
但是mkvinfo
,mkvmerge
和mediainfo
似乎无法检索有关给定轨道 ID 的信息,而且我不知道如何解析它们的完整输出以仅检索我需要的内容。
这个怎么做?我需要检索猜测质量所需的所有内容,例如格式、比特率、通道数、大小并将其存储在诸如track1channels
.
我对解决这个难题的其他解决方案持开放态度。
答案1
可能有很多不同的方法可以做到这一点,具体取决于您想要使用什么工具来解析输出。一种方法是生成mkvmerge
JSON,然后用jq
.例如,要获取所有音轨:
mkvmerge --identify --identification-format json sample.mkv | jq '.tracks[] | select(.type=="audio")'
您可以在 中指定各种条件jq
,例如.id=="2"
轨道 2 等。也许您甚至可以使用 进行比较/排序jq
,具体取决于您想要执行的操作,请参阅man jq
获取详细信息。
您还可以将一些过滤后的输出存储jq
在 shell 变量中,并使用多次jq
调用将所有字段提取到其他 shell 变量中。 (可能有一种并行的方法,但我不知道)。
编辑
至于比特率:我尝试了一个mkv
包含AAC
音频的样本,但首先既mediainfo
没有给出任何纯粹的音频比特率。mkvinfo
也许人们可以根据其他信息来计算它,例如该轨道使用的总位数和总持续时间,但我对 mkv 容器的内部结构不够熟悉,无法确定哪个数字是哪个数字。
读取.tracks[] | select(.type=="audio")
“流式传输字段中的所有信息track
,然后选择具有type
等于字段的信息audio
”。假设你得到类似的东西
{
"codec": "AAC",
"id": 1,
"properties": {
"audio_channels": 2,
"audio_sampling_frequency": 44100,
"codec_id": "A_AAC",
"codec_private_data": "1210",
"codec_private_length": 2,
"default_duration": 23219954,
"default_track": true,
"enabled_track": true,
"forced_track": true,
"language": "und",
"minimum_timestamp": 0,
"number": 2,
"uid": 2897612726
},
"type": "audio"
}
然后将其保存到文件或变量中。将其通过管道传输到第二个jq
命令中,例如jq '.properties.audio_channels'
获取子字段。我不确定你打算如何循环多个轨道或你想要做什么,但你可以仅通过jq
查询做很多事情。
编辑
要获取单行上的 id、编解码器名称、编解码器 id 和通道数,请执行以下操作
jq '[[.id, .codec, .properties.codec_id, .properties.audio_channels] | map(tostring) | join(",")] | join("\n")'
保存的值(或添加到原始表达式)。
外部[...]
捕获JSON记录流,内部[...]
构造一个列表,将数字转换为字符串后可以join
用逗号编辑,然后外部列表也用join
换行符编辑。我想如果有必要的话,可以用命令行选项去掉引号。
另请考虑sort
是否要先按通道数排序等。
这真的变成了一个“我如何jq
正确使用”的问题,所以也许谷歌一个jq
教程,或者提出一个新问题/新问题?