Работа с пакетным транскрибированием

Пакетное транскрибирование — это набор операций REST API, позволяющих вам транскрибировать большой объем аудио в хранилище. Вы можете указать эти звуковые файлы с помощью стандартного URI или URI подписанного URL-адреса (SAS) и асинхронно получать результаты транскрибирования. С помощью API версии 3.0 можно транскрибировать один аудиофайл или несколько или обработать весь контейнер хранилища.

REST API пакетного транскрибирования можно использовать для вызова следующих методов.

Операция пакетной записи Метод Вызов REST API
Создает новую расшифровку. POST speechtotext/v3.0/transcriptions
Получает список расшифровок для подписки, прошедшей проверку подлинности. GET speechtotext/v3.0/transcriptions
Возвращает список поддерживаемых языковых стандартов для автономных расшифровок. GET speechtotext/v3.0/transcriptions/locales
Обновляет изменяемые сведения о расшифровке, определяемые его ИД. PATCH speechtotext/v3.0/transcriptions/{id}
Удаляет указанную задачу транскрибирования. DELETE speechtotext/v3.0/transcriptions/{id}
Получает расшифровку, определяемую заданным ИД. GET speechtotext/v3.0/transcriptions/{id}
Возвращает файлы результатов транскрибирования, идентифицируемые по заданному ИД. GET speechtotext/v3.0/transcriptions/{id}/files

Вы можете проверить и протестировать подробный API, который доступен как документ Swagger.

Задания пакетного транскрибирования планируются с учетом всех возможных усилий. Нельзя сказать наверняка, когда состояние задания изменится на "Выполняется", однако это должно произойти в течение нескольких минут после обычной загрузки системы. В состоянии выполнения транскрибирование выполняется быстрее, чем воспроизведение аудио в среде выполнения.

Предварительные требования

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

Примечание

Для использования пакетного транскрибирования требуется стандартная подписка (S0) для Служб речи. Ключи бесплатной подписки (F0) не подходят. Дополнительные сведения см. на странице с Цены и ограничения.

Если вы планируете индивидуально настраивать модели, выполните действия, описанные в разделах Настройка акустических параметров и Настройка параметров языка. Чтобы использовать созданные модели при пакетном транскрибировании, требуется расположение моделей. Расположение модели можно получить при проверке сведений о модели (свойство self). Развернутая пользовательская конечная точка не требуется для службы транскрибирования пакетов.

Примечание

Служба пакетного транскрибирования в REST API содержит набор квот и ограничений, которые рекомендуется изучить. Чтобы использовать все преимущества пакетного транскрибирования для эффективного транскрибирования большого числа звуковых файлов, рекомендуется всегда отправлять несколько файлов в одном запросе или указывать контейнер хранилища BLOB-объектов с аудиофайлами для транскрибирования. Служба будет транскрибировать файлы одновременно, чтобы уменьшить общее время обработки. Использовать нескольких файлов в одном запросе довольно просто. Инструкции см. разделе Конфигурация.

API пакетного транскрибирования

API пакетного транскрибирования поддерживает следующие форматы.

Формат Кодек Число бит на выборку. Частота выборки
WAV PCM 16-разрядный 8 или 16 кГц, моно или стерео
MP3 PCM 16-разрядный 8 или 16 кГц, моно или стерео
OGG OPUS 16-разрядный 8 или 16 кГц, моно или стерео

Для аудиопотоков в стереоформате левый и правый каналы во время транскрибирования разделяются. Файл результатов JSON создается для каждого канала. Чтобы создать упорядоченную финальную расшифровку, используйте метки времени, созданные для каждого речевого фрагмента.

Конфигурация

Параметры конфигурации указываются в формате JSON.

Транскрибировать один отдельный файл или несколько. Если есть несколько файлов для транскрибирования, рекомендуется отправить несколько файлов в одном запросе. В следующем примере используется три файла.

{
  "contentUrls": [
    "<URL to an audio file 1 to transcribe>",
    "<URL to an audio file 2 to transcribe>",
    "<URL to an audio file 3 to transcribe>"
  ],
  "properties": {
    "wordLevelTimestampsEnabled": true
  },
  "locale": "en-US",
  "displayName": "Transcription of file using default model for en-US"
}

