Как я могу структурировать фильтры jq для возврата информации о видео и аудио кодеках из ffprobe?

В целях стандартизации моей видео библиотеки я пытаюсь найти способ быстро создать список файлов, которые необходимо преобразовать. Посмотрев на этот вопрос и его ответ (и много погуглив), я думаю, что у меня есть основы, но у меня возникли проблемы при разработке раздела jq. Для справки: команда jq, с которой я начинаю: производит следующий вывод:

{"video":"hevc","path":"./Video.mkv"}

Это здорово, но я хочу пойти еще дальше - я также хотел бы включить кодек, используемый для любых аудиопотоков. Итак, учитывая тот же вклад, я хотел бы следующий вывод:

{"video":"hevc","audio":"aac","path":"./Video.mkv"}

Как мне это сделать?

4
задан 6 July 2017 в 11:12

2 ответа

Выбрать и аудиокодек и типы видеокодека и исключить 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.

2
ответ дан 1 December 2019 в 10:00

Вот другой подход.

$ 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"
}
1
ответ дан 1 December 2019 в 10:00

Другие вопросы по тегам:

Похожие вопросы: