-
-
Save cupsster/dc64e126952e255e4af7fd29ae23024c to your computer and use it in GitHub Desktop.
Unreal FFMpeg decoder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Fill out your copyright notice in the Description page of Project Settings. | |
#include "RIVR.h" | |
#include "FFMpegSoundWave.h" | |
UFFMpegSoundWave::UFFMpegSoundWave(const FObjectInitializer &ObjectInitializer) | |
{ | |
bProcedural = true; | |
bCanProcessAsync = true; | |
bStreaming = true; | |
DecompressionType = DTYPE_Procedural; | |
//TODO Move to safer zone | |
av_register_all(); | |
avformat_open_input(&container, "/Users/drouar_b/Antidote.mp3", NULL, NULL); | |
avformat_find_stream_info(container, NULL); | |
for (int i = 0; i < container->nb_streams; i++) { | |
if (container->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { | |
stream_id = i; | |
break; | |
} | |
} | |
codec_parameter = container->streams[stream_id]->codecpar; | |
codec = avcodec_find_decoder(codec_parameter->codec_id); | |
codec_context = avcodec_alloc_context3(codec); | |
avcodec_parameters_to_context(codec_context, codec_parameter); | |
avcodec_open2(codec_context, codec, NULL); | |
} | |
int32 UFFMpegSoundWave::GeneratePCMData(uint8* PCMData, const int32 SamplesNeeded) { | |
AVPacket *packet = av_packet_alloc(); | |
AVFrame *frame = av_frame_alloc(); | |
if (av_read_frame(container, packet) == 0) { | |
avcodec_send_packet(codec_context, packet); | |
avcodec_receive_frame(codec_context, frame); | |
GEngine->AddOnScreenDebugMessage(-1, 15, FColor::Red, FString::FromInt(frame->linesize[0])); | |
GEngine->AddOnScreenDebugMessage(-1, 15, FColor::Red, FString::FromInt(SamplesNeeded)); | |
memcpy(PCMData, frame->data[0], frame->linesize[0]); | |
return frame->linesize[0]; | |
} | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Fill out your copyright notice in the Description page of Project Settings. | |
#pragma once | |
#include "RIVR.h" | |
#include "Sound/SoundWaveProcedural.h" | |
extern "C" { | |
#include "libavformat/avformat.h" | |
#include "libavcodec/avcodec.h" | |
} | |
#include "FFMpegSoundWave.generated.h" | |
/** | |
* | |
*/ | |
UCLASS() | |
class RIVR_API UFFMpegSoundWave : public USoundWaveProcedural | |
{ | |
GENERATED_BODY() | |
public: | |
UFFMpegSoundWave(const FObjectInitializer &ObjectInitializer); | |
virtual int32 GeneratePCMData(uint8* PCMData, const int32 SamplesNeeded) override; | |
private: | |
int stream_id; | |
AVFormatContext* container; | |
AVCodecParameters* codec_parameter; | |
AVCodec* codec; | |
AVCodecContext *codec_context; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Fill out your copyright notice in the Description page of Project Settings. | |
#include "RIVR.h" | |
#include "MyActor.h" | |
// Sets default values | |
AMyActor::AMyActor(const FObjectInitializer &ObjectInitializer) | |
{ | |
ac = ObjectInitializer.CreateDefaultSubobject<UAudioComponent>(this, TEXT("audio component")); | |
ac->bAutoActivate = false; | |
ac->bStopWhenOwnerDestroyed = false; | |
} | |
// Called when the game starts or when spawned | |
void AMyActor::BeginPlay() | |
{ | |
Super::BeginPlay(); | |
sw = NewObject<UFFMpegSoundWave>(this); | |
sw->SampleRate = 44100; | |
sw->NumChannels = 1; | |
sw->Duration = INDEFINITELY_LOOPING_DURATION; | |
sw->bLooping = true; | |
TArray<uint8> data; | |
data.Init(0, 512); | |
int lol = sw->GeneratePCMData(data.GetData(), 512); | |
GEngine->AddOnScreenDebugMessage(-1, 1, FColor::Red, FString::FromInt(lol)); | |
ac->SetVolumeMultiplier(100); | |
ac->Activate(true); | |
ac->SetSound(sw); | |
ac->Play(0); | |
} | |
// Called every frame | |
void AMyActor::Tick( float DeltaTime ) | |
{ | |
Super::Tick( DeltaTime ); | |
} | |
void AMyActor::Debug(FString msg){ | |
if (GEngine){ | |
GEngine->AddOnScreenDebugMessage(-1, 1, FColor::Red, msg); | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Fill out your copyright notice in the Description page of Project Settings. | |
#pragma once | |
#include "GameFramework/Actor.h" | |
#include "Sound/SoundCue.h" | |
#include "Sound/SoundWaveProcedural.h" | |
#include "FFMpegSoundWave.h" | |
#include "MyActor.generated.h" | |
UCLASS() | |
class RIVR_API AMyActor : public AActor | |
{ | |
GENERATED_BODY() | |
public: | |
// Sets default values for this actor's properties | |
AMyActor(const FObjectInitializer &ObjectInitializer); | |
// Called when the game starts or when spawned | |
virtual void BeginPlay() override; | |
// Called every frame | |
virtual void Tick( float DeltaSeconds ) override; | |
void Debug(FString msg); | |
private: | |
UAudioComponent *ac; | |
USoundWave *sw; | |
TArray < uint8 > rawFile; | |
bool loaded; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you for providing example!