Обработка всего контейнера хранилища. SAS -контейнер должен содержать разрешения (чтение) и l (List):

{
  "contentContainerUrl": "<SAS URL to the Azure blob container to transcribe>",
  "properties": {
    "wordLevelTimestampsEnabled": true
  },
  "locale": "en-US",
  "displayName": "Transcription of container using default model for en-US"
}

Используйте пользовательскую обученную модель для пакетного транскрибирования. В следующем примере используется три файла.

{
  "contentUrls": [
    "<URL to an audio file 1 to transcribe>",
    "<URL to an audio file 2 to transcribe>",
    "<URL to an audio file 3 to transcribe>"
  ],
  "properties": {
    "wordLevelTimestampsEnabled": true
  },
  "locale": "en-US",
  "model": {
    "self": "https://westus.api.cognitive.microsoft.com/speechtotext/v3.0/models/{id}"
  },
  "displayName": "Transcription of file using default model for en-US"
}

Свойства конфигурации

Используйте следующие дополнительные свойства для настройки транскрибирования.

Параметр

Описание

profanityFilterMode

(Необязательно.) По умолчанию установлено значение Masked. Указывает, как обрабатывать ненормативную лексику в результатах распознавания. Допустимые значения: None — отключает фильтрацию ненормативной лексики, Masked — заменяет ненормативную лексику звездочками, Removed — удаляет всю ненормативную лексику из результата, Tags — добавляет теги, указывающие на ненормативную лексику.

punctuationMode

(Необязательно.) По умолчанию установлено значение DictatedAndAutomatic. Указывает, как обрабатывать знаки препинания в результатах распознавания. Допустимые значения: None — отключает пунктуацию, Dictated — указывает явный (произнесенный) знак пунктуации, Automatic — разрешает декодеру обрабатывать знаки препинания или DictatedAndAutomatic — позволяет использовать озвученную и автоматическую пунктуацию.

wordLevelTimestampsEnabled

(Необязательно.) По умолчанию установлено значение false. Указывает, следует ли добавлять к выводимым данным метки времени на уровне слова.

diarizationEnabled

(Необязательно.) По умолчанию установлено значение false. Указывает, что анализ диаризации должен выполняться для входных данных, в качестве которых, предположительно, выступает моноканал, содержащий два голоса. Примечание. Необходимо установить для параметра wordLevelTimestampsEnabled значение true.

channels

(Необязательно.) 0 и 1 транскрибируются по умолчанию. Массив номеров каналов для обработки. Здесь можно указать для обработки подмножество доступных каналов в звуковом файле (например, только 0).

timeToLive

(Необязательно.) По умолчанию удаление не выполняется. Длительность автоматического удаления записей после выполнения транскрипции. Параметр timeToLive полезен при массовой обработке расшифровок, позволяя обеспечить постепенное удаление расшифровок (например, в PT12H за 12 часов).

destinationContainerUrl

Дополнительный URL-адрес с динамическим SAS в контейнер Azure, доступный для записи. Результат сохраняется в этом контейнере. SAS с хранимой политикой доступа не поддерживаются. Если этот параметр не указан, корпорация Майкрософт сохраняет результаты в контейнере хранилища, который управляется Майкрософт. При удалении транскрипции путем вызова функции удаления расшифровки результирующие данные также будут удалены.

Память

Запись пакетов может считывать аудиоданные из общедоступного URI в Интернете, а также считывать аудиоданные или записывать расшифровки с помощью URI SAS с хранилищем BLOB-объектов Azure.

Результат пакетного транскрибирования

Для каждого входного аудиофайла создается один файл результатов транскрибирования. Операция получения файлов расшифровок возвращает список файлов результатов для этой операции транскрибирования. Чтобы найти файл транскрипции для определенного входного файла, отфильтруйте все возвращенные файлы с помощью kind == Transcription и name == {originalInputName.suffix}.json .

Все файлы результатов транскрибирования имеют следующий формат.

