Импорт аудио
Обзор
Процесс импорта аудио во время выполнения можно разбить на несколько шагов:
- Создать Runtime Audio Importer
- Привязаться к необходимым делегатам (OnProgress и OnResult)
- Импортировать аудио из файла или буфера
- Воспроизвести импортированную звуковую волну, полученную из делегата OnResult (подробнее здесь)
Убедитесь, что экземпляры Runtime Audio Importer и Sound Wave не будут преждевременно удалены сборщиком мусора, поддерживая на них жёсткую ссылку. Это можно сделать, присвоив их отдельным переменным с помощью UPROPERTY(), TStrongObjectPtr или любого другого метода, который предотвращает уничтожение объекта.
Поддерживаемые аудиоформаты
Runtime Audio Importer поддерживает импорт следующих аудиоформатов:
| Формат | Описание |
|---|---|
| MP3 | MPEG-1/2/2.5 Audio Layer I/II/III |
| WAV | Waveform Audio File Format |
| FLAC | Free Lossless Audio Codec |
| OGG VORBIS | Контейнер Ogg с аудио Vorbis |
| OGG OPUS | Контейнер Ogg с аудио Opus |
| BINK | Bink Audio |
| RAW (PCM) | Несжатые аудиоданные импульсно-кодовой модуляции (Int8, UInt8, Int16, UInt16, Int32, UInt32, Float32) |
При импорте аудио вы можете либо явно указать формат, либо использовать автоматическое определение формата на основе расширения файла или его содержимого.
Импорт аудио с потоковой передачей
Для сценариев потоковой передачи, где аудиоданные поступают постепенно (например, с сервера, при захвате в реальном времени или из сетевых потоков), рассмотрите возможность использования Streaming Sound Waves.
Этот метод предоставляет непрерывный способ добавления аудиоданных в буфер одной и той же звуковой волны, что делает его подходящим для прямых трансляций или больших файлов, обрабатываемых частями. Подробнее см. в документации по Streaming Sound Wave.
Основные шаги реализации
1. Создать Runtime Audio Importer
Сначала необходимо создать объект Runtime Audio Importer. Убедитесь, что сборщик мусора рассматривает его как сильную ссылку.
- Blueprint
- C++

// UPROPERTY() is used here to prevent the object from being prematurely garbage collected
UPROPERTY()
class URuntimeAudioImporterLibrary* Importer;
Importer = URuntimeAudioImporterLibrary::CreateRuntimeAudioImporter();
2. Привязка к делегату OnProgress
Для отслеживания прогресса импорта аудиоданных вы можете привязаться к делегату OnProgress (Blueprints) / OnProgressNative (C++).
- Blueprint
- C++

// Assuming Importer is a UE reference to a URuntimeAudioImporterLibrary object
// AddWeakLambda is used just as an example. You can use any other method to bind the delegate, such as AddUObject, AddUFunction, etc.
Importer->OnProgressNative.AddWeakLambda(this, [](int32 Percentage)
{
UE_LOG(LogTemp, Log, TEXT("Import progress: %d"), Percentage);
});
Это позволит вам отслеживать прогресс и, например, реализовать экран загрузки.
3. Привязка к делегату OnResult
Чтобы получать уведомление о завершении процесса импорта аудиоданных и получить доступ к ссылке на результирующую звуковую волну, необходимо привязаться к делегату OnResult (Blueprints) / OnResultNative (C++).
- Blueprint
- C++

// Assuming Importer is a UE reference to a URuntimeAudioImporterLibrary object
// AddWeakLambda is used just as an example. You can use any other method to bind the delegate, such as AddUObject, AddUFunction, etc.
Importer->OnResultNative.AddWeakLambda(this, [](URuntimeAudioImporterLibrary* Importer, UImportedSoundWave* ImportedSoundWave, ERuntimeImportStatus Status)
{
UE_LOG(LogTemp, Log, TEXT("Import result: %s"), *UEnum::GetValueAsString(Status));
});
Убедитесь, что импортированная звуковая волна обрабатывается сборщиком мусора как сильная ссылка, чтобы предотвратить нежелательную преждевременную сборку мусора. Это можно сделать, поместив её в отдельную переменную в Blueprints.
4. Начать импорт аудио
Начните процесс импорта аудио, вызвав соответствующую функцию, которая может обрабатывать как сжатые, так и несжатые форматы аудиоданных.
- Blueprint
- C++

