国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Whisper、React 和 Node 構(gòu)建語(yǔ)音轉(zhuǎn)文本 Web 應(yīng)用程序

這篇具有很好參考價(jià)值的文章主要介紹了Whisper、React 和 Node 構(gòu)建語(yǔ)音轉(zhuǎn)文本 Web 應(yīng)用程序。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

在本文中,我們將使用 OpenAI 的 Whisper 以及 React、Node.js 和 FFmpeg 構(gòu)建一個(gè)語(yǔ)音轉(zhuǎn)文本應(yīng)用程序。該應(yīng)用程序?qū)@取用戶輸入,使用 OpenAI 的 Whisper API 將其合成為語(yǔ)音,并輸出結(jié)果文本。Whisper 提供了我用過(guò)的最準(zhǔn)確的語(yǔ)音到文本轉(zhuǎn)錄,即使對(duì)于非英語(yǔ)母語(yǔ)人士也是如此。

介紹

OpenAI解釋說(shuō),Whisper 是一種自動(dòng)語(yǔ)音識(shí)別 (ASR) 系統(tǒng),經(jīng)過(guò) 680,000 小時(shí)從網(wǎng)絡(luò)收集的多語(yǔ)言和多任務(wù)監(jiān)督數(shù)據(jù)的訓(xùn)練。

文本比音頻更容易搜索和存儲(chǔ)。然而,將音頻轉(zhuǎn)錄為文本可能非常費(fèi)力。像 Whisper 這樣的 ASR 可以檢測(cè)語(yǔ)音,并非常快速地將音頻轉(zhuǎn)錄為文本,非常準(zhǔn)確,這使其成為一種特別有用的工具。

先決條件

本文面向熟悉 JavaScript 并且對(duì) React 和 Express 有基本了解的開(kāi)發(fā)人員。

如果您想一起構(gòu)建,則需要 API 密鑰。您可以通過(guò)在 OpenAI 平臺(tái)上注冊(cè)帳戶來(lái)獲取。獲得 API 密鑰后,請(qǐng)確保其安全并且不要公開(kāi)共享。

技術(shù)堆棧

我們將使用 Create React App (CRA) 構(gòu)建此應(yīng)用程序的前端。我們?cè)谇岸艘龅木褪巧蟼魑募?、選擇時(shí)間邊界、發(fā)出網(wǎng)絡(luò)請(qǐng)求和管理一些狀態(tài)。為了簡(jiǎn)單起見(jiàn),我選擇了 CRA。隨意使用您喜歡的任何前端庫(kù),甚至是普通的舊 JS。代碼應(yīng)該大部分是可轉(zhuǎn)移的。

對(duì)于后端,我們將使用 Node.js 和 Express,這樣我們就可以堅(jiān)持使用此應(yīng)用程序的完整 JS 堆棧。您可以使用 Fastify 或任何其他替代方案來(lái)代替 Express,并且您仍然應(yīng)該能夠遵循。

注意:為了使本文重點(diǎn)關(guān)注主題,將鏈接到長(zhǎng)代碼塊,以便我們可以專注于手頭的實(shí)際任務(wù)。

設(shè)置項(xiàng)目

我們首先創(chuàng)建一個(gè)新文件夾,其中包含用于組織目的的項(xiàng)目的前端和后端。請(qǐng)隨意選擇您喜歡的任何其他結(jié)構(gòu):

mkdir speech-to-text-app
cd speech-to-text-app

接下來(lái),我們使用以下命令初始化一個(gè)新的 React 應(yīng)用程序create-react-app

npx create-react-app frontend

導(dǎo)航到新frontend文件夾并安裝以使用以下代碼axios發(fā)出網(wǎng)絡(luò)請(qǐng)求和文件上傳:react-dropzone

cd frontend
npm install axios react-dropzone react-select react-toastify

現(xiàn)在,讓我們切換回主文件夾并創(chuàng)建backend文件夾:

cd ..
mkdir backend
cd backend

接下來(lái),我們?cè)?code>backend目錄中初始化一個(gè)新的 Node 應(yīng)用程序,同時(shí)安裝所需的庫(kù):

npm init -y
npm install express dotenv cors multer form-data axios fluent-ffmpeg ffmetadata ffmpeg-static
npm install --save-dev nodemon

在上面的代碼中,我們安裝了以下庫(kù):

  • dotenv:有必要讓我們的 OpenAI API 密鑰遠(yuǎn)離源代碼。
  • cors:?jiǎn)⒂每缬蛘?qǐng)求。
  • multer:用于上傳音頻文件的中間件。它將一個(gè).fileor.files對(duì)象添加到請(qǐng)求對(duì)象,然后我們將在路由處理程序中訪問(wèn)該對(duì)象。
  • form-data:以編程方式創(chuàng)建帶有文件上傳和字段的表單并將其提交到服務(wù)器。
  • axios:向 Whisper 端點(diǎn)發(fā)出網(wǎng)絡(luò)請(qǐng)求。

另外,由于我們將使用 FFmpeg 進(jìn)行音頻修剪,因此我們有這些庫(kù):

  • fluent-ffmpeg:這提供了一個(gè)流暢的 API 來(lái)與 FFmpeg 工具配合使用,我們將使用它來(lái)進(jìn)行音頻修剪。
  • ffmetadata:這用于讀取和寫(xiě)入媒體文件中的元數(shù)據(jù)。我們需要它來(lái)檢索音頻持續(xù)時(shí)間。
  • ffmpeg-static:這為不同平臺(tái)提供靜態(tài) FFmpeg 二進(jìn)制文件,并簡(jiǎn)化了 FFmpeg 的部署。

Node.js 應(yīng)用程序的入口文件是index.js.?在文件夾內(nèi)創(chuàng)建文件backend并在代碼編輯器中打開(kāi)它。讓我們連接一個(gè)基本的 Express 服務(wù)器:

const express = require('express');
const cors = require('cors');
const app = express();

app.use(cors());
app.use(express.json());

app.get('/', (req, res) => {
  res.send('Welcome to the Speech-to-Text API!');
});

const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

更新package.json文件夾backend以包含啟動(dòng)和開(kāi)發(fā)腳本:

"scripts": {
  "start": "node index.js",
  "dev": "nodemon index.js",
}

上面的代碼只是注冊(cè)了一個(gè)簡(jiǎn)單的GET路由。當(dāng)我們運(yùn)行npm run dev并前往localhost:3001或無(wú)論我們的端口是什么時(shí),我們應(yīng)該看到歡迎文本。

整合耳語(yǔ)

現(xiàn)在是時(shí)候添加秘制醬汁了!在本節(jié)中,我們將:

  • POST接受路由上的文件上傳
  • 將文件轉(zhuǎn)換為可讀流
  • 非常重要的是,將文件發(fā)送到 Whisper 進(jìn)行轉(zhuǎn)錄
  • 以 JSON 形式發(fā)送回響應(yīng)

現(xiàn)在讓我們.env在文件夾的根目錄創(chuàng)建一個(gè)文件backend來(lái)存儲(chǔ)我們的 API 密鑰,并記住將其添加到gitignore

OPENAI_API_KEY=YOUR_API_KEY_HERE

首先,讓我們導(dǎo)入一些更新文件上傳、網(wǎng)絡(luò)請(qǐng)求和流媒體所需的庫(kù):

const  multer  =  require('multer')
const  FormData  =  require('form-data');
const { Readable } =  require('stream');
const  axios  =  require('axios');

const  upload  =  multer();

接下來(lái),我們將創(chuàng)建一個(gè)簡(jiǎn)單的實(shí)用程序函數(shù),將文件緩沖區(qū)轉(zhuǎn)換為可讀流,并將其發(fā)送到 Whisper:

const  bufferToStream  = (buffer) => {
  return  Readable.from(buffer);
}

我們將創(chuàng)建一個(gè)新路由 ,/api/transcribe并使用 axios 向 OpenAI 發(fā)出請(qǐng)求。

首先,axios在文件頂部導(dǎo)入app.jsconst axios = require('axios');.

然后,創(chuàng)建新路線,如下所示:

app.post('/api/transcribe', upload.single('file'), async (req, res) => {
  try {
    const  audioFile  = req.file;
    if (!audioFile) {
      return res.status(400).json({ error: 'No audio file provided' });
    }
    const  formData  =  new  FormData();
    const  audioStream  =  bufferToStream(audioFile.buffer);
    formData.append('file', audioStream, { filename: 'audio.mp3', contentType: audioFile.mimetype });
    formData.append('model', 'whisper-1');
    formData.append('response_format', 'json');
    const  config  = {
      headers: {
        "Content-Type": `multipart/form-data; boundary=${formData._boundary}`,
        "Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,
      },
    };
    // Call the OpenAI Whisper API to transcribe the audio
    const  response  =  await axios.post('https://api.openai.com/v1/audio/transcriptions', formData, config);
    const  transcription  = response.data.text;
    res.json({ transcription });
  } catch (error) {
    res.status(500).json({ error: 'Error transcribing audio' });
  }
});

