
Con el fin de estandarizar mi biblioteca de videos, estoy tratando de encontrar una manera de crear rápidamente una lista de archivos que deben convertirse. Después de mirarestepregunta y su respuesta (y mucho buscar en Google) Creo que he descubierto los conceptos básicos, pero tengo problemas para desarrollar la sección jq. Como referencia, el comando jq con el que estoy empezando es el siguiente:
jq -c '.format.filename as $path |
.streams[]? |
select(.codec_type=="video" and .codec_name!="h264") |
.codec_name as $vcodec |
{video: $vcodec, path: $path}'
y, en aras de la simplicidad, digamos que esto es lo que se envía a jq:
{
"streams": [
{
"index": 0,
"codec_name": "hevc",
"codec_type": "video"
},
{
"index": 1,
"codec_name": "aac",
"codec_type": "audio"
}
],
"format": {
"filename": "Video.mkv"
}
}
que produce el siguiente resultado:
{"video":"hevc","path":"./Video.mkv"}
Esto es genial, pero quiero ir un paso más allá: también me gustaría incluir el códec utilizado para cualquier transmisión de audio. Entonces, dada la misma entrada, me gustaría obtener el siguiente resultado:
{"video":"hevc","audio":"aac","path":"./Video.mkv"}
¿Cómo logro esto?
Respuesta1
Para seleccionar tipos de códecs de audio y video y excluir h264
video:
$ 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
Si un comando de shell se vuelve complejo y ocupa más de unas pocas líneas; Cambio a Python más detallado para gestionar la complejidad:
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
es la entrada ( data = json.loads(json_text)
) y result
es la salida deseada ( print(json.dumps(result))
).
Debería ser relativamente sencillo adaptar el código anterior a su caso particular si está más familiarizado con una programación imperativa en Python que con un estilo más funcional en jq
.
Respuesta2
Aquí hay otro enfoque.
$ 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
Producción
{
"path": "Video.mkv",
"video": "hevc",
"audio": "aac"
}