Basic Multi-Track Audio Player

I am trying to make a very basic multi-track audio player. Below is the rough start I have come up with, based on some of the demos. It is a 2 track audio player. Do I have the right idea, or this a really bad way to do this?

#pragma once

//==============================================================================
class Track  :  public AudioTransportSource,
                public Component
{
public:
    Track()
    {
        formatManager.registerBasicFormats();
        thread.startThread (3);
    }

    ~Track() override
    {
        setSource (nullptr);
    }

    void paint (Graphics& g) override
    {
        g.fillAll (Colours::grey);
    }

    void resized() override {}
    
    void loadFile(String absoluteFilePath)
    {
        const File *f1 = new const File(absoluteFilePath);
        showAudioResource (URL (*f1));
    }
    
    void startOrStop()
    {
        if (this->isPlaying())
        {
            this->stop();
        }
        else
        {
            this->setPosition (0);
            this->start();
        }
    }

private:
    AudioFormatManager formatManager;
    TimeSliceThread thread { "audio file preview" };

    URL currentAudioFile;
    std::unique_ptr<AudioFormatReaderSource> currentAudioFileSource;

    TextButton startStopButton { "Play/Stop" };

    void showAudioResource (URL resource)
    {
        if (loadURLIntoTransport (resource))
            currentAudioFile = std::move (resource);
    }

    bool loadURLIntoTransport (const URL& audioURL)
    {
        // unload the previous file source and delete it..
        this->stop();
        this->setSource (nullptr);
        currentAudioFileSource.reset();

        AudioFormatReader* reader = nullptr;

       #if ! JUCE_IOS
        if (audioURL.isLocalFile())
        {
            reader = formatManager.createReaderFor (audioURL.getLocalFile());
        }
        else
       #endif
        {
            if (reader == nullptr)
                reader = formatManager.createReaderFor (audioURL.createInputStream (false));
        }

        if (reader != nullptr)
        {
            currentAudioFileSource.reset (new AudioFormatReaderSource (reader, true));
            
            // ..and plug it into our transport source
            this->setSource (currentAudioFileSource.get(),
                                       32768,                   // tells it to buffer this many samples ahead
                                       &thread,                 // this is the background thread to use for reading-ahead
                                       reader->sampleRate);     // allows for sample rate correction
            return true;
        }

        return false;
    }
};

//==============================================================================
class MultiTrackTest : public Component
{
public:
    MultiTrackTest()
    {
        RuntimePermissions::request (RuntimePermissions::recordAudio,
        [this] (bool granted)
        {
            int numInputChannels = granted ? 2 : 0;
            audioDeviceManager.initialise (numInputChannels, 2, nullptr, true, {}, nullptr);
        });
        
        track1.loadFile("/Users/shawn/Documents/Test1.wav");
        audioSourcePlayer1.setSource (&track1);
        audioDeviceManager.addAudioCallback (&audioSourcePlayer1);
        
        track2.loadFile("/Users/shawn/Documents/Test2.wav");
        audioSourcePlayer2.setSource (&track2);
        audioDeviceManager.addAudioCallback (&audioSourcePlayer2);
        
        addAndMakeVisible (track1);
        addAndMakeVisible (track2);
        
        addAndMakeVisible (startStopButton);
        startStopButton.setColour (TextButton::buttonColourId, Colours::green);
        startStopButton.setColour (TextButton::textColourOffId, Colours::black);
        startStopButton.onClick = [this] { startOrStop(); };
        
        setOpaque (true);
        setSize (600, 500);
    }
    
    ~MultiTrackTest() override
    {
        audioSourcePlayer1.setSource (nullptr);
        audioDeviceManager.removeAudioCallback (&audioSourcePlayer1);
        
        audioSourcePlayer2.setSource (nullptr);
        audioDeviceManager.removeAudioCallback (&audioSourcePlayer2);
    }
    
    void paint (Graphics& g) override
    {
        g.fillAll ();
    }
    
    void resized() override
    {
        auto r = getLocalBounds().reduced (8);
        
        auto startStopButtonPlacement = r.removeFromTop (30);
        startStopButton.setBounds (startStopButtonPlacement);
        
        r.removeFromTop (10);
        
        auto track1Placement = r.removeFromTop(100);
        track1.setBounds (track1Placement);
        
        r.removeFromTop (10);
        
        auto track2Placement = r.removeFromTop(100);
        track2.setBounds (track2Placement);
    }
    
private:
    AudioDeviceManager audioDeviceManager;
    AudioSourcePlayer audioSourcePlayer1;
    AudioSourcePlayer audioSourcePlayer2;
    TextButton startStopButton { "Play/Stop" };
    
    Track track1;
    Track track2;
    
    void startOrStop()
    {
        track1.startOrStop();
        track2.startOrStop();
    }
    
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MultiTrackTest)
};