#pragma once #include #include #include #include #include #include #include "CDNTrackStream.h" #include "CSpotContext.h" #include "TrackProvider.h" #include "TrackReference.h" #ifdef BELL_VORBIS_FLOAT #include "vorbis/vorbisfile.h" #else #include "ivorbisfile.h" #endif namespace cspot { class TrackPlayer : bell::Task { public: typedef std::function TrackLoadedCallback; typedef std::function DataCallback; typedef std::function EOFCallback; typedef std::function isAiringCallback; TrackPlayer(std::shared_ptr ctx, isAiringCallback, EOFCallback, TrackLoadedCallback); ~TrackPlayer(); void loadTrackFromRef(TrackReference& ref, size_t playbackMs, bool startAutomatically); void setDataCallback(DataCallback callback); CDNTrackStream::TrackInfo getCurrentTrackInfo(); void seekMs(size_t ms); void stopTrack(); // Vorbis codec callbacks size_t _vorbisRead(void* ptr, size_t size, size_t nmemb); size_t _vorbisClose(); int _vorbisSeek(int64_t offset, int whence); long _vorbisTell(); void destroy(); private: std::shared_ptr ctx; std::shared_ptr trackProvider; std::shared_ptr currentTrackStream; size_t sequence = std::time(nullptr); std::unique_ptr playbackSemaphore; TrackLoadedCallback trackLoaded; DataCallback dataCallback = nullptr; EOFCallback eofCallback; isAiringCallback isAiring; // Playback control std::atomic currentSongPlaying; std::mutex playbackMutex; std::mutex seekMutex; // Vorbis related OggVorbis_File vorbisFile; ov_callbacks vorbisCallbacks; int currentSection; std::vector pcmBuffer = std::vector(1024); size_t playbackPosition = 0; bool autoStart = false; std::atomic isRunning = true; std::mutex runningMutex; void runTask() override; }; } // namespace cspot