Skip to content

Instantly share code, notes, and snippets.

@cupsster
Forked from drouarb/FFMpegSoundWave.cpp
Created February 10, 2017 14:17
Show Gist options
  • Save cupsster/dc64e126952e255e4af7fd29ae23024c to your computer and use it in GitHub Desktop.
Save cupsster/dc64e126952e255e4af7fd29ae23024c to your computer and use it in GitHub Desktop.
Unreal FFMpeg decoder
// 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;
}
// 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;
};
// 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);
}
}
// 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;
};
@cupsster
Copy link
Author

Thank you for providing example!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment