Google Speech API возвращает временные сдвиги для неправильных слов - PullRequest
0 голосов
/ 26 мая 2020

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

Вот моя функция:

const speech = require('@google-cloud/speech');
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const path = require('path');
const os = require('os');
const fs = require('fs');
const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
const ffmpeg = require('fluent-ffmpeg');

admin.initializeApp();

export const transcribeAudio = functions.https.onRequest(async (req, res) => {
    const { name, fullPath } = req.query;
    const bucket = admin.storage().bucket('audio-test.appspot.com');
    const tempFilePath = path.join(os.tmpdir(), name);
    const targetTempFilePath = path.join(os.tmpdir(), `${name}-converted.mp3`);
    await bucket.file(fullPath).download({ destination: tempFilePath }).catch(console.warn);
    const command = ffmpeg(tempFilePath)
        .setFfmpegPath(ffmpegPath)
        .format('mp3')
        .output(targetTempFilePath);
    await new Promise((resolve, reject) => command.on('end', resolve).on('error', reject).run()).catch(console.warn);
    const file = fs.readFileSync(targetTempFilePath);
    const audioBytes = file.toString('base64');
    const audio = { content: audioBytes };
    const client = new speech.SpeechClient();
    const config = {
        encoding: 'MP3',
        sampleRateHertz: 16000,
        languageCode: 'en-US',
        enableWordTimeOffsets: true,
        enableAutomaticPunctuation: true,
    };
    const request = {
        audio: audio,
        config: config,
    };
    const [response] = await client.recognize(request).catch(console.warn);
    res.send(response);
    fs.unlinkSync(tempFilePath);
    fs.unlinkSync(targetTempFilePath);
});

И вот json, возвращенный из этого function:

  {
    "results": Array [
      Object {
        "alternatives": Array [
          Object {
            "confidence": 0.9800227284431458,
            "transcript": "How much wood would a woodchuck chuck if a woodchuck could chuck wood?",
            "words": Array [
              Object {
                "endTime": Object {
                  "nanos": 100000000,
                  "seconds": "4",
                },
                "speakerTag": 0,
                "startTime": Object {
                  "nanos": 700000000,
                  "seconds": "3",
                },
                "word": "How",
              },
              Object {
                "endTime": Object {
                  "nanos": 400000000,
                  "seconds": "4",
                },
                "speakerTag": 0,
                "startTime": Object {
                  "nanos": 100000000,
                  "seconds": "4",
                },
                "word": "much",
              },
              Object {
                "endTime": Object {
                  "nanos": 700000000,
                  "seconds": "4",
                },
                "speakerTag": 0,
                "startTime": Object {
                  "nanos": 400000000,
                  "seconds": "4",
                },
                "word": "wood",
              },
              Object {
                "endTime": Object {
                  "nanos": 800000000,
                  "seconds": "4",
                },
                "speakerTag": 0,
                "startTime": Object {
                  "nanos": 700000000,
                  "seconds": "4",
                },
                "word": "would",
              },
              Object {
                "endTime": Object {
                  "nanos": 0,
                  "seconds": "5",
                },
                "speakerTag": 0,
                "startTime": Object {
                  "nanos": 800000000,
                  "seconds": "4",
                },
                "word": "a",
              },
              Object {
                "endTime": Object {
                  "nanos": 100000000,
                  "seconds": "5",
                },
                "speakerTag": 0,
                "startTime": Object {
                  "nanos": 0,
                  "seconds": "5",
                },
                "word": "woodchuck",
              },
              Object {
                "endTime": Object {
                  "nanos": 600000000,
                  "seconds": "5",
                },
                "speakerTag": 0,
                "startTime": Object {
                  "nanos": 100000000,
                  "seconds": "5",
                },
                "word": "chuck",
              },
              Object {
                "endTime": Object {
                  "nanos": 200000000,
                  "seconds": "6",
                },
                "speakerTag": 0,
                "startTime": Object {
                  "nanos": 600000000,
                  "seconds": "5",
                },
                "word": "if",
              },
              Object {
                "endTime": Object {
                  "nanos": 400000000,
                  "seconds": "6",
                },
                "speakerTag": 0,
                "startTime": Object {
                  "nanos": 200000000,
                  "seconds": "6",
                },
                "word": "a",
              },
              Object {
                "endTime": Object {
                  "nanos": 700000000,
                  "seconds": "6",
                },
                "speakerTag": 0,
                "startTime": Object {
                  "nanos": 400000000,
                  "seconds": "6",
                },
                "word": "woodchuck",
              },
              Object {
                "endTime": Object {
                  "nanos": 0,
                  "seconds": "9",
                },
                "speakerTag": 0,
                "startTime": Object {
                  "nanos": 700000000,
                  "seconds": "6",
                },
                "word": "could",
              },
              Object {
                "endTime": Object {
                  "nanos": 200000000,
                  "seconds": "9",
                },
                "speakerTag": 0,
                "startTime": Object {
                  "nanos": 0,
                  "seconds": "9",
                },
                "word": "chuck",
              },
              Object {
                "endTime": Object {
                  "nanos": 600000000,
                  "seconds": "9",
                },
                "speakerTag": 0,
                "startTime": Object {
                  "nanos": 200000000,
                  "seconds": "9",
                },
                "word": "wood?",
              },
            ],
          },
        ],
        "channelTag": 0,
      },
    ],
  }

В приведенном выше примере я намеренно вытащил слово «сурок» во второй раз, когда сказал его. Если вы посмотрите на смещения, кажется, что времена для этого слова были применены к следующему слову «мог», которое я сказал гораздо быстрее в записи. Любое понимание того, почему это происходит, было бы очень полезно. Спасибо!

...