Spotify
е платформа за stream
-ване на музика, която предоставя на потребителите достъп до милиони песни на изпълнители от цял свят.
Stream
-ването е метод за предаване на данни, използван обикновено за мултимедийни файлове. При него възпроизвеждането на съдържанието върху устройството на потребителя започва още с достъпването му, без да се налага то отначало да бъде изтеглено изцяло като файл и после да се стартира в подходящ плеър. Предаването на данните протича едновременно с възпроизвеждането, затова е необходима постоянна мрежова свързаност.
Създайте приложение по подобие на Spotify
, състоящо се от две части - сървър и клиент.
Предоставя следните функционалности на клиента:
- регистриране в платформата чрез email и парола (потребителите трябва да се съхраняват във файл)
- login в платформата чрез email и парола
- съхраняване на набор от песни, достъпни на потребителите за слушане
- търсене на песни
- създаване на статистика на най-слушаните песни от потребителите
- създаване на плейлисти (плейлистите трябва да се съхраняват във файлове)
- добавяне на песни към плейлисти
- връщане на информация за даден плейлист
stream
-ване на песни
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
-
За да можете да изпълнявате песни от
Spotify
клиента, използвайте API-тоjavax.sound.sampled
. -
javax.sound.sampled
работи само с файлове във wav формат, затова всички песни, които имате на сървъра, трябва да са .wav -
javax.sound.sampled
предоставя два начина за възпроизвеждане на музика - чрезClip
иSourceDataLine
.Clip
се използва когато имамеnon-real-time
музикални данни (файл), които могат да бъдат предварително заредени в паметта.SourceDataLine
се използва заstream
-ване на данни, като например голям музикален файл, който не може да се зареди в паметта наведнъж, или за данни, които предварително не са известни. (за повече информация тук)За целите на проекта, трябва да използвате
SourceDataLine
.-
За да създадем
SourceDataLine
първо трябва да знаем конкретния формат на данните, които ще получаваме по мрежата. Това става с класаAudioFormat
. За да успеем да възпроизведем дадена песен при клиента, трябва предварително да знаем какъв е този формат. -
Преди сървърът да започне да ни
stream
-ва песента, той трябва да ни даде(прати) информация за формата на данните. КласътAudioFormat
не еSerializable
, т.е не можем да изпратим на клиента директно обект от типAudioFormat
. -
За да вземем формата на песента на сървъра, можем да използваме следния код:
AudioFormat audioFormat = AudioSystem.getAudioInputStream(new File(song)).getFormat();
-
Данните, които са необходими на клиента, са всички полета от конструктора на
AudioFormat
. Те могат да бъдат достъпени чрез съответнитеgetter
методи:AudioFormat(AudioFormat.Encoding encoding, float sampleRate, int sampleSizeInBits, int channels, int frameSize, float frameRate, boolean bigEndian)
-
След като сървърът е изпратил формата на данните, клиентът вече е готов да създаде съответния
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() пуска нова нишка. За повече информация, може да проверите имплементацията.
-
За да запишем данни в
SourceDataLine
обекта (данните, които искаме да възпроизведем) използваме следния метод:dataLine.write(byte[] b, int off, int len);
-
За тестови цели, можем да си пуснем песен (non-real-time) със следния код:
AudioInputStream stream = AudioSystem.getAudioInputStream(new File("<music>.wav")); SourceDataLine dataLine = AudioSystem.getSourceDataLine(stream.getFormat()); dataLine.open(); dataLine.start(); while (true);
-
-
Валидирайте по подходящ начин командите
-
При възникване на програмна грешка, извеждайте в конзолата смислени съобщения на потребителя - не се предполага клиентът да има умения да
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.
Качете в грейдъра .zip
архив на познатите директории src
и test
. Ако пакетирате допълнителни файлове (които не са .java), те трябва да са в корена на архива, на нивото на src
и test
.
В грейдъра няма да има автоматизирани референтни тестове.
Проектът ви трябва да е качен в грейдъра не по-късно от 18:00 в деня преди датата на защитата.
Успех!