Как извлечь расшифровку стенограммы с несколькими выступающими из вывода JSON с расшифровкой речи Google Video Intelligence API с помощью jq?
Я тестирую преобразование речи в текст Google Video Intelligence для расшифровки эпизодов подкастов с несколькими динамиками.
Я извлек пример и опубликовал его в gist: output.json.
cat file.json | jq '.response.annotationResults[].speechTranscriptions[].alternatives[] | {startTime: .words[0].startTime, segment: .transcript }'
Команда выше распечатает startTime
каждого сегмента вместе с самим сегментом. jq-output.json
{
"time": "6.400s",
"segment": "Hi, my name is Melinda Smith from Noble works. ...snip"
}
{
"time": "30s",
"segment": " Any Graham as a tool for personal and organizational ...snip"
}
Я стремлюсь к тому, чтобы speakerTag
для каждого сегмента, включенного в мой вывод jq.
Вот где я застрял... для начала, каждый массив внутри .alternatives[]
содержит .transcript
строка, содержащая этот сегмент, .confidence
, а также .words[]
массив с каждым словом этого сегмента и временем его произнесения.
Эта часть JSON - это то, как я получаю первую часть вывода. Затем, после того, как он прошел через каждый сегмент расшифровки стенограммы, внизу будет один последний.alternatives[]
массив, содержащий (снова) каждое слово из всей транскрипции, по одному, вместе с его startTime, endTime и SpeakerTag.
Вот упрощенный пример того, что я имею в виду:
speechTranscriptions:
alternatives:
transcript: "Example transcript segment"
words:
word: "Example"; startTime: 0s;
word: "transcript"; startTime: 1s;
word: "segment"; startTime: 2s;
alternatives:
transcript: "Another transcript segment"
words:
word: "Another"; startTime: 3s;
word: "transcript"; startTime: 4s;
word: "segment"; startTime: 5s;
alternatives:
words:
word: "Example"; startTime: 0s; speakerTag: 1;
word: "transcript"; startTime: 1s; speakerTag: 1;
word: "segment"; startTime: 2s; speakerTag: 1;
word: "Another"; startTime: 3s; speakerTag: 2;
word: "transcript"; startTime: 4s; speakerTag: 2;
word: "segment"; startTime: 5s; speakerTag: 2;
Я думал как-то пройти через jq-output.json и сопоставить каждыйstartTime
с соответствующим speakerTag
найдено в исходном выводе Video Intelligence API.
.response.annotationResults[].speechTranscriptions[].alternatives[] | ( if .words[].speakerTag then {time: .words[].startTime, speaker: .words[].speakerTag} else empty end)
Я попробовал несколько вариантов этого, с идеей распечатать только время начала и динамик Tag, а затем сопоставить значения на моем следующем шаге. Моя проблема заключалась в том, что я не понимал, как распечатать startTime, только если у него есть соответствующий SpeakerTag.
Как упоминалось в комментариях, было бы предпочтительнее генерировать этот результат в одной команде, но я просто пытался разбить проблему на части, которые я мог бы попытаться понять.
1 ответ
Моя проблема заключалась в том, что я не понимал, как распечатать startTime, только если у него есть соответствующий SpeakerTag.
Это можно сделать с помощью фильтра:
.response.annotationResults[].speechTranscriptions[].alternatives[].words[]
| select(.speakerTag)
| {time: .startTime, speaker: .speakerTag}
Так что, возможно, следующее решение (или, по крайней мере, близкое к решению) основной проблемы:
.response.annotationResults[].speechTranscriptions[].alternatives[]
| (INDEX(.words[] | select(.speakerTag); .startTime) | map_values(.speakerTag)) as $dict
| {startTime: .words[0].startTime, segment: .transcript}
| . + {speaker: $dict[.startTime]}