Техническое задание: веб-приложение для распознавания речи в текст через Yandex SpeechKit

📌 Описание задачи

Здравствуйте.

Необходимо разработать простое веб-приложение, в котором пользователь может нажать на кнопку, записать голос с микрофона (в том числе с мобильного телефона), а затем получить распознанный текст. Распознавание должно происходить через облачный сервис Yandex SpeechKit.

🔧 Функциональные требования

  1. Фронтенд (React + Next.js):

    • Одна страница.

    • Кнопка “Начать запись”, “Остановить запись”.

    • После записи — отправка аудио на бэкенд.

    • Отображение результата распознавания на экране.

  2. Бэкенд (Node.js + Express):

    • Принимает аудиофайл от клиента.

    • Отправляет его в Yandex SpeechKit API.

    • Возвращает клиенту распознанный текст.

    • Использует переменные IAM_TOKEN и FOLDER_ID (через .env).

  3. Поддержка с мобильных устройств.

    • Приложение должно работать с браузеров телефонов.

    • Запись должна работать с мобильного микрофона.

⚙️ Технические детали

Формат аудио: WAV или PCM, 16 или 48 kHz, mono

Язык распознавания: ru-RU

Режим: однократная запись (не потоковая)

📂 Структура проекта

/

├── frontend (Next.js)

│   └── pages/index.js

└── backend (Node.js)

    └── index.js

    └── .env

💻 Фронтенд — 

pages/index.js

npm install react-media-recorder axios

import { ReactMediaRecorder } from "react-media-recorder";

import axios from "axios";

export default function Home() {

  const sendAudioToBackend = async (blob) => {

    const formData = new FormData();

    formData.append("audio", blob, "audio.wav");

    const response = await axios.post("http://localhost:5000/recognize", formData, {

      headers: { "Content-Type": "multipart/form-data" },

    });

    alert("Результат: " + response.data.result);

  };

  return (

    <div style={{ textAlign: "center", marginTop: 100 }}>

      <h2>🎤 Распознавание речи</h2>

      <ReactMediaRecorder

        audio

        render={({ startRecording, stopRecording, mediaBlobUrl }) => (

          <>

            <button onClick={startRecording}>🎙 Начать запись</button>

            <button onClick={() => stopRecording()}>🛑 Остановить</button>

            {mediaBlobUrl && (

              <audio

                src={mediaBlobUrl}

                controls

                onEnded={() => {

                  fetch(mediaBlobUrl)

                    .then((res) => res.blob())

                    .then(sendAudioToBackend);

                }}

              />

            )}

          </>

        )}

      />

    </div>

  );

}

💾 Бэкенд — 

index.js

npm init -y

npm install express multer axios cors dotenv

const express = require("express");

const multer = require("multer");

const cors = require("cors");

const axios = require("axios");

require("dotenv").config();

const app = express();

const upload = multer();

app.use(cors());

app.post("/recognize", upload.single("audio"), async (req, res) => {

  try {

    const response = await axios.post(

      "https://stt.api.cloud.yandex.net/speech/v1/stt:recognize",

      req.file.buffer,

      {

        headers: {

          Authorization: `Bearer ${process.env.IAM_TOKEN}`,

          "Content-Type": "application/octet-stream",

        },

        params: {

          folderId: process.env.FOLDER_ID,

          lang: "ru-RU",

          format: "lpcm",

          sampleRateHertz: 48000,

        },

      }

    );

    res.json({ result: response.data.result });

  } catch (error) {

    console.error(error.response?.data || error.message);

    res.status(500).json({ error: "Ошибка распознавания" });

  }

});

app.listen(5000, () => console.log("Бэкенд запущен на http://localhost:5000"));

🔐 

.env

IAM_TOKEN=ваш_IAM_токен

FOLDER_ID=ваш_folder_id

✅ Что от вас требуется:

  • Сделать полностью рабочий фронт и бэк (с учётом CORS и .env)

  • Убедиться, что работает с телефонов

  • Сделать простый чистый UI с кнопками

  • Выдать исходный код + инструкцию запуска (README.md)

📦 Как будет использоваться:

Прототип для внутреннего использования и будущей мобильной версии (на Flutter).

день назад
Максим
 
42 года
18 лет в сервисе
Был
2 часа назад
358 отзывов

Заявки фрилансеров

Владислав
 
26 лет
год в сервисе
Был
7 часов назад
10 часов назад
Денис
 
23 года
2 месяца в сервисе
Был
18 часов назад
18 часов назад
Павел
 
26 лет
6 дней в сервисе
Был
4 часа назад
21 час назад
Євген
 
19 лет
день в сервисе
Был
34 минуты назад
день назад
Назар
 
33 года
3 года в сервисе
онлайн
4 отзыва(-1)
день назад
Лучший веб-программист мая