// Assuming Importer is a UE reference to a URuntimeAudioImporterLibrary object
// Import audio from a file
Importer->ImportAudioFromFile(TEXT("C:/Folder/AudioFile.mp3"), ERuntimeAudioFormat::Auto);
// Import audio from a buffer
TArray<uint8> AudioData = ...; // Fill the array with your audio data
Importer->ImportAudioFromBuffer(MoveTemp(AudioData), ERuntimeAudioFormat::OggVorbis);
// Import audio from a RAW file
Importer->ImportAudioFromRAWFile(TEXT("C:/Folder/AudioFile.raw"), ERuntimeRAWAudioFormat::Int8, 44100, 2);
// Import audio from a RAW buffer
TArray<uint8> RAWBuffer = ...; // Fill the array with your PCM int 16-bit audio data
Importer->ImportAudioFromRAWBuffer(MoveTemp(RAWBuffer), ERuntimeRAWAudioFormat::Int16, 44100, 2);
Вспомогательные функции
Поиск аудиофайлов
Вы можете просканировать каталог на наличие поддерживаемых аудиофайлов:
- Blueprint
- C++

URuntimeAudioUtilities::ScanDirectoryForAudioFiles(TEXT("C:/Folder/"), true,
FOnScanDirectoryForAudioFilesResultNative::CreateWeakLambda(this, [this](bool bSucceeded, const TArray<FString>& AudioFilePaths)
{
// Handle the result
}));
Полный пример
Вот полный пример реализации для импорта аудио:
- Blueprint
- C++

Это базовый пример кода для импорта аудио из файла.
Пример использует функцию ImportAudioExample, расположенную в классе UImportAudioClassExample внутри модуля EXAMPLEMODULE.
Для успешного запуска примера убедитесь, что добавили модуль RuntimeAudioImporter либо в PublicDependencyModuleNames, либо в PrivateDependencyModuleNames в файле .Build.cs, а также в файл .uproject вашего проекта.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "ImportAudioClassExample.generated.h"
UCLASS(BlueprintType)
class EXAMPLEMODULE_API UImportAudioClassExample : public UObject
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
void ImportAudioExample();
private:
// Please pay attention to making the RuntimeAudioImporter a hard reference, such as using UPROPERTY(), to prevent it from being prematurely garbage collected
UPROPERTY()
class URuntimeAudioImporterLibrary* RuntimeAudioImporter;
};
#include "ImportAudioClassExample.h"
#include "RuntimeAudioImporterLibrary.h"
void UImportAudioClassExample::ImportAudioExample()
{
RuntimeAudioImporter = URuntimeAudioImporterLibrary::CreateRuntimeAudioImporter();
if (!IsValid(RuntimeAudioImporter))
{
UE_LOG(LogTemp, Error, TEXT("Failed to create audio importer"));
return;
}
RuntimeAudioImporter->OnProgressNative.AddWeakLambda(this, [](int32 Percentage)
{
UE_LOG(LogTemp, Log, TEXT("Audio importing percentage: %d"), Percentage);
});
RuntimeAudioImporter->OnResultNative.AddWeakLambda(this, [this](URuntimeAudioImporterLibrary* Importer, UImportedSoundWave* ImportedSoundWave, ERuntimeImportStatus Status)
{
if (Status == ERuntimeImportStatus::SuccessfulImport)
{
UE_LOG(LogTemp, Warning, TEXT("Successfully imported audio with sound wave %s"), *ImportedSoundWave->GetName());
// Here you can handle ImportedSoundWave playback, like "UGameplayStatics::PlaySound2D(GetWorld(), ImportedSoundWave);"
}
else
{
UE_LOG(LogTemp, Error, TEXT("Failed to import audio"));
}
RuntimeAudioImporter = nullptr;
});
RuntimeAudioImporter->ImportAudioFromFile(TEXT("C:/Folder/Example.mp3"), ERuntimeAudioFormat::Auto);
}