В интересах стандартизации моей видео-библиотеки я пытаюсь найти способ быстро создать список файлов, которые необходимо преобразовать. Посмотрев на этот вопрос и его ответ (и многое другое), я думаю, что у меня есть основы, но у меня возникли проблемы с разработкой раздела jq. Для справки, команда jq, с которой я начинаю, выглядит следующим образом:
jq -c '.format.filename as $path |
.streams[]? |
select(.codec_type=="video" and .codec_name!="h264") |
.codec_name as $vcodec |
{video: $vcodec, path: $path}'
и, для простоты, предположим, что это то, что подается в jq:
{
"streams": [
{
"index": 0,
"codec_name": "hevc",
"codec_type": "video"
},
{
"index": 1,
"codec_name": "aac",
"codec_type": "audio"
}
],
"format": {
"filename": "Video.mkv"
}
}
, который производит следующий вывод:
{"video":"hevc","path":"./Video.mkv"}
Это здорово, но я хочу пойти еще дальше - я также хотел бы включить кодек, используемый для любых аудиопотоков. Поэтому, учитывая тот же ввод, я хотел бы получить следующий результат:
{"video":"hevc","audio":"aac","path":"./Video.mkv"}
Как это сделать?
Чтобы выбрать типы аудио и видео кодеков и исключить видео h264:
$ jq '.format.filename as $path |
[.streams[]? | select(.codec_type=="audio"
or (.codec_type=="video"
and .codec_name!="h264")) |
{(.codec_type): .codec_name, $path}] |
group_by(.path) | map(add) | .[]' input.json
$ jq --version
jq-1.5-1-a5b5cbe
Если команда оболочки становится сложной и занимает больше нескольких строк; Я переключусь на более подробный Python для управления сложностью:
result = dict(path=data['format']['filename'])
for stream in data['streams']:
if (stream['codec_type'] == 'audio'
or (stream['codec_type'] == 'video'
and stream['codec_name'] != 'h264')):
result[stream['codec_type']] = stream['codec_name'] # last value wins
data - это вход (data = json.loads(json_text)), а result - желаемый вывод (print(json.dumps(result))).
Для вашего конкретного случая должно быть относительно просто адаптировать приведенный выше код, если вы более знакомы с императивным программированием на Python, чем с более функциональным стилем в jq.
Чтобы выбрать типы аудио и видео кодеков и исключить видео h264:
$ jq '.format.filename as $path |
[.streams[]? | select(.codec_type=="audio"
or (.codec_type=="video"
and .codec_name!="h264")) |
{(.codec_type): .codec_name, $path}] |
group_by(.path) | map(add) | .[]' input.json
$ jq --version
jq-1.5-1-a5b5cbe
Если команда оболочки становится сложной и занимает больше нескольких строк; Я переключусь на более подробный Python для управления сложностью:
result = dict(path=data['format']['filename'])
for stream in data['streams']:
if (stream['codec_type'] == 'audio'
or (stream['codec_type'] == 'video'
and stream['codec_name'] != 'h264')):
result[stream['codec_type']] = stream['codec_name'] # last value wins
data - это вход (data = json.loads(json_text)), а result - желаемый вывод (print(json.dumps(result))).
Для вашего конкретного случая должно быть относительно просто адаптировать приведенный выше код, если вы более знакомы с императивным программированием на Python, чем с более функциональным стилем в jq.
Чтобы выбрать типы аудио и видео кодеков и исключить видео h264:
$ jq '.format.filename as $path |
[.streams[]? | select(.codec_type=="audio"
or (.codec_type=="video"
and .codec_name!="h264")) |
{(.codec_type): .codec_name, $path}] |
group_by(.path) | map(add) | .[]' input.json
$ jq --version
jq-1.5-1-a5b5cbe
Если команда оболочки становится сложной и занимает больше нескольких строк; Я переключусь на более подробный Python для управления сложностью:
result = dict(path=data['format']['filename'])
for stream in data['streams']:
if (stream['codec_type'] == 'audio'
or (stream['codec_type'] == 'video'
and stream['codec_name'] != 'h264')):
result[stream['codec_type']] = stream['codec_name'] # last value wins
data - это вход (data = json.loads(json_text)), а result - желаемый вывод (print(json.dumps(result))).
Для вашего конкретного случая должно быть относительно просто адаптировать приведенный выше код, если вы более знакомы с императивным программированием на Python, чем с более функциональным стилем в jq.
Вот еще один подход.
$ jq -M '
def getpath: {path: .format.filename} ;
def getcodecs: [
.streams[]?
| {(.codec_type):.codec_name}
| if . == {"video":"h264"} then empty else . end
] | add
;
getpath + getcodecs
' input.json
Выход
{
"path": "Video.mkv",
"video": "hevc",
"audio": "aac"
}
Вот еще один подход.
$ jq -M '
def getpath: {path: .format.filename} ;
def getcodecs: [
.streams[]?
| {(.codec_type):.codec_name}
| if . == {"video":"h264"} then empty else . end
] | add
;
getpath + getcodecs
' input.json
Выход
{
"path": "Video.mkv",
"video": "hevc",
"audio": "aac"
}
Вот еще один подход.
$ jq -M '
def getpath: {path: .format.filename} ;
def getcodecs: [
.streams[]?
| {(.codec_type):.codec_name}
| if . == {"video":"h264"} then empty else . end
] | add
;
getpath + getcodecs
' input.json
Выход
{
"path": "Video.mkv",
"video": "hevc",
"audio": "aac"
}