Транскрибирование каналов подкастов с вашего терминала

Каждый настоящий подкаст имеет бесплатный и общедоступный RSS-канал, который содержит информацию о шоу и каждом эпизоде. В свою очередь, эти эпизоды содержат метаданные о шоу и ссылку на размещенный аудиофайл. В этом руководстве мы будем загружать транскрипты последних эпизодов наших любимых шоу и хранить их в текстовых файлах на нашем компьютере.

Перед началом работы

Вам понадобится API-ключ Deepgram — получить его можно здесь. Также вам нужно будет установить jq и yq для просмотра и манипулирования XML в вашем терминале (формат данных, используемый для RSS-каналов).

Этот учебник будет представлять собой набор строительных блоков, постепенно усложняющихся по мере достижения конечной цели. Мы не будем торопиться и объясним каждый шаг, чтобы вы могли применить эти знания и в других контекстах.

Мы будем использовать канал подкастов NPR Morning Edition Podcast Feed: https://feeds.npr.org/510318/podcast.xml, но его можно заменить на ваш любимый подкаст.

Начало работы

Откройте терминал и выполните следующие действия:

curl https://feeds.npr.org/510318/podcast.xml
Войдите в полноэкранный режим Выйти из полноэкранного режима

Это должно отобразить полный RSS-канал — кучу XML (похожих на HTML), содержащих информацию о канале.

Получение только элементов эпизода

Структура XML включает тег rss, содержащий тег channel. Внутри channel находится целая куча тегов метаданных для шоу и набор тегов item для каждого эпизода. Теги item не находятся внутри содержащего списка, как мы могли бы ожидать в HTML — все они являются прямыми дочерними тегами channel. Попробуйте выполнить следующую команду:

curl https://feeds.npr.org/510318/podcast.xml | xq '.rss.channel.item[]'
Войти в полноэкранный режим Выйти из полноэкранного режима

Это направит вывод curl в команду xq и извлечет все теги item. Он также выводит его в терминал, что я нахожу весьма полезным при изучении данных. То, что находится после команды xq в кавычках, называется «выражением».

Получение конкретных элементов

Мы можем указать позицию индекса в квадратных скобках, чтобы извлечь конкретные элементы. При этом будет возвращен только первый (последний) item:

curl https://feeds.npr.org/510318/podcast.xml | xq '.rss.channel.item[0]'
Войти в полноэкранный режим Выйти из полноэкранного режима

Мы также можем нарезать результаты и перечислить элементы с первыми n элементами. При этом будут возвращены только первые три элемента:

curl https://feeds.npr.org/510318/podcast.xml | xq '.rss.channel.item[:3]'
Войти в полноэкранный режим Выйти из полноэкранного режима

Важное замечание — это возвращает массив (элементы окружены []), в то время как раньше это было просто несколько объектов, выводимых на терминал. Чтобы превратить его обратно в набор объектов, которыми мы можем в дальнейшем манипулировать, добавьте к команде []:

curl https://feeds.npr.org/510318/podcast.xml | xq '.rss.channel.item[:3][]'
Войти в полноэкранный режим Выйти из полноэкранного режима

Отображение специфических свойств

Даже после извлечения списка элементов мы можем извлечь только одно свойство, продолжая использовать синтаксис точки:

curl https://feeds.npr.org/510318/podcast.xml | xq '.rss.channel.item[:3][].title'
Enter fullscreen mode Выйти из полноэкранного режима

Если мы хотим извлечь одно свойство из массива объектов, мы можем использовать map:

curl https://feeds.npr.org/510318/podcast.xml | xq '.rss.channel.item[:3] | map(.title)'
Войти в полноэкранный режим Выйти из полноэкранного режима

В отличие от документов JSON, XML также имеет атрибуты (как HTML). Для доступа к ним мы используем следующий синтаксис:

curl https://feeds.npr.org/510318/podcast.xml | xq '.rss.channel.item[:3] | map(.enclosure."@url")'
Войти в полноэкранный режим Выйти из полноэкранного режима

Хотите создать новую структуру данных? Здесь мы создаем объект, содержащий только title и url:

curl https://feeds.npr.org/510318/podcast.xml | xq '.rss.channel.item[:3] | map({ title: .title, url: .enclosure."@url" })'
Вход в полноэкранный режим Выход из полноэкранного режима

Перемещение по объектам

Объектов в BASH на самом деле не существует, поэтому перебирать их и извлекать значения может быть сложновато. К счастью, Рубен Костер из Start &Wayne представил рабочий подход. Давайте пройдемся по нему.

Во-первых, сохраните результат предыдущего шага в переменной:

DATA=$(curl https://feeds.npr.org/510318/podcast.xml | xq '.rss.channel.item[:3] | map({ title: .title, url: .enclosure."@url" })')
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь к ней можно обратиться в терминале как $DATA:

echo $DATA
# Array of objects with title and url will show here
Войти в полноэкранный режим Выйти из полноэкранного режима

Если вы попытаетесь просмотреть эти данные, то заметите кое-что нежелательное:

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

for row in $(echo "${DATA}" | jq -r '.[] | @base64'); do
    _jq() {
        echo ${row} | base64 --decode | jq -r ${1}
    }
    url=$(_jq '.url')
    title=$(_jq '.title')

    echo $url, $title
done
Войти в полноэкранный режим Выйти из полноэкранного режима

Транскрибирование каждого эпизода

Теперь, когда каждый элемент подкаста доступен в цикле, а свойства url и title можно адресовать по отдельности, мы можем создать транскрипт с помощью cURL. Более подробно об этом мы рассказываем в нашей недавней статье в блоге.

Убедитесь, что вы заменили YOUR_DEEPGRAM_API_KEY на ваш собственный API-ключ Deepgram.

DATA=$(curl https://feeds.npr.org/510318/podcast.xml | xq '.rss.channel.item[:3] | map({ title: .title, url: .enclosure."@url" })')
for row in $(echo "${DATA}" | jq -r '.[] | @base64'); do
    _jq() {
        echo ${row} | base64 --decode | jq -r ${1}
    }
    RESPONSE=$(
        curl -X POST "https://api.deepgram.com/v1/listen?punctuate=true&tier=enhanced" 
            -H "Authorization: Token YOUR_DEEPGRAM_API_KEY" 
            -H "Content-Type: application/json" 
            -d "{"url":"$(_jq '.url')"}"
   )
   echo $RESPONSE | jq '.results.channels[0].alternatives[0].transcript' > "$(_jq '.title').txt"
done
Вход в полноэкранный режим Выйдите из полноэкранного режима

В результате будет создан один текстовый файл для каждого эпизода.

Завершение

jq и xq — исключительно мощные инструменты, еще более мощные в сочетании с запросами cURL. С минимальными настройками вы можете начать изменять получаемые подкасты, количество создаваемых транскриптов или включать дополнительные метаданные об эпизоде в создаваемый файл.

Если у вас есть вопросы, обращайтесь — мы любим помогать!

Оцените статью
devanswers.ru
Добавить комментарий