
내 비디오 라이브러리를 표준화하기 위해 변환해야 하는 파일 목록을 빠르게 만드는 방법을 찾으려고 노력하고 있습니다. 살펴본 후이것질문과 답변(그리고 많은 인터넷 검색) 기본 사항은 파악한 것 같지만 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"}
이 작업을 어떻게 수행합니까?
답변1
오디오 및 비디오 코덱 유형을 모두 선택하고 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))
)입니다.
NET의 보다 기능적인 스타일보다 Python의 명령형 프로그래밍에 더 익숙하다면 특정 사례에 위의 코드를 적용하는 것이 비교적 간단할 것입니다 jq
.
답변2
또 다른 접근 방식이 있습니다.
$ 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"
}