{
  "source": "...",                      // sas url of a given contentUrl or the path relative to the root of a given container
  "timestamp": "2020-06-16T09:30:21Z",  // creation time of the transcription, ISO 8601 encoded timestamp, combined date and time
  "durationInTicks": 41200000,          // total audio duration in ticks (1 tick is 100 nanoseconds)
  "duration": "PT4.12S",                // total audio duration, ISO 8601 encoded duration
  "combinedRecognizedPhrases": [        // concatenated results for simple access in single string for each channel
    {
      "channel": 0,                     // channel number of the concatenated results
      "lexical": "hello world",
      "itn": "hello world",
      "maskedITN": "hello world",
      "display": "Hello world."
    }
  ],
  "recognizedPhrases": [                // results for each phrase and each channel individually
    {
      "recognitionStatus": "Success",   // recognition state, e.g. "Success", "Failure"
      "speaker": 1,                     // if `diarizationEnabled` is `true`, this is the identified speaker (1 or 2), otherwise this property is not present
      "channel": 0,                     // channel number of the result
      "offset": "PT0.07S",              // offset in audio of this phrase, ISO 8601 encoded duration
      "duration": "PT1.59S",            // audio duration of this phrase, ISO 8601 encoded duration
      "offsetInTicks": 700000.0,        // offset in audio of this phrase in ticks (1 tick is 100 nanoseconds)
      "durationInTicks": 15900000.0,    // audio duration of this phrase in ticks (1 tick is 100 nanoseconds)

      // possible transcriptions of the current phrase with confidences
      "nBest": [
        {
          "confidence": 0.898652852,    // confidence value for the recognition of the whole phrase
          "lexical": "hello world",
          "itn": "hello world",
          "maskedITN": "hello world",
          "display": "Hello world.",

          // if wordLevelTimestampsEnabled is `true`, there will be a result for each word of the phrase, otherwise this property is not present
          "words": [
            {
              "word": "hello",
              "offset": "PT0.09S",
              "duration": "PT0.48S",
              "offsetInTicks": 900000.0,
              "durationInTicks": 4800000.0,
              "confidence": 0.987572
            },
            {
              "word": "world",
              "offset": "PT0.59S",
              "duration": "PT0.16S",
              "offsetInTicks": 5900000.0,
              "durationInTicks": 1600000.0,
              "confidence": 0.906032
            }
          ]
        }
      ]
    }
  ]
}

Результат содержит следующие поля.

Поле

Содержимое

lexical

Фактическое количество распознанных слов.

itn

Форма распознанного текста, нормализованная путем обратного преобразования текста. Применяются аббревиатуры («доктор Смит» — «д-р Смит»), номера телефонов и другие преобразования.

maskedITN

Форма ITN с применением маскировки ненормативной лексики.

display

Отображаемая форма распознанного текста. Включены знаки препинания и прописные буквы.

Разделение дикторов (диаризация)

Диаризация — это процесс разделения дикторов в фрагменте аудиозаписи. Конвейер пакетной обработки поддерживает диаризацию и может распознать двух дикторов в моноканальных записях. Эта функция недоступна для стереозаписей.

Выходные данные транскрибирования с диаризацией содержат записи Speaker для каждой транскрибированной фразы. Если диаризация не используется, свойство Speaker отсутствует в выходных данных JSON. Для диаризации поддерживается два голоса, поэтому дикторы обозначены как 1 или 2.

Чтобы запросить диаризацию, добавьте свойство diarizationEnabled в значение true, как показано в HTTP-запросе ниже.

{
  "contentUrls": [
    "<URL to an audio file to transcribe>",
  ],
  "properties": {
    "diarizationEnabled": true,
    "wordLevelTimestampsEnabled": true,
    "punctuationMode": "DictatedAndAutomatic",
    "profanityFilterMode": "Masked"
  },
  "locale": "en-US",
  "displayName": "Transcription of file using default model for en-US"
}

Метки времени на уровне слов должны быть включены, как определено параметрами в приведенном выше запросе.

Рекомендации

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

Совет

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

Пример кода

