Со времени моей последней записи в блоге я внес несколько изменений в приложение, над которым я работаю. Приложение будет принимать пользовательский ввод для url вопросов stackoverflow и url видео youtube и создавать рассказывающий тикток, подобный этому проекту. Сначала я хочу рассказать о некоторых изменениях, которые я сделал, затем я расскажу о файле main.js
и о том, что он делает.
Изменения с прошлой недели
Несколько вещей изменились, но ничего серьезного. Я создал папку внутри /lib
для файлов, используемых в edit-video.js
. Я сделал это потому, что количество шагов, необходимых для редактирования видео, оправдывает их разделение. Пока что я смог прикрепить аудиофайлы из Google Cloud text-to-speech API к снимкам экрана из Puppeteer. Я не смог найти столько же времени, чтобы добиться такого же прогресса, как вначале, но с тех пор, как я перешел с etro.js на ffmpeg, все идет гораздо более гладко. Я решил перейти на ffmpeg после того, как прочитал о remotion и попытался реализовать его. Я также нашел shotstack, но не хотел быть потенциально ограниченным в количестве вызовов API, которые я мог бы сделать.
Я также переименовал файл index.js
в main.js
в какой-то момент и до сих пор не изменил его обратно.
Вот изменения, которые я внес в файл /lib
└─── lib
└─── edit-video
add-audio.js
edit-video.js
image-to-video.js
│
│ api-call.js
│ download-video.js
│ parse-text.js
│ screenshot.js
│ text-to-speech.js
Пока я завершаю проект, может произойти еще несколько изменений, и я сделаю подобное обновление в следующем посте.
Файл Main.js
main.js
— это вход в приложение. В main.js
я импортирую модули из /lib
, а также несколько пакетов npm.
import chalk from "chalk";
import inquirer from "inquirer";
import { screenshot } from "./lib/screenshot.js";
import { makeApiCall } from "./lib/api-call.js";
import { downloadVideo } from "./lib/download-video.js";
import { convertTextToSpeech } from "./lib/text-to-speech.js";
import { editVideo } from "./lib/edit-video.js";
В предыдущем сообщении я немного рассказал о том, что делает каждый из используемых мной пакетов npm, но сейчас я лучше объясню, как они используются в моем приложении.
Chalk и Inquirer используются вместе, когда приложение выводит данные в консоль и когда запрашивает пользовательский ввод. Inquirer используется для получения ввода, а Chalk — для стилизации всего, что записывается в консоль.
Вот как они используются в main.js
const greeting = chalk.green("STACKOVERFLOW VIDEO CREATOR");
console.log(greeting);
async function getQuestionURL() {
const answer = await inquirer.prompt({
name: "questionURL",
type: "input",
message: "Enter the stackoverflow questions URL:",
});
questionURL = answer.questionURL;
}
greeting
печатается зеленым текстом, а при вызове getQuestionURL
пользователю предлагается ввести URL на вопрос stackoverflow.
Следующие пять операторов импорта импортируют модули, экспортируемые из /lib
. Я покажу, как вызывается каждая функция в этом посте, и сделаю еще несколько постов о том, что на самом деле делают вызываемые функции.
После того, как приложение получает оба URL от пользователя, оно просит пользователя подтвердить свой ввод перед вызовом функции startVideoEdit
, которая выполняет вызовы функций модулей /lib
.
Сначала makeApiCall
получает текст, который нужно преобразовать в аудио. Ему передается URL-адрес вопроса и несколько глобальных переменных, хранящихся в main.js
, которые используются во всем приложении.
await makeApiCall(questionURL, questionDataObj, plainTextStrings, fileNames);
Затем вызывается функция screenshot
, которая использует Puppeteer для создания необходимых снимков экрана. Эта функция также принимает URL вопроса и глобальные переменные.
await screenshot(questionURL, questionDataObj, fileNames);
Далее вызывается функция convertTextToSpeech
для получения звука для заголовка, тела вопроса и ответов на него. В функцию передаются текстовые строки, а также заголовок для сохранения звука. Я бы хотел со временем попытаться рефакторизовать это в один вызов функции, но пока для выполнения работы требуется несколько. Сначала я получаю звук для заголовка, затем тело вопроса, после чего перебираю массив строк вопроса.
await convertTextToSpeech(questionDataObj.title[0], "question-title");
await convertTextToSpeech(questionDataObj.textString[0], "question-body");
async function getAnswerAudio() {
for (let i = 1; i <= plainTextStrings.strings.length; i++) {
await convertTextToSpeech(
plainTextStrings.strings[i - 1],
fileNames[i + 1]
);
}
}
await getAnswerAudio();
Наконец, перед тем, как вызвать editVideo
, чтобы завершить все, вызывается downloadVideo
, чтобы загрузить видео с youtube для использования в качестве фона видео. Единственным параметром для downloadVideo
является видеоролик youtube, переданный пользователем.
await downloadVideo(videoURL);
Это все для main.js
, если у вас есть какие-либо вопросы, я постараюсь ответить. Спасибо, что прочитали, и не стесняйтесь проверить некоторые из моих других постов на dev.to.