ChunkedByteStream.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #ifndef CSPOT_CHUNKEDBYTESTREAM_H
  2. #define CSPOT_CHUNKEDBYTESTREAM_H
  3. #include "ByteStream.h"
  4. #include "BellLogger.h"
  5. #include <memory>
  6. #include "MercuryManager.h"
  7. #include "stdint.h"
  8. class ChunkedByteStream : public bell::ByteStream {
  9. private:
  10. // AES key used for data decryption
  11. std::vector<uint8_t> audioKey;
  12. // Spotify internal fileId
  13. std::vector<uint8_t> fileId;
  14. // Buffer for storing currently read chunks
  15. std::vector<std::shared_ptr<AudioChunk>> chunks;
  16. // Current position of the read pointer
  17. size_t pos = 0;
  18. size_t fileSize = -1;
  19. std::mutex readMutex;
  20. std::atomic<bool> loadAheadEnabled = false;
  21. std::shared_ptr<MercuryManager> mercuryManager;
  22. /**
  23. * Returns an audio chunk for given position.
  24. * @param position requested position
  25. * @return matching audio chunk, or nullptr if no chunk is available
  26. */
  27. std::shared_ptr<AudioChunk> getChunkForPosition(size_t position);
  28. /**
  29. * Requests a new audio chunk from mercury manager. Returns its structure immediately.
  30. * @param position index of a chunk to request
  31. * @return requested chunk
  32. */
  33. std::shared_ptr<AudioChunk> requestChunk(uint16_t position);
  34. /**
  35. * Tries to read data from a given audio chunk.
  36. * @param buffer destination buffer
  37. * @param bytes number of bytes to read
  38. * @param chunk `AudioChunk` to read from
  39. * @return number of bytes read
  40. */
  41. size_t attemptRead(uint8_t *buffer, size_t bytes, std::shared_ptr<AudioChunk> chunk);
  42. public:
  43. ChunkedByteStream(std::shared_ptr<MercuryManager> manager);
  44. ~ChunkedByteStream() {};
  45. /**
  46. * Requests first chunk from the file, and then fills file information based on its header
  47. */
  48. void fetchFileInformation();
  49. /**
  50. * Enables / disables load-ahead of chunks.
  51. * @param loadAhead true to enable load ahead
  52. */
  53. void setEnableLoadAhead(bool loadAhead);
  54. /**
  55. * Sets information about given spotify file, necessary for chunk request
  56. * @param fileId id of given audio file
  57. * @param audioKey audio key used for decryption
  58. */
  59. void setFileInfo(std::vector<uint8_t>& fileId, std::vector<uint8_t>& audioKey);
  60. // ---- ByteStream methods ----
  61. /**
  62. * Reads given amount of bytes from stream. Data is OPUS encoded.
  63. * @param buffer buffer to read into
  64. * @param size amount of bytes to read
  65. * @return amount of bytes read
  66. */
  67. size_t read(uint8_t *buf, size_t nbytes);
  68. /**
  69. * Seeks to given position in stream
  70. * @param pos position to seek to
  71. */
  72. void seek(size_t pos);
  73. /**
  74. * skip given amount of bytes in stream.
  75. * @param nbytes amount of bytes to skip
  76. */
  77. size_t skip(size_t nbytes);
  78. /**
  79. * Returns current position in stream.
  80. * @return position
  81. */
  82. size_t position();
  83. /**
  84. * Returns size of the file
  85. * @return bytes in file
  86. */
  87. size_t size();
  88. /**
  89. * Close the reader
  90. */
  91. void close();
  92. };
  93. #endif //CSPOT_CHUNKEDBYTESTREAM_H