在上面的代碼中,我們使用實(shí)用程序函數(shù)bufferToStream將音頻文件緩沖區(qū)轉(zhuǎn)換為可讀流,然后通過(guò)網(wǎng)絡(luò)請(qǐng)求將其發(fā)送到 Whisper 和await響應(yīng),然后將響應(yīng)作為響應(yīng)發(fā)回JSON。

您可以查看文檔以了解有關(guān) Whisper 請(qǐng)求和響應(yīng)的更多信息。

安裝 FFmpeg

我們將在下面添加附加功能,以允許用戶轉(zhuǎn)錄部分音頻。為此,我們的 API 端點(diǎn)將接受startTimeendTime,之后我們將使用 修剪音頻ffmpeg。

安裝適用于 Windows 的 FFmpeg

要安裝 Windows 版 FFmpeg,請(qǐng)按照以下簡(jiǎn)單步驟操作:

  1. 在這里訪問(wèn) FFmpeg 官方網(wǎng)站的下載頁(yè)面。
  2. Windows 圖標(biāo)下有幾個(gè)鏈接。選擇 gyan.dev 提供的“Windows Builds”鏈接。
  3. 下載與我們的系統(tǒng)(32 或 64 位)相對(duì)應(yīng)的版本。確保下載“靜態(tài)”版本以獲取包含的所有庫(kù)。
  4. 解壓縮下載的 ZIP 文件。我們可以將提取的文件夾放置在我們喜歡的任何位置。
  5. 要從命令行使用 FFmpeg 而無(wú)需導(dǎo)航到其文件夾,請(qǐng)將 FFmpegbin文件夾添加到系統(tǒng) PATH。

為 macOS 安裝 FFmpeg

如果我們?cè)?macOS 上,我們可以使用 Homebrew 安裝 FFmpeg:

brew install ffmpeg

為 Linux 安裝 FFmpeg

如果我們?cè)?Linux 上,我們可以使用apt、dnf或來(lái)安裝 FFmpeg?pacman,具體取決于我們的 Linux 發(fā)行版。這是安裝命令apt

sudo apt update
sudo apt install ffmpeg

修剪代碼中的音頻

為什么我們需要修剪音頻?假設(shè)用戶有一個(gè)長(zhǎng)達(dá)一小時(shí)的音頻文件,并且只想從 15 分鐘標(biāo)記轉(zhuǎn)錄到 45 分鐘標(biāo)記。使用 FFmpeg,我們可以修剪到精確的startTimeendTime,然后將修剪后的流發(fā)送到 Whisper 進(jìn)行轉(zhuǎn)錄。

首先,我們將導(dǎo)入以下庫(kù):

const ffmpeg = require('fluent-ffmpeg');
const ffmpegPath = require('ffmpeg-static');
const ffmetadata = require('ffmetadata');
const fs  =  require('fs');

ffmpeg.setFfmpegPath(ffmpegPath);
  • fluent-ffmpeg是一個(gè) Node.js 模塊,提供與 FFmpeg 交互的流暢 API。
  • ffmetadata將用于讀取音頻文件的元數(shù)據(jù) - 具體來(lái)說(shuō),duration.
  • ffmpeg.setFfmpegPath(ffmpegPath)用于顯式設(shè)置 FFmpeg 二進(jìn)制文件的路徑。

接下來(lái),讓我們創(chuàng)建一個(gè)實(shí)用函數(shù),將傳遞的時(shí)間轉(zhuǎn)換為mm:ss秒。這可以在我們的app.post路線之外,就像bufferToStream函數(shù)一樣:

/**
 * Convert time string of the format 'mm:ss' into seconds.
 * @param {string} timeString - Time string in the format 'mm:ss'.
 * @return {number} - The time in seconds.
 */
const parseTimeStringToSeconds = timeString => {
    const [minutes, seconds] = timeString.split(':').map(tm => parseInt(tm));
    return minutes * 60 + seconds;
}

接下來(lái),我們應(yīng)該更新我們的app.post路線以執(zhí)行以下操作:

  • 接受startTimeendTime
  • 計(jì)算持續(xù)時(shí)間
  • 處理基本的錯(cuò)誤處理
  • 將音頻緩沖區(qū)轉(zhuǎn)換為流
  • 使用 FFmpeg 修剪音頻
  • 將修剪后的音頻發(fā)送至 OpenAI 進(jìn)行轉(zhuǎn)錄

trimAudio函數(shù)在指定的開(kāi)始時(shí)間和結(jié)束時(shí)間之間修剪音頻流,并返回一個(gè)使用修剪后的音頻數(shù)據(jù)進(jìn)行解析的承諾。如果在此過(guò)程中的任何一點(diǎn)發(fā)生錯(cuò)誤,則 Promise 將因該錯(cuò)誤而被拒絕。

讓我們逐步分解該功能。

  1. 定義修剪音頻功能。該trimAudio函數(shù)是異步的,接受audioStreamendTime作為參數(shù)。我們定義用于處理音頻的臨時(shí)文件名:

    const trimAudio = async (audioStream, endTime) => {
        const tempFileName = `temp-${Date.now()}.mp3`;
        const outputFileName = `output-${Date.now()}.mp3`;
    
  2. 將流寫(xiě)入臨時(shí)文件。我們使用 將傳入的音頻流寫(xiě)入臨時(shí)文件fs.createWriteStream()。如果出現(xiàn)錯(cuò)誤,則會(huì)Promise被拒絕:

    return new Promise((resolve, reject) => {
        audioStream.pipe(fs.createWriteStream(tempFileName))
    
  3. 讀取元數(shù)據(jù)并設(shè)置 endTime。音頻流完成寫(xiě)入臨時(shí)文件后,我們使用 讀取文件的元數(shù)據(jù)ffmetadata.read()。如果提供的時(shí)間endTime長(zhǎng)于音頻持續(xù)時(shí)間,我們將調(diào)整endTime為音頻的持續(xù)時(shí)間:

    .on('finish', () => {
        ffmetadata.read(tempFileName, (err, metadata) => {
            if (err) reject(err);
            const duration = parseFloat(metadata.duration);
            if (endTime > duration) endTime = duration;
    
  4. 使用 FFmpeg 修剪音頻。我們利用 FFmpeg 根據(jù)startSeconds接收到的開(kāi)始時(shí)間 () 和timeDuration之前計(jì)算的持續(xù)時(shí)間 () 來(lái)修剪音頻。修剪后的音頻將寫(xiě)入輸出文件:

    ffmpeg(tempFileName)
        .setStartTime(startSeconds)
        .setDuration(timeDuration)
        .output(outputFileName)
    
  5. 刪除臨時(shí)文件并解決承諾。修剪音頻后,我們刪除臨時(shí)文件并將修剪后的音頻讀入緩沖區(qū)。將輸出文件讀取到緩沖區(qū)后,我們還使用 Node.js 文件系統(tǒng)將其刪除。如果一切順利,問(wèn)題Promise就會(huì)得到解決trimmedAudioBuffer。如果出現(xiàn)錯(cuò)誤,則會(huì)Promise被拒絕:

    .on('end', () => {
        fs.unlink(tempFileName, (err) => {
            if (err) console.error('Error deleting temp file:', err);
        });const trimmedAudioBuffer = fs.readFileSync(outputFileName);
    fs.unlink(outputFileName, (err) => {
        if (err) console.error('Error deleting output file:', err);
    });
    
    resolve(trimmedAudioBuffer);
    
    })
    .on('error', reject)
    .run();
    

端點(diǎn)的完整代碼可在此GitHub 存儲(chǔ)庫(kù)中找到。

前端

樣式將使用 Tailwind 完成,但我不會(huì)介紹如何設(shè)置 Tailwind。您可以在此處閱讀有關(guān)如何設(shè)置和使用 Tailwind 的信息。

創(chuàng)建 TimePicker 組件

由于我們的 API 接受startTimeendTime,所以讓我們使用TimePicker來(lái)創(chuàng)建一個(gè)組件react-select
使用react-select只是將其他功能添加到選擇菜單中,例如搜索選項(xiàng),但這對(duì)本文并不重要,可以跳過(guò)。

讓我們分解一下TimePicker下面的 React 組件:

  1. 進(jìn)口和組件申報(bào)。首先,我們導(dǎo)入必要的包并聲明我們的TimePicker組件。該TimePicker組件接受 props?idlabel、valueonChangemaxDuration

    import React, { useState, useEffect, useCallback } from 'react';
    import Select from 'react-select';
    
    const TimePicker = ({ id, label, value, onChange, maxDuration }) => {
    
  2. 解析valueprop。該valueprop 預(yù)計(jì)是一個(gè)時(shí)間字符串(格式HH:MM:SS)。這里我們將時(shí)間分為小時(shí)、分鐘和秒:

    const [hours, minutes, seconds] = value.split(':').map((v) => parseInt(v, 10));
    
  3. 計(jì)算最大值。maxDuration是根據(jù)音頻持續(xù)時(shí)間可以選擇的最大時(shí)間(以秒為單位)。它被轉(zhuǎn)換為小時(shí)、分鐘和秒:

    const validMaxDuration = maxDuration === Infinity ? 0 : maxDuration
    const maxHours = Math.floor(validMaxDuration / 3600);
    const maxMinutes = Math.floor((validMaxDuration % 3600) / 60);
    const maxSeconds = Math.floor(validMaxDuration % 60);
    
  4. 時(shí)間選項(xiàng)選擇。我們?yōu)榭赡艿男r(shí)、分鐘和秒選項(xiàng)創(chuàng)建數(shù)組,并創(chuàng)建狀態(tài)掛鉤來(lái)管理分鐘和秒選項(xiàng):

    const hoursOptions = Array.from({ length: Math.max(0, maxHours) + 1 }, (_, i) => i);
    const minutesSecondsOptions = Array.from({ length: 60 }, (_, i) => i);
    
    const [minuteOptions, setMinuteOptions] = useState(minutesSecondsOptions);
    const [secondOptions, setSecondOptions] = useState(minutesSecondsOptions);
    
  5. 更新值函數(shù)onChange該函數(shù)通過(guò)調(diào)用作為 prop 傳入的函數(shù)來(lái)更新當(dāng)前值:

    const updateValue = (newHours, newMinutes, newSeconds) => {
        onChange(`${String(newHours).padStart(2, '0')}:${String(newMinutes).padStart(2, '0')}:${String(newSeconds).padStart(2, '0')}`);
    };
    
  6. 更新分秒選項(xiàng)功能。此功能根據(jù)所選的小時(shí)和分鐘更新分鐘和秒選項(xiàng):

    const updateMinuteAndSecondOptions = useCallback((newHours, newMinutes) => {
        const minutesSecondsOptions = Array.from({ length: 60 }, (_, i) => i);
            let newMinuteOptions = minutesSecondsOptions;
            let newSecondOptions = minutesSecondsOptions;
            if (newHours === maxHours) {
                newMinuteOptions = Array.from({ length: Math.max(0, maxMinutes) + 1 }, (_, i) => i);
                if (newMinutes === maxMinutes) {
                    newSecondOptions = Array.from({ length: Math.max(0, maxSeconds) + 1 }, (_, i) => i);
                }
            }
            setMinuteOptions(newMinuteOptions);
            setSecondOptions(newSecondOptions);
    }, [maxHours, maxMinutes, maxSeconds]);
    
  7. 效果掛鉤。這會(huì)調(diào)用updateMinuteAndSecondOptions何時(shí)hoursminutes更改:

    useEffect(() => {
        updateMinuteAndSecondOptions(hours, minutes);
    }, [hours, minutes, updateMinuteAndSecondOptions]);
    
  8. 輔助功能。這兩個(gè)輔助函數(shù)將時(shí)間整數(shù)轉(zhuǎn)換為選擇選項(xiàng),反之亦然:

    const toOption = (value) => ({
        value: value,
        label: String(value).padStart(2, '0'),
    });
    const fromOption = (option) => option.value;
    
  9. 渲染。該render函數(shù)顯示時(shí)間選擇器,它由庫(kù)管理的三個(gè)下拉菜單(小時(shí)、分鐘、秒)組成react-select。更改選擇框中的值將調(diào)用updateValueupdateMinuteAndSecondOptions,這已在上面進(jìn)行了解釋。

您可以在GitHub上找到 TimePicker 組件的完整源代碼。

主要成分

現(xiàn)在讓我們通過(guò)替換 來(lái)構(gòu)建主要的前端組件App.js。

應(yīng)用程序組件將實(shí)現(xiàn)具有以下功能的轉(zhuǎn)錄頁(yè)面:

  • 定義時(shí)間格式轉(zhuǎn)換的輔助函數(shù)。
  • 更新startTimeendTime基于TimePicker組件的選擇。
  • 定義一個(gè)getAudioDuration函數(shù)來(lái)檢索音頻文件的持續(xù)時(shí)間并更新audioDuration狀態(tài)。
  • 處理要轉(zhuǎn)錄的音頻文件的文件上傳。
  • 定義一個(gè)transcribeAudio函數(shù),通過(guò)向我們的 API 發(fā)出 HTTP POST 請(qǐng)求來(lái)發(fā)送音頻文件。
  • 渲染文件上傳的 UI。
  • TimePicker用于選擇startTime和 的渲染組件endTime
  • 顯示通知消息。
  • 顯示轉(zhuǎn)錄的文本。

讓我們將該組件分解為幾個(gè)較小的部分:

  1. 導(dǎo)入和輔助函數(shù)。導(dǎo)入必要的模塊并定義時(shí)間轉(zhuǎn)換的輔助函數(shù):

    import React, { useState, useCallback } from 'react';
    import { useDropzone } from 'react-dropzone'; // for file upload
    import axios from 'axios'; // to make network request
    import TimePicker from './TimePicker'; // our custom TimePicker
    import { toast, ToastContainer } from 'react-toastify'; // for toast notification
    
    // Helper functions (timeToSeconds, secondsToTime, timeToMinutesAndSeconds)
    
  2. 組件聲明和狀態(tài)掛鉤。聲明TranscriptionPage組件并初始化狀態(tài)掛鉤:

    const TranscriptionPage = () => {
      const [uploading, setUploading] = useState(false);
      const [transcription, setTranscription] = useState('');
      const [audioFile, setAudioFile] = useState(null);
      const [startTime, setStartTime] = useState('00:00:00');
      const [endTime, setEndTime] = useState('00:10:00'); // 10 minutes default endtime
      const [audioDuration, setAudioDuration] = useState(null);
      // ...
    
  3. 事件處理程序。定義各種事件處理程序 - 用于處理開(kāi)始時(shí)間更改、獲取音頻持續(xù)時(shí)間、處理文件刪除和轉(zhuǎn)錄音頻:

    const handleStartTimeChange = (newStartTime) => {
      //...
    };
    
    const getAudioDuration = (file) => {
      //...
    };
    
    const onDrop = useCallback((acceptedFiles) => {
      //...
    }, []);
    
    const transcribeAudio = async () => { // we'll explain this in detail shortly
      //...
    };
    
  4. 使用 Dropzone 掛鉤。使用庫(kù)useDropzone中的鉤子react-dropzone來(lái)處理文件丟失:

    const { getRootProps, getInputProps, isDragActive, isDragReject } = useDropzone({
      onDrop,
      accept: 'audio/*',
    });
    
  5. 渲染。最后,渲染組件。這包括用于文件上傳的拖放區(qū)、TimePicker用于設(shè)置開(kāi)始和結(jié)束時(shí)間的組件、用于啟動(dòng)轉(zhuǎn)錄過(guò)程的按鈕以及用于顯示轉(zhuǎn)錄結(jié)果的顯示。

transcribeAudio函數(shù)是一個(gè)異步函數(shù),負(fù)責(zé)將音頻文件發(fā)送到服務(wù)器進(jìn)行轉(zhuǎn)錄。讓我們來(lái)分解一下:

const transcribeAudio = async () => {
    setUploading(true);

    try {
      const formData = new FormData();
      audioFile && formData.append('file', audioFile);
      formData.append('startTime', timeToMinutesAndSeconds(startTime));
      formData.append('endTime', timeToMinutesAndSeconds(endTime));

      const response = await axios.post(`http://localhost:3001/api/transcribe`, formData, {
        headers: { 'Content-Type': 'multipart/form-data' },
      });

      setTranscription(response.data.transcription);
      toast.success('Transcription successful.')
    } catch (error) {
      toast.error('An error occurred during transcription.');
    } finally {
      setUploading(false);
    }
  };

下面是更詳細(xì)的介紹:

  1. setUploading(true);。此行將uploading狀態(tài)設(shè)置為true,我們用它來(lái)向用戶指示轉(zhuǎn)錄過(guò)程已經(jīng)開(kāi)始。
  2. const formData = new FormData();。FormData是一個(gè) Web API,用于將表單數(shù)據(jù)發(fā)送到服務(wù)器。它允許我們發(fā)送鍵值對(duì),其中值可以是 Blob、文件或字符串。
  3. 如果 不為 null ( ),則audioFile會(huì)附加到對(duì)象。開(kāi)始時(shí)間和結(jié)束時(shí)間也會(huì)附加到對(duì)象中,但首先會(huì)轉(zhuǎn)換為格式。formData``audioFile && formData.append('file', audioFile);``formData``MM:SS
  4. axios.post方法用于將 發(fā)送formData到服務(wù)器端點(diǎn) (?http://localhost:3001/api/transcribe)。更改http://localhost:3001為服務(wù)器地址。這是通過(guò)await關(guān)鍵字完成的,這意味著該函數(shù)將暫停并等待 Promise 被解析或被拒絕。
  5. 如果請(qǐng)求成功,響應(yīng)對(duì)象將包含轉(zhuǎn)錄結(jié)果 (?response.data.transcription)。transcription然后使用該函數(shù)將其設(shè)置為狀態(tài)setTranscription。然后會(huì)顯示成功的 Toast 通知。
  6. 如果在此過(guò)程中發(fā)生錯(cuò)誤,則會(huì)顯示錯(cuò)誤 Toast 通知。
  7. 在該finally塊中,無(wú)論結(jié)果如何(成功或錯(cuò)誤),uploading狀態(tài)都會(huì)被設(shè)置回false以允許用戶重試。

本質(zhì)上,該transcribeAudio函數(shù)負(fù)責(zé)協(xié)調(diào)整個(gè)轉(zhuǎn)錄過(guò)程,包括處理表單數(shù)據(jù)、發(fā)出服務(wù)器請(qǐng)求和處理服務(wù)器響應(yīng)。

您可以在GitHub上找到 App 組件的完整源代碼。

結(jié)論

我們已經(jīng)到了最后,現(xiàn)在有了一個(gè)完整的 Web 應(yīng)用程序,可以利用 Whisper 的強(qiáng)大功能將語(yǔ)音轉(zhuǎn)錄為文本。

我們絕對(duì)可以添加更多功能,但我會(huì)讓您自己構(gòu)建其余的功能。希望我們已經(jīng)為您提供了一個(gè)良好的開(kāi)端。

這是完整的源代碼:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-545366.html

  • GitHub 上的后端存儲(chǔ)庫(kù)
  • GitHub 上的前端存儲(chǔ)庫(kù)

到了這里,關(guān)于Whisper、React 和 Node 構(gòu)建語(yǔ)音轉(zhuǎn)文本 Web 應(yīng)用程序的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Node.js 中的事件驅(qū)動(dòng)編程:構(gòu)建強(qiáng)大應(yīng)用程序的利器

    引言: 在當(dāng)今高度并發(fā)的網(wǎng)絡(luò)環(huán)境下,構(gòu)建高效、響應(yīng)迅速的應(yīng)用程序是開(kāi)發(fā)人員的一項(xiàng)重要任務(wù)。Node.js,作為一種基于事件驅(qū)動(dòng)編程模型的 JavaScript 運(yùn)行環(huán)境,為開(kāi)發(fā)人員提供了一個(gè)強(qiáng)大的工具。本文將介紹 Node.js 中的事件模型以及如何使用事件驅(qū)動(dòng)編程模式構(gòu)建強(qiáng)大的

    2024年02月10日
    瀏覽(28)
  • 創(chuàng)建web應(yīng)用程序,React和Vue怎么選?

    創(chuàng)建web應(yīng)用程序,React和Vue怎么選?

    React和Vue都是創(chuàng)建web應(yīng)用程序的絕佳選擇。React得到了科技巨頭和龐大的開(kāi)源社區(qū)的支持,代碼庫(kù)可以很大程度地?cái)U(kuò)展,允許你創(chuàng)建企業(yè)級(jí)web應(yīng)用程序。React擁有大量合格甚至優(yōu)秀的開(kāi)發(fā)人員粉絲,可以解決你在開(kāi)發(fā)階段可能遇到的任何問(wèn)題。 毫無(wú)疑問(wèn),React是創(chuàng)建跨平臺(tái)解決

    2024年02月11日
    瀏覽(25)
  • 【Serverless Web 應(yīng)用程序】構(gòu)建流程

    【Serverless Web 應(yīng)用程序】構(gòu)建流程

    【1】選擇構(gòu)建 Serverless Web 應(yīng)用程序,程序架構(gòu)如下所示: 【2】開(kāi)發(fā)流程 【2.1】靜態(tài) Web 托管與持續(xù)部署: 所有的靜態(tài)網(wǎng)頁(yè)內(nèi)容(HTML、CSS、JavaScript、圖 像)和其他文件將由 AWS Amplify 控制臺(tái)管理。用戶將使用 AWS Amplify 控制 臺(tái)公開(kāi)的公共網(wǎng)站 URL 訪問(wèn) Web。不需要額外運(yùn)行

    2024年02月03日
    瀏覽(35)
  • 基于aws構(gòu)建一個(gè)web應(yīng)用程序

    基于aws構(gòu)建一個(gè)web應(yīng)用程序

    經(jīng)驗(yàn)帖以及個(gè)人總結(jié)。 一. 在創(chuàng)建EC2主機(jī)前,可先行創(chuàng)建密匙以及安全組。 關(guān)于安全組: 1. 入站規(guī)則(別人訪問(wèn)你做的一些限制) :開(kāi)放ssh 端口。是為了可以進(jìn)行l(wèi)inux相關(guān)的連接。 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?開(kāi)放http端口。

    2024年02月08日
    瀏覽(29)
  • Whisper實(shí)現(xiàn)語(yǔ)音識(shí)別轉(zhuǎn)文本

    Whisper實(shí)現(xiàn)語(yǔ)音識(shí)別轉(zhuǎn)文本

    #教程 主要參考開(kāi)源免費(fèi)離線語(yǔ)音識(shí)別神器whisper如何安裝, OpenAI開(kāi)源模型Whisper——音頻轉(zhuǎn)文字 Whisper是一個(gè)開(kāi)源的 自動(dòng)語(yǔ)音識(shí)別 系統(tǒng),它在網(wǎng)絡(luò)上收集了680,000小時(shí)的多語(yǔ)種和多任務(wù)監(jiān)督數(shù)據(jù)進(jìn)行訓(xùn)練,使得它可以將多種語(yǔ)言的音頻轉(zhuǎn)文字。 Whisper的好處是 開(kāi)源免費(fèi)、支持多

    2024年03月19日
    瀏覽(19)
  • 快速入門(mén):使用 Spring Boot 構(gòu)建 Web 應(yīng)用程序

    快速入門(mén):使用 Spring Boot 構(gòu)建 Web 應(yīng)用程序

    本文將討論以下主題: 安裝 Java JDK、Gradle 或 Maven 和 Eclipse 或 IntelliJ IDEA 創(chuàng)建一個(gè)新的 Spring Boot 項(xiàng)目 運(yùn)行 Spring Boot 應(yīng)用程序 編寫(xiě)一個(gè)簡(jiǎn)單的 Web 應(yīng)用程序 打包應(yīng)用程序以用于生產(chǎn)環(huán)境 通過(guò)這些主題,您將能夠開(kāi)始使用 Spring Boot 并創(chuàng)建自己的 Web 應(yīng)用程序。 Spring Boot是一個(gè)

    2024年02月07日
    瀏覽(73)
  • 解釋 RESTful API,以及如何使用它構(gòu)建 web 應(yīng)用程序

    ???????? RESTful API stands for Representational State Transfer Application Programming Interface. It is a set of principles and guidelines for building web services that provide data in a standard format, typically JSON or XML. RESTful API emphasizes on uniformity, scalability, reliability, performance, and flexibility. It operates on HTTP and follo

    2024年02月14日
    瀏覽(38)
  • 解釋 RESTful API,以及如何使用它構(gòu)建 web 應(yīng)用程序。

    RESTful API是一種利用HTTP協(xié)議進(jìn)行通信的Web API設(shè)計(jì)風(fēng)格,它采用了一組統(tǒng)一且可緩存的操作,包括GET、POST、PUT、DELETE等,通過(guò)URL來(lái)定位資源,以及使用JSON、XML等格式來(lái)傳輸數(shù)據(jù),以實(shí)現(xiàn)系統(tǒng)之間的數(shù)據(jù)交互和資源共享。 使用RESTful API構(gòu)建Web應(yīng)用程序,首先需要設(shè)計(jì)API的URL、

    2024年02月11日
    瀏覽(41)
  • 使用PostgreSQL構(gòu)建強(qiáng)大的Web應(yīng)用程序:最佳實(shí)踐和建議

    使用PostgreSQL構(gòu)建強(qiáng)大的Web應(yīng)用程序:最佳實(shí)踐和建議

    PostgreSQL是一個(gè)功能強(qiáng)大的開(kāi)源關(guān)系型數(shù)據(jù)庫(kù),它擁有廣泛的用戶群和活躍的開(kāi)發(fā)社區(qū)。越來(lái)越多的Web應(yīng)用選擇PostgreSQL作為數(shù)據(jù)庫(kù) backend。如何充分利用PostgreSQL的特性來(lái)構(gòu)建健壯、高性能的Web應(yīng)用?本文將給出一些最佳實(shí)踐和建議。 一、選擇合適的PostgreSQL數(shù)據(jù)類型 PostgreSQL提供

    2024年02月12日
    瀏覽(34)
  • C#使用whisper.net實(shí)現(xiàn)語(yǔ)音識(shí)別(語(yǔ)音轉(zhuǎn)文本)

    C#使用whisper.net實(shí)現(xiàn)語(yǔ)音識(shí)別(語(yǔ)音轉(zhuǎn)文本)

    目錄 介紹 效果 輸出信息? 項(xiàng)目 代碼 下載? github地址:https://github.com/sandrohanea/whisper.net Whisper.net. Speech to text made simple using Whisper Models 模型下載地址:https://huggingface.co/sandrohanea/whisper.net/tree/main/classic whisper_init_from_file_no_state: loading model from \\\'ggml-small.bin\\\' whisper_model_load: loading

    2024年02月05日
    瀏覽(23)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包