I gave it a spin, seems like the MP3Format is not really made for streaming, it will always fail, because the stream returns zero length…
BTW, if MP3AudioFormat is not found, enable it in the Projucer in the module juce_audio_formats
Here is my code anyway, maybe you or somebody else gets it to work, like another server type or something:
#include "../JuceLibraryCode/JuceHeader.h"
//==============================================================================
class MainContentComponent : public AudioAppComponent,
public Button::Listener
{
public:
//==============================================================================
MainContentComponent() :
tune (TRANS ("Tune")),
stop (TRANS ("Stop")),
play (TRANS ("PLay"))
{
thread = new TimeSliceThread ("Radio Thread");
url.setText ("https://listen.radionomy.com/Jazz4ever", dontSendNotification);
url.setEditable (true);
addAndMakeVisible (url);
addAndMakeVisible (tune);
addAndMakeVisible (stop);
addAndMakeVisible (play);
tune.addListener (this);
stop.addListener (this);
play.addListener (this);
setSize (200, 400);
thread->startThread (5);
// specify the number of input and output channels that we want to open
setAudioChannels (0, 2);
}
~MainContentComponent()
{
shutdownAudio();
thread->stopThread (1000);
}
//==============================================================================
void buttonClicked (Button* b) override
{
if (b == &tune)
tuneIn (url.getText());
else if (b == &stop)
radio.stop ();
else if (b == &play)
radio.start ();
}
void tuneIn (const String& address)
{
radio.setSource (nullptr);
MP3AudioFormat format;
auto* stream = new WebInputStream (address, false);
auto* reader = format.createReaderFor (stream, true);
if (reader)
{
auto* readerSource = new AudioFormatReaderSource (reader, true);
radio.setSource (readerSource,
jmax (480000., reader->sampleRate * 10),
thread,
reader->sampleRate,
reader->numChannels);
}
else
{
radio.setSource (nullptr);
}
}
//==============================================================================
void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override
{
radio.prepareToPlay (samplesPerBlockExpected, sampleRate);
}
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override
{
radio.getNextAudioBlock (bufferToFill);
}
void releaseResources() override
{
radio.releaseResources();
}
//==============================================================================
void paint (Graphics& g) override
{
// (Our component is opaque, so we must completely fill the background with a solid colour)
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
// You can add your drawing code here!
}
void resized() override
{
auto box = getLocalBounds().reduced (10);
auto h = box.getHeight() / 10;
url.setBounds (box.removeFromTop (h).reduced (0, 3));
auto buttonRow = box.removeFromTop (h).reduced (0, 3);
auto w = buttonRow.getWidth () / 3;
tune.setBounds (buttonRow.removeFromLeft (w));
stop.setBounds (buttonRow.removeFromLeft (w));
play.setBounds (buttonRow);
}
private:
//==============================================================================
// Your private member variables go here...
ScopedPointer<TimeSliceThread> thread;
AudioTransportSource radio;
Label url;
TextButton tune;
TextButton stop;
TextButton play;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};
// (This function is called by the app startup code to create our main component)
Component* createMainContentComponent() { return new MainContentComponent(); }