полные примеры доступны в GitHub примере репозитория в подкаталоге.

Обновите пример кода, указав сведения о подписке, регион службы, URI, указывающий на аудиофайл, для которого будет выполнено транскрибирование, а также расположение модели (если используется пользовательская модель).

var newTranscription = new Transcription
{
    DisplayName = DisplayName, 
    Locale = Locale, 
    ContentUrls = new[] { RecordingsBlobUri },
    //ContentContainerUrl = ContentAzureBlobContainer,
    Model = CustomModel,
    Properties = new TranscriptionProperties
    {
        IsWordLevelTimestampsEnabled = true,
        TimeToLive = TimeSpan.FromDays(1)
    }
};

newTranscription = await client.CreateTranscriptionAsync(newTranscription).ConfigureAwait(false);
Console.WriteLine($"Created transcription {newTranscription.Self}");

Пример кода настраивает клиент и отправляет запрос на транскрибирование. Затем пример кода запросит информацию о статусе и отобразит сведения о ходе выполнения транскрибирования.

// get the status of our transcriptions periodically and log results
int completed = 0, running = 0, notStarted = 0;
while (completed < 1)
{
    completed = 0; running = 0; notStarted = 0;

    // get all transcriptions for the user
    paginatedTranscriptions = null;
    do
    {
        // <transcriptionstatus>
        if (paginatedTranscriptions == null)
        {
            paginatedTranscriptions = await client.GetTranscriptionsAsync().ConfigureAwait(false);
        }
        else
        {
            paginatedTranscriptions = await client.GetTranscriptionsAsync(paginatedTranscriptions.NextLink).ConfigureAwait(false);
        }

        // delete all pre-existing completed transcriptions. If transcriptions are still running or not started, they will not be deleted
        foreach (var transcription in paginatedTranscriptions.Values)
        {
            switch (transcription.Status)
            {
                case "Failed":
                case "Succeeded":
                    // we check to see if it was one of the transcriptions we created from this client.
                    if (!createdTranscriptions.Contains(transcription.Self))
                    {
                        // not created form here, continue
                        continue;
                    }

                    completed++;

                    // if the transcription was successful, check the results
                    if (transcription.Status == "Succeeded")
                    {
                        var paginatedfiles = await client.GetTranscriptionFilesAsync(transcription.Links.Files).ConfigureAwait(false);

                        var resultFile = paginatedfiles.Values.FirstOrDefault(f => f.Kind == ArtifactKind.Transcription);
                        var result = await client.GetTranscriptionResultAsync(new Uri(resultFile.Links.ContentUrl)).ConfigureAwait(false);
                        Console.WriteLine("Transcription succeeded. Results: ");
                        Console.WriteLine(JsonConvert.SerializeObject(result, SpeechJsonContractResolver.WriterSettings));
                    }
                    else
                    {
                        Console.WriteLine("Transcription failed. Status: {0}", transcription.Properties.Error.Message);
                    }

                    break;

                case "Running":
                    running++;
                    break;

                case "NotStarted":
                    notStarted++;
                    break;
            }
        }

        // for each transcription in the list we check the status
        Console.WriteLine(string.Format("Transcriptions status: {0} completed, {1} running, {2} not started yet", completed, running, notStarted));
    }
    while (paginatedTranscriptions.NextLink != null);

    // </transcriptionstatus>
    // check again after 1 minute
    await Task.Delay(TimeSpan.FromMinutes(1)).ConfigureAwait(false);
}

Подробные сведения о предыдущих вызовах см. в документации по Swagger. полный пример, показанный здесь, можно найти в подкаталоге GitHub.

В этом примере асинхронная настройка используется для публикации аудиозаписей и получения сведений о статусе транскрибирования. Этот PostTranscriptionsметод отправляет сведения об аудиофайле, а метод GetTranscriptions получает сведения о статусе. PostTranscriptions возвращает дескриптор, который GetTranscriptions использует для создания дескриптора, чтобы получить состояние транскрибирования.

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

Примечание

Для базового транскрибирования не нужно объявлять идентификаторы базовых моделей.

Дальнейшие действия