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

Предпосылки

Чтобы следовать этому руководству, убедитесь, что на вашем компьютере для разработки установлено следующее:

  • Node.js (v12 или выше)
  • npm или менеджер пакетов Yarn

Настройка проекта

Для начала давайте настроим новый проект React, используя Create React App. Откройте терминал и выполните следующую команду:

npx create-react-app subtitle-creator-app

После настройки проекта перейдите в каталог проекта:

cd subtitle-creator-app

Далее устанавливаем необходимые зависимости:

npm install react-datetime node-webvtt moment

Создание генератора субтитров

Создатель субтитров позволит пользователям вводить время начала, время окончания и текст для каждого субтитра. Он будет динамически отображать добавленные субтитры и предоставит возможность создать файл субтитров.

Начнем с создания нового файла с именем SubtitleCreator.js в каталоге src. Откройте файл и скопируйте следующий код:

import React, { useState } from "react";
import WebVTT from "node-webvtt";
import DateTime from "react-datetime";
import "react-datetime/css/react-datetime.css";
import "./SubtitleCreator.css";
import moment from "moment";

function SubtitleCreator() {
  const [subtitles, setSubtitles] = useState([]);
  const [startTime, setStartTime] = useState("");
  const [endTime, setEndTime] = useState("");
  const [subtitleText, setSubtitleText] = useState("");

  const handleSubtitleTextChange = (event) => {
    setSubtitleText(event.target.value);
  };

  const convertToSeconds = (timeString) => {
    const timeParts = timeString.split(":");
    const hours = parseInt(timeParts[0], 10);
    const minutes = parseInt(timeParts[1], 10);
    const secs = parseInt(timeParts[2], 10);

    return hours * 3600 + minutes * 60 + secs;
  };

  const convertSecondsToTime = (totalSeconds) => {
    const hours = Math.floor(totalSeconds / 3600);
    const minutes = Math.floor((totalSeconds % 3600) / 60);
    const seconds = totalSeconds % 60;

    const formattedTime = `${String(hours).padStart(2, "0")}:${String(
      minutes
    ).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
    return formattedTime;
  };

  const handleAddSubtitle = () => {
    const newSubtitle = {
      startTime: convertToSeconds(startTime),
      endTime: convertToSeconds(endTime),
      text: subtitleText,
    };
    setSubtitles([...subtitles, newSubtitle]);
    setStartTime(endTime);
    setSubtitleText("");
  };

  const handleGenerateSubtitleFile = () => {
    const parsedSubtitle = {
      cues: [],
      valid: true,
    };

    subtitles.forEach((subtitle, index) => {
      const cue = {
        identifier: (index + 1).toString(),
        start: subtitle.startTime,
        end: subtitle.endTime,
        text: subtitle.text,
        styles: "",
      };
      parsedSubtitle.cues.push(cue);
    });

    const modifiedSubtitleContent = WebVTT.compile(parsedSubtitle);
    const modifiedSubtitleBlob = new Blob([modifiedSubtitleContent], {
      type: "text/vtt",
    });
    const downloadLink = URL.createObjectURL(modifiedSubtitleBlob);
    const a = document.createElement("a");
    a.href = downloadLink;
    a.download = "subtitles.vtt";
    a.click();
  };

  const handleStartTimeChange = (selectedTime) => {
    const formattedTime = moment(selectedTime).format("HH:mm:ss");
    setStartTime(formattedTime);
  };

  const handleEndTimeChange = (selectedTime) => {
    const formattedTime = moment(selectedTime).format("HH:mm:ss");
    setEndTime(formattedTime);
  };

  return (
    <div className="container">
      <h1>Subtitle Creator</h1>
      <div className="subtitle-input">
        <div className="time-input">
          <label>Start Time:</label>
          <DateTime
            value={startTime}
            onChange={handleStartTimeChange}
            dateFormat={false}
            timeFormat="HH:mm:ss"
          />
        </div>
        <div className="time-input">
          <label>End Time:</label>
          <DateTime
            value={endTime}
            onChange={handleEndTimeChange}
            dateFormat={false}
            timeFormat="HH:mm:ss"
          />
        </div>
        <label>Subtitles:</label>
        <textarea
          rows={4}
          cols={30}
          placeholder="Subtitle text"
          value={subtitleText}
          onChange={handleSubtitleTextChange}
        />
        <button onClick={handleAddSubtitle}>Add Subtitle</button>
      </div>
      <div className="subtitle-list">
        <h2>Subtitles:</h2>
        {subtitles.map((subtitle, index) => (
          <div className="subtitle-item" key={index}>
            <p>
              [{convertSecondsToTime(subtitle.startTime)} -{" "}
              {convertSecondsToTime(subtitle.endTime)}]: {subtitle.text}
            </p>
          </div>
        ))}
      </div>
      {subtitles.length > 0 && (
        <div className="generate-button">
          <button onClick={handleGenerateSubtitleFile}>
            Generate Subtitle File
          </button>
        </div>
      )}
    </div>
  );
}

export default SubtitleCreator;

Компонент SubtitleCreator состоит из переменных состояния для субтитров, времени начала, времени окончания и текста субтитров. Он также включает в себя различные обработчики событий и функции для добавления субтитров, преобразования времени и создания файлов субтитров.

Чтобы увидеть средство создания субтитров в действии, откройте файл src/App.js и замените его содержимое следующим кодом:

// App.js

import React from "react";
import SubtitleCreator from "./SubtitleCreator";

function App() {
  return (
    <div className="App">
      <SubtitleCreator />
    </div>
  );
}

export default App;

После внесения этих изменений вы можете запустить приложение с помощью следующей команды:

npm start

Создатель субтитров должен быть доступен по адресу http://localhost:3000. Вы должны увидеть начальный пользовательский интерфейс с разделом ввода заголовка и субтитров.

Добавление стилей

Чтобы улучшить внешний вид нашего Создателя субтитров, мы применим базовые стили с помощью CSS. Создайте новый файл с именем SubtitleCreator.css в каталоге src и добавьте следующие стили:

/* SubtitleCreator.css */

.container {
  max-width: 600px;
  margin: 0 auto;
  padding: 20px;
  font-family: Arial, sans-serif;
}

h1 {
  text-align: center;
  margin-bottom: 20px;
}

.subtitle-input {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
}

.subtitle-input label {
  margin-right: 10px;
  font-weight: bold;
}

.subtitle-input .time-input {
  display: flex;
  align-items: center;
}

.subtitle-input .time-input label {
  margin-right: 5px;
}

.subtitle-input textarea {
  width: 300px;
  height: 100px;
  resize: vertical;
}

.subtitle-input button {
  margin-left: 10px;
  padding: 8px 12px;
  background-color: #007bff;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.subtitle-list {
  margin-top: 20px;
}

.subtitle-item {
  margin-bottom: 10px;
}

.subtitle-item p {
  margin: 0;
  line-height: 1.5;
}

.subtitle-item p:first-child {
  font-weight: bold;
}

.generate-button {
  margin-top: 20px;
  text-align: center;
}

.generate-button button {
  padding: 10px 20px;
  background-color: #007bff;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

Затем импортируйте файл CSS в компонент SubtitleCreator.js, добавив следующую строку вверху:

import './SubtitleCreator.css';

Сохраните изменения, и вы должны увидеть компонент Subtitle Creator с примененным стилем.

Заключение

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

Вы можете найти полный исходный код этого проекта на GitHub.

Я надеюсь, что вы нашли этот учебник полезным и что он предоставляет