استيراد الصوت
نظرة عامة
يمكن تقسيم عملية استيراد الصوت أثناء التشغيل إلى عدة خطوات:
- إنشاء أداة استيراد الصوت أثناء التشغيل (Runtime Audio Importer)
- الربط بالوكلاء المطلوبين (OnProgress و OnResult)
- استيراد الصوت من ملف أو مخزن مؤقت (buffer)
- تشغيل موجة الصوت المستوردة التي تم الحصول عليها من وكيل OnResult (المزيد من المعلومات هنا)
تأكد من عدم جمع كلا مثيلي Runtime Audio Importer و Sound Wave بواسطة جامع القمامة قبل الأوان عن طريق الحفاظ على مرجع قوي لهما، ويمكن القيام بذلك عن طريق تعيينهما لمتغيرات منفصلة باستخدام UPROPERTY()، أو TStrongObjectPtr، أو أي طريقة أخرى تمنع تدمير الكائن.
تنسيقات الصوت المدعومة
تدعم أداة استيراد الصوت أثناء التشغيل استيراد تنسيقات الصوت التالية:
| التنسيق | الوصف |
|---|---|
| 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) | بيانات صوت غير مضغوطة بتعديل رمز النبض (Pulse-Code Modulation) (Int8, UInt8, Int16, UInt16, Int32, UInt32, Float32) |
عند استيراد الصوت، يمكنك إما تحديد التنسيق صراحةً أو استخدام الكشف التلقائي عن التنسيق بناءً على امتداد الملف أو محتواه.
عمليات استيراد الصوت المتدفق
بالنسبة لسيناريوهات التدفق حيث يتم استقبال بيانات الصوت بشكل تدريجي (على سبيل المثال، من خادم، أو تسجيل في الوقت الفعلي، أو تدفقات الشبكة)، فكر في استخدام Streaming Sound Waves.
توفر هذه الطريقة وسيلة مستمرة لإلحاق بيانات الصوت بنفس المخزن المؤقت (buffer) لموجة الصوت، مما يجعلها مناسبة للتدفقات الحية أو الملفات الكبيرة التي تتم معالجتها على شكل أجزاء. راجع توثيق Streaming Sound Wave لمزيد من التفاصيل.
خطوات التنفيذ الأساسية
1. إنشاء أداة استيراد الصوت أثناء التشغيل
أولاً، تحتاج إلى إنشاء كائن 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 (بلوبرينتس) / 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);
}