导入音频
概述
在运行时导入音频的过程可以分为以下几个步骤:
- 创建运行时音频导入器
- 绑定所需的委托(OnProgress 和 OnResult)
- 从文件或缓冲区导入音频
- 播放从 OnResult 委托获取的导入音效(更多信息请参见此处)
请确保 Runtime Audio Importer 和 Sound Wave 实例不会因垃圾回收而提前被销毁,可以通过使用 UPROPERTY()、TStrongObjectPtr 或其他防止对象被销毁的方法将它们分配给单独的变量来保持硬引用。
支持的音频格式
Runtime Audio Importer 支持导入以下音频格式:
格式 | 描述 |
---|---|
MP3 | MPEG-1/2/2.5 音频层 I/II/III |
WAV | 波形音频文件格式 |
FLAC | 免费无损音频编解码器 |
OGG VORBIS | 包含 Vorbis 音频的 Ogg 容器 |
OGG OPUS | 包含 Opus 音频的 Ogg 容器 |
BINK | Bink 音频 |
RAW (PCM) | 未压缩的脉冲编码调制音频数据(Int8、UInt8、Int16、UInt16、Int32、UInt32、Float32) |
导入音频时,您可以显式指定格式,也可以根据文件扩展名或内容自动检测格式。
流式音频导入
对于音频数据是增量接收的场景(例如来自服务器、实时捕获或网络流),请考虑使用 Streaming Sound Waves。
此方法提供了一种连续的方式将音频数据追加到同一音效的缓冲区中,适用于实时流或分块处理的大文件。详情请参阅流式音效文档。
基本实现步骤
1. 创建运行时音频导入器
首先,您需要创建一个 Runtime Audio Importer 对象。您应确保垃圾回收器将其视为强引用。
- 蓝图
- 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
(蓝图)/ 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));
});
请确保导入的声波被垃圾回收器视为强引用,以防止意外的过早垃圾回收。可以通过将其作为单独变量放置在蓝图中实现。
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
}));
完整示例
以下是导入音频的完整实现示例:
- 蓝图
- C++
这是一个从文件导入音频的基础代码示例。
该示例使用了位于EXAMPLEMODULE
模块中UImportAudioClassExample
类里的ImportAudioExample
函数。
要成功运行此示例,请确保将RuntimeAudioImporter
模块添加到**.Build.cs文件中的PublicDependencyModuleNames
或PrivateDependencyModuleNames
,同时也要添加到项目的.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);
}