
Im Interesse der Standardisierung meiner Videobibliothek versuche ich, einen Weg zu finden, schnell eine Liste der zu konvertierenden Dateien zu erstellen. Nach einem Blick aufDasFrage und ihre Antwort (und viel googeln) Ich denke, ich habe die Grundlagen verstanden, aber ich habe Probleme, den jq-Abschnitt näher auszuführen. Zur Referenz lautet der jq-Befehl, mit dem ich beginne, wie folgt:
jq -c '.format.filename as $path |
.streams[]? |
select(.codec_type=="video" and .codec_name!="h264") |
.codec_name as $vcodec |
{video: $vcodec, path: $path}'
und nehmen wir der Einfachheit halber an, dass jq Folgendes zugeführt wird:
{
"streams": [
{
"index": 0,
"codec_name": "hevc",
"codec_type": "video"
},
{
"index": 1,
"codec_name": "aac",
"codec_type": "audio"
}
],
"format": {
"filename": "Video.mkv"
}
}
Das Ergebnis ist folgende:
{"video":"hevc","path":"./Video.mkv"}
Das ist großartig, aber ich möchte noch einen Schritt weiter gehen - ich möchte auch den Codec einschließen, der für alle Audiostreams verwendet wird. Bei derselben Eingabe hätte ich also gerne die folgende Ausgabe:
{"video":"hevc","audio":"aac","path":"./Video.mkv"}
Wie erreiche ich das?
Antwort1
So wählen Sie sowohl Audio- als auch Video-Codec-Typen aus und schließen h264
Video aus:
$ 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
Wenn ein Shell-Befehl komplex wird und mehr als ein paar Zeilen umfasst, wechsle ich zum ausführlicheren Python, um die Komplexität zu bewältigen:
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
ist die Eingabe ( data = json.loads(json_text)
) und result
ist die gewünschte Ausgabe ( print(json.dumps(result))
).
Es sollte relativ einfach sein, den obigen Code an Ihren speziellen Fall anzupassen, wenn Sie mit der imperativen Programmierung in Python besser vertraut sind als mit einem eher funktionalen Stil in jq
.
Antwort2
Hier ist ein anderer Ansatz.
$ 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
Ausgabe
{
"path": "Video.mkv",
"video": "hevc",
"audio": "aac"
}