Skip to content

DanielHalachev/Spotify

Repository files navigation

Spotify 🎶

Spotify е платформа за stream-ване на музика, която предоставя на потребителите достъп до милиони песни на изпълнители от цял свят.

Stream-ването е метод за предаване на данни, използван обикновено за мултимедийни файлове. При него възпроизвеждането на съдържанието върху устройството на потребителя започва още с достъпването му, без да се налага то отначало да бъде изтеглено изцяло като файл и после да се стартира в подходящ плеър. Предаването на данните протича едновременно с възпроизвеждането, затова е необходима постоянна мрежова свързаност.

Условие

Създайте приложение по подобие на Spotify, състоящо се от две части - сървър и клиент.

Spotify Server

Предоставя следните функционалности на клиента:

  • регистриране в платформата чрез email и парола (потребителите трябва да се съхраняват във файл)
  • login в платформата чрез email и парола
  • съхраняване на набор от песни, достъпни на потребителите за слушане
  • търсене на песни
  • създаване на статистика на най-слушаните песни от потребителите
  • създаване на плейлисти (плейлистите трябва да се съхраняват във файлове)
  • добавяне на песни към плейлисти
  • връщане на информация за даден плейлист
  • stream-ване на песни

Spotify Client

Spotify клиентът трябва да има command line interface със следните команди:

register <email> <password>
login <email> <password>
disconnect
search <words> - връща всички песни, в чиито имена или имената на изпълнителите им, се среща потърсената дума (или думи)
top <number> - връща списък с *number* от най-слушаните песни в момента, сортиран в намаляващ ред
create-playlist <name_of_the_playlist>
add-song-to <name_of_the_playlist> <song>
show-playlist <name_of_the_playlist>
play <song>
stop

Забележки:

  1. За да можете да изпълнявате песни от Spotify клиента, използвайте API-то javax.sound.sampled.

  2. javax.sound.sampled работи само с файлове във wav формат, затова всички песни, които имате на сървъра, трябва да са .wav

  3. javax.sound.sampled предоставя два начина за възпроизвеждане на музика - чрез Clip и SourceDataLine. Clip се използва когато имаме non-real-time музикални данни (файл), които могат да бъдат предварително заредени в паметта. SourceDataLine се използва за stream-ване на данни, като например голям музикален файл, който не може да се зареди в паметта наведнъж, или за данни, които предварително не са известни. (за повече информация тук)

    За целите на проекта, трябва да използвате SourceDataLine.

    1. За да създадем SourceDataLine първо трябва да знаем конкретния формат на данните, които ще получаваме по мрежата. Това става с класа AudioFormat. За да успеем да възпроизведем дадена песен при клиента, трябва предварително да знаем какъв е този формат.

    2. Преди сървърът да започне да ни stream-ва песента, той трябва да ни даде(прати) информация за формата на данните. Класът AudioFormat не е Serializable, т.е не можем да изпратим на клиента директно обект от тип AudioFormat.

    3. За да вземем формата на песента на сървъра, можем да използваме следния код:

      AudioFormat audioFormat = AudioSystem.getAudioInputStream(new File(song)).getFormat();
    4. Данните, които са необходими на клиента, са всички полета от конструктора на AudioFormat. Те могат да бъдат достъпени чрез съответните getter методи:

      AudioFormat(AudioFormat.Encoding encoding, float sampleRate, int sampleSizeInBits, int channels, int frameSize, float frameRate, boolean bigEndian)
    5. След като сървърът е изпратил формата на данните, клиентът вече е готов да създаде съответния SourceDataLine обект, чрез който ще се възпроизвежда песента.

      Encoding encoding = ...;
      int sampleRate = ...;
      ...
      AudioFormat format = new AudioFormat(encoding, sampleRate, sampleSizeInBits, channels, frameSize, frameRate, bigEndian);
      DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
      
      SourceDataLine dataLine = (SourceDataLine) AudioSystem.getLine(info);
      dataLine.open();
      dataLine.start(); // Имайте предвид, че SourceDataLine.start() пуска нова нишка. За повече информация, може да проверите имплементацията.
    6. За да запишем данни в SourceDataLine обекта (данните, които искаме да възпроизведем) използваме следния метод:

      dataLine.write(byte[] b, int off, int len);
    7. За тестови цели, можем да си пуснем песен (non-real-time) със следния код:

      AudioInputStream stream = AudioSystem.getAudioInputStream(new File("<music>.wav"));
      SourceDataLine dataLine = AudioSystem.getSourceDataLine(stream.getFormat());
      dataLine.open();
      dataLine.start();
      
      while (true);
  4. Валидирайте по подходящ начин командите

  5. При възникване на програмна грешка, извеждайте в конзолата смислени съобщения на потребителя - не се предполага клиентът да има умения да troubleshoot-ва exception-и, затова printStackTrace() не е добър вариант. Хврълените exception-и записвайте във файл.

Съобщения за грешки

При неправилно използване на програмата, на потребителя да се извеждат подходящи съобщения за грешка.

При възникване програмна грешка, на потребителя да се извежда само уместна за него информация. Техническа информация за самата грешка и stackтraces да се записват във файл на файловата система - няма определен формат за записване на грешката.

Например, нерелевантно е при команда на потребител и възникнал проблем с мрежовата комуникация, да се изписва грешка от вида на "IO exception occurred: connection reset", по-подходящо би било "Unable to connect to the server. Try again later or contact administrator by providing the logs in <path_to_logs_file>".

При възникване на програмна грешка от страна на сървъра, подходящо съобщение се изписва на конзолата и във файл, като освен това, във файла се записва допълнителна информация (например, при заявка на кой потребител е възникнала грешката, ако въобще е обвързана с потребителско взаимодействие) и stacktraces.

Submission

Качете в грейдъра .zip архив на познатите директории src и test. Ако пакетирате допълнителни файлове (които не са .java), те трябва да са в корена на архива, на нивото на src и test. В грейдъра няма да има автоматизирани референтни тестове. Проектът ви трябва да е качен в грейдъра не по-късно от 18:00 в деня преди датата на защитата.

Успех!

About

My Java Course Project

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages