音频(FIXME)

This commit is contained in:
Sch 2023-07-15 15:03:52 +08:00
parent 59e248fe01
commit 55bf9f6c0d

View File

@ -25,6 +25,7 @@
extern "C"
{
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"
#include "portaudio.h"
}
@ -77,36 +78,36 @@ void SCustomInputPanel::Construct(const FArguments& InArgs)
{
if (FPaths::GetExtension(OpenFileName[i]) == "mp3")
{
URuntimeAudioImporterLibrary* AudioImporter = URuntimeAudioImporterLibrary::CreateRuntimeAudioImporter();
AudioImporter->ImportAudioFromFile(OpenFileName[i], ERuntimeAudioFormat::Auto);
AudioImporter->OnResultNoDynamic.AddLambda([&, OpenFileName, i](URuntimeAudioImporterLibrary* Importer,
UImportedSoundWave* ImportedSoundWave, ERuntimeImportStatus Status)
{
switch (Status)
{
case ERuntimeImportStatus::SuccessfulImport:
{
GWorld->bAllowAudioPlayback = true;
UGameplayStatics::PlaySound2D(GEngine->GetWorldContextFromPIEInstance(0)->World(), ImportedSoundWave);
FTimelinePropertyData PropertyData;
PropertyData.Name = OpenFileName[i];
PropertyData.Type = ETrackType::AudioTrack;
PropertyData.MoviePath = OpenFileName[i];
PropertyData.Sound = ImportedSoundWave;
PropertyData.MovieFrameLength = ImportedSoundWave->GetDuration() * FGlobalData::GlobalFPS;
GridPanel->AddSlot(GridPanel->GetChildren()->Num() % 3, GridPanel->GetChildren()->Num() / 3)
[
SNew(SCustomInputResource)
.PropertyData(PropertyData)
];
}
break;
default:
break;
}
});
// URuntimeAudioImporterLibrary* AudioImporter = URuntimeAudioImporterLibrary::CreateRuntimeAudioImporter();
// AudioImporter->ImportAudioFromFile(OpenFileName[i], ERuntimeAudioFormat::Auto);
// AudioImporter->OnResultNoDynamic.AddLambda([&, OpenFileName, i](URuntimeAudioImporterLibrary* Importer,
// UImportedSoundWave* ImportedSoundWave, ERuntimeImportStatus Status)
// {
// switch (Status)
// {
// case ERuntimeImportStatus::SuccessfulImport:
// {
// GWorld->bAllowAudioPlayback = true;
//
// UGameplayStatics::PlaySound2D(GEngine->GetWorldContextFromPIEInstance(0)->World(), ImportedSoundWave);
// FTimelinePropertyData PropertyData;
// PropertyData.Name = OpenFileName[i];
// PropertyData.Type = ETrackType::AudioTrack;
// PropertyData.MoviePath = OpenFileName[i];
// PropertyData.Sound = ImportedSoundWave;
// PropertyData.MovieFrameLength = ImportedSoundWave->GetDuration() * FGlobalData::GlobalFPS;
//
// GridPanel->AddSlot(GridPanel->GetChildren()->Num() % 3, GridPanel->GetChildren()->Num() / 3)
// [
// SNew(SCustomInputResource)
// .PropertyData(PropertyData)
// ];
// }
// break;
// default:
// break;
// }
// });
AVFormatContext* FormatContext = nullptr;
if (avformat_open_input(&FormatContext, TCHAR_TO_UTF8(*OpenFileName[i]), nullptr, nullptr) != 0)
@ -135,32 +136,41 @@ void SCustomInputPanel::Construct(const FArguments& InArgs)
Pa_StartStream(Stream);
int64 Num = 0;
AVFrame* Frame;
AVCodec* Codec;
AVCodecParameters* CodecParam;
CodecParam = FormatContext->streams[0]->codecpar;
Codec = avcodec_find_decoder(CodecParam->codec_id);
Frame = av_frame_alloc();
AVCodecContext *CodecContext = avcodec_alloc_context3(Codec);
avcodec_open2(CodecContext, Codec, nullptr);
SwrContext* SwrContext = swr_alloc_set_opts(nullptr, AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, SampleRate, CodecContext->channel_layout, CodecContext->sample_fmt, CodecParam->sample_rate, 0, nullptr);
swr_init(SwrContext);
while (av_read_frame(FormatContext, &Packet) >= 0)
{
// Packet.buf->buffer->data.
Num = Pa_GetStreamWriteAvailable(Stream);
if (Num > 0)
avcodec_send_packet(CodecContext, &Packet);
while(avcodec_receive_frame(CodecContext, Frame) == 0)
{
Pa_WriteStream(Stream, Packet.buf, Packet.buf->size);
av_packet_unref(&Packet);
uint8* Out[2] = {nullptr, nullptr};
int OutCount = sizeof(Out) / sizeof(*Out);
int OutSize = av_samples_get_buffer_size(nullptr, CodecContext->channels, Frame->nb_samples, CodecContext->sample_fmt, 0);
// 设置 Out 指针到 新建的缓冲区
if (av_samples_alloc(Out, nullptr, CodecContext->channels, Frame->nb_samples, CodecContext->sample_fmt, 0) < 0)
{
check(false)
}
int32 Size = sizeof(*Out[0]);
swr_convert(SwrContext, Out, OutCount, const_cast<const uint8**>(Frame->data), Frame->nb_samples);
Pa_WriteStream(Stream, Out[0], Frame->nb_samples);
// Pa_Sleep(100);
av_freep(&Out[0]);
}
else
{
Pa_Sleep(10);
}
av_packet_unref(&Packet);
}
av_packet_unref(&Packet);
return FReply::Handled();
}
Async(EAsyncExecution::Thread, [&, this, OpenFileName, i]