Видео на YouTube могут быть отличным ресурсом для изучения множества тем. Иногда мне хотелось скопировать и вставить код прямо на экран в свой редактор кода. Хотя существуют расширения для браузера, которые позволяют это делать, я хотел создать эту функцию самостоятельно в виде веб-приложения, которое могло бы работать в любом браузере - установка не требуется.
Это руководство предназначено для начинающих разработчиков, желающих познакомиться с Puppeteer.
Цель
Создайте RESTful API, который будет принимать два запроса (идентификатор видео YouTube и временную метку) и возвращать текст.
Примечание
Если вы предпочитаете альтернативу использованию Google Cloud Vision API для чтения текста, есть альтернативы с открытым исходным кодом, такие как Tesseract.js.
Кроме того, это руководство лучше всего подходит для немонетизированных видео. Видео с рекламой в начале ролика или оверлеем, скорее всего, не будут работать без дополнительных настроек.
Ресурсы
Документация по API Puppeteer:
https://github.com/GoogleChrome/puppeteer/blob/v1.10.0/docs/api.md
Документация по Google Cloud Vision API:
https://cloud.google.com/vision/docs/
Другие руководства:
https://blog.georgi-yanev.com/projects/youtube-timestamp-screenshot/
https://codeburst.io/a-guide-to-automating- очистка-веб-с помощью-javascript-chrome-puppeteer-node-js-b18efb9e9921
https://timleland.com/headless-chrome-on-heroku/
Начиная
Примечание: мы будем использовать функцию async / await с Puppeteer, для чего потребуется Node v7.6.0 или выше.
Создайте папку проекта и инициализируйте ее:
$ mkdir youtube-text $ cd youtube-text $ npm init
Нажмите Enter, чтобы использовать имя по умолчанию, лицензию и т. Д., Или введите свое собственное.
Затем инициализируйте репозиторий git:
$ git init
Не забудьте создать файл .gitignore:
node_modules secrets.js
Загрузите и установите Express, Axios и Puppeteer с помощью NPM. Puppeteer загрузит последнюю версию Chromium и потребует много места (~ 170 МБ для Mac, ~ 282 МБ для Linux, ~ 280 МБ для Win).
$ npm install --save express puppeteer axios
Если вы еще этого не сделали, зарегистрируйтесь и получите ключ Google Cloud API. На момент написания этой статьи вы можете подписаться на бесплатную пробную версию, которая предоставит кредит. Чтобы использовать Google Cloud Vision API, вам потребуется аккаунт с включенной оплатой.
В корневом каталоге нашего проекта создадим файл с именем secrets.js: он будет содержать наш ключ API, когда мы запустим наше приложение локально.
В корневом каталоге нашего проекта создадим файл с именем app.js:
Строка 1–2: Импортируйте экспресс и назначьте переменную приложения.
Строка 3: Устанавливает порт прослушивания, используя либо переменную окружения, либо 8080.
Строка 5: Если переменная NODE_ENV не является "производственной", мы импортируем файл секретов, который назначает ключевую переменную Google API. Необходимо для использования Google Cloud Vision API.
Строка 7–9: Наш маршрут / api GET. Просто отправляет пока статус 200.
Строки 11–13: обратный вызов прослушивателя приложений.
Проверка статуса №1
Запуск нашего приложения с node app
и переход к http: // localhost: 8080 / api должен вернуть статус OK.
Использование Puppeteer для создания скриншотов
Теперь напишем функцию скриншота. А пока мы просто сделаем снимок экрана веб-страницы и вернем его клиенту.
Строка 1: Импортируйте модуль.
Строки 3: мы объявляем функцию, которая будет принимать строку URL и возвращать изображение в кодировке base-64. Мы сделаем это async
, чтобы запускать каждую строку последовательно.
Строка 5: запускает новый экземпляр браузера. Мы могли бы передать необязательный объект параметров (см. Документацию), но сейчас в этом нет необходимости.
Строка 6: открывает новую вкладку.
Строка 7: переход к входному URL-адресу.
Строка 8: Измените размер области просмотра нашего браузера.
Строка 9: Создайте снимок экрана с объектом параметров. Мы собираемся сгенерировать строку в кодировке base-64, поэтому будем использовать
{encoding: 'base64'}
Строка 10–11: закрывает браузер и возвращает изображение. Нам не нужно await
browser.close()
, так как мы уже получили image
.
(В документации API Puppeteer описаны все используемые здесь методы и функции; это очень полезно!)
После того, как вы добавите приведенный выше код в app.js, мы изменим наш маршрут GET.
Строка 2: Создает скриншот строки в кодировке base-64 переданного URL (на данный момент мы жестко запрограммировали его как http://youtube.com/).
Строка 3: Поворачивает изображение в кодировке base-64 и превращает его в двоичный буфер. (Если вам кажется, что нет необходимости генерировать изображение в виде строки base64, только чтобы превратить его в двоичный буфер, не волнуйтесь - мы вернемся к этому позже).
Строка 4–8: Записывает заголовки и отправляет файл изображения клиенту.
Проверка статуса # 2
На этом этапе, когда мы перейдем к http: // localhost: 8080 / api, наше приложение Express сгенерирует снимок экрана с главной страницы YouTube, а затем отправит его в браузер в виде изображения.
Создание снимка экрана видео в определенное время
Давайте сейчас сделаем скриншот видео с YouTube. Как мы передадим в приложение видео и время? Будем использовать параметры запроса!
Например, если мы хотим сделать снимок экрана этого видео в указанное время:
https://www.youtube.com/watch?v=o3ka5fYysBM&t=1740
Если мы хотим быть в состоянии RESTful, мы можем перейти к /api?videoId=o3ka5fYysBM&t=1740
.
Давайте изменим нашу generateScreenshot
функцию:
Пройдемся по изменениям:
Строка 9: Мы выбираем DOM-элемент видеоплеера на веб-странице YouTube.
Строка 10–13: мы скрываем элементы управления YouTube от элемента проигрывателя. Если вы хотите увидеть элементы управления / время, прошедшее на скриншоте, вы можете закомментировать этот раздел.
Строка 14: мы имитируем нажатие пользователем клавиши пробела, чтобы Кукловод воспроизвел видео.
Строка 15: Мы делаем снимок экрана, но не всей страницы. Вместо этого мы делаем снимок экрана только элемента video
, который мы выбрали в строке 9.
Итак, теперь наша функция generateScreenshot
делает снимок экрана видео YouTube, но как нам передать правильные параметры? Мы отредактируем маршрут GET.
Наш маршрут GET теперь будет смотреть на параметры с именем videoId
и t,
создавать URL-адрес YouTube на основе параметров, а затем передавать этот новый URL-адрес в нашу generateScreenshot
функцию.
Строки 2–5: Проверяет, заданы ли параметры videoId
и t
. В противном случае он возвращает полезное сообщение об ошибке и завершает обратный вызов.
Строка 6: Использует деструктуризацию для присвоения значений videoId
и t
из req.query
.
Строка 7. Создайте URL-адрес YouTube. (Примечание: это работает, только если параметр t
представляет собой одно число в секундах).
Проверка статуса # 3
Перейдите по адресу http: // localhost: 8080 / api? VideoId = o3ka5fYysBM & t = 1740. Мы должны получить скриншот видео YouTube в нужное время.
Получение текста с помощью Google Cloud Vision API
Теперь нам нужно отправить изображение в Vision API.
Сначала мы определим функцию, которая сделает снимок экрана, который мы создали ранее, сгенерирует объект запроса JSON, а затем отправит его в API с помощью axios.
(Документация: https://cloud.google.com/vision/docs/detecting-text)
Строка 1: мы определяем переменную GOOGLE_API_KEY из переменной окружения, которая должна быть установлена при импорте secrets.js
.
Строка 3: мы определим нашу функцию getText как async
из-за запроса POST, и в качестве входных данных она будет использовать скриншот в кодировке base64.
Строка 4–12: мы определяем тело запроса в формате JSON. Мы передаем наш снимок экрана в строке 6. Поскольку это строка в кодировке base-64, мы можем передать ее туда content
. Если бы у вас был URL-адрес изображения, вы могли бы вместо этого назначить URL-адрес content
. Я определил тип запроса как ‘DOCUMENT_TEXT_DETECTION’
в строке 8 на случай, если изображение было насыщенным текстом.
Строка 13–16: наш axios
запрос к API.
Строка 17: Мы возвращаем результаты запроса API.
Давайте отредактируем наш маршрут GET, чтобы вернуть клиенту только очищенный текст.
Строка 10: Мы вызываем getText
с screenshot
, который мы создали ранее, и присваиваем полученный JSON text
.
Строка 11: она достигает нескольких уровней в возвращенном результате Google Vision JSON и присваивает текст нашей переменной response
.
Строка 12: отправьте строку обратно.
(В качестве альтернативы, если вы хотите увидеть весь полученный JSON из Google Vision / getText, измените строки 11 и 12 на res.json(text)
, который будет отправлять текст вместе с данными о местоположении.)
Проверка статуса # 4
Переход к http: // localhost: 8080 / api? VideoId = o3ka5fYysBM & t = 1740 вернет строку вместо изображения.
Развертывание на Heroku
Если вы хотите развернуть это в Heroku, вам нужно сделать несколько дополнений:
В функции generateScreenshot
:
Передайте объект с указанным выше аргументом args
в launch()
.
В package.json
обязательно укажите node
версию и start
скрипт:
// ... "engines": { "node": "9.8.0" }, "scripts": { "start": "node app" }, // ...
Вам также необходимо включить buildpack для кукловода в дополнение к buildpack узла. Один из способов добавить это может быть через Heroku CLI:
$ heroku buildpacks:add https://github.com/jontewks/puppeteer-heroku-buildpack $ heroku buildpacks:add heroku/nodejs
Вы должны иметь возможность развернуть приложение на Heroku. Однако вы можете получить ошибки H12, потому что Heroku имеет 30-секундный лимит тайм-аута для запросов. Я оставлю эту часть на ваше усмотрение.
Последние мысли
Кукольник - довольно интересный инструмент. Немного изменив код, который я описал выше, вы можете использовать его для создания таких файлов, как GIF. Я хотел бы глубже погрузиться в это и посмотреть, что еще возможно. Если у вас есть какие-либо комментарии, вопросы или исправления, я буду рад их услышать!
Если вы хотите клонировать приведенный выше код, вот URL-адрес GitHub:
https://github.com/djung31/youtube-text