├── MP3MusicPlayer.iml
├── README.md
├── Screenshot_38.png
├── lib
├── jaudiotagger-3.0.1.jar
├── jlayer-1.0.1.jar
└── mp3agic-0.9.0.jar
├── out
└── production
│ └── MP3MusicPlayer
│ ├── App$1.class
│ ├── App.class
│ ├── MusicPlayer$1.class
│ ├── MusicPlayer$2.class
│ ├── MusicPlayer.class
│ ├── MusicPlayerGUI$1.class
│ ├── MusicPlayerGUI$2.class
│ ├── MusicPlayerGUI$3.class
│ ├── MusicPlayerGUI$4.class
│ ├── MusicPlayerGUI$5.class
│ ├── MusicPlayerGUI$6.class
│ ├── MusicPlayerGUI$7.class
│ ├── MusicPlayerGUI$8.class
│ ├── MusicPlayerGUI.class
│ ├── MusicPlaylistDialog$1.class
│ ├── MusicPlaylistDialog$2.class
│ ├── MusicPlaylistDialog.class
│ ├── Song.class
│ └── assets
│ ├── Auld Lang Syne (Instrumental) - Jingle Punks.mp3
│ ├── Tropic Fuse - French Fuse.mp3
│ ├── Wind Riders - Asher Fulero.mp3
│ ├── next.png
│ ├── pause.png
│ ├── play.png
│ ├── playlist.txt
│ ├── playlist2.txt
│ ├── playlist3.txt
│ ├── previous.png
│ └── record.png
└── src
├── App.java
├── MusicPlayer.java
├── MusicPlayerGUI.java
├── MusicPlaylistDialog.java
├── Song.java
└── assets
├── Auld Lang Syne (Instrumental) - Jingle Punks.mp3
├── Tropic Fuse - French Fuse.mp3
├── Wind Riders - Asher Fulero.mp3
├── next.png
├── pause.png
├── play.png
├── playlist.txt
├── playlist2.txt
├── playlist3.txt
├── previous.png
└── record.png
/MP3MusicPlayer.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
MP3 Music Player App
3 |
4 |
5 | Introduction
6 | In this project, you'll learn how to build a MP3 Music Player App in Java! You can check out the full tutorial here
7 | , where I carefully go over the logic flow so that you can understand how this project is coded the way it was.
8 |
9 |
10 |
11 | Technologies Frameworks
12 |
13 | - JDK 18+ - Java Version
14 | - Mp3Magic - A java library for reading mp3 files and manipulating mp3 file ID3 tags
15 | - JLayer - MP3 decoder/player/converter library for Java™ platform.
16 | - JAudioTagger - The aim of this project is to provide a world class Java library for editing tag information in audio files. Most existing solutions are not java based inhibiting the use of java applications with digital files.
17 |
18 |
19 |
20 | Features
21 |
22 | - 🎶 Play an MP3 File (Song)
23 | - 🎙 Display Title of Song
24 | - 👤 Display Artist of Song
25 | - ⏳ Display the Length of the Song
26 | - ⏪ Playback Functionality
27 | - ⏸ Pause Song
28 | - ▶ Resume Song
29 | - ⏭ Go to next Song in a playlist
30 | - ⏮ Go to previous Song in a playlist
31 | - 📃 Create a Custom Playlist
32 | - 🔃 Load a Custom Playlist
33 |
34 |
35 |
36 |
37 | Screenshots
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Screenshot_38.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/Screenshot_38.png
--------------------------------------------------------------------------------
/lib/jaudiotagger-3.0.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/lib/jaudiotagger-3.0.1.jar
--------------------------------------------------------------------------------
/lib/jlayer-1.0.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/lib/jlayer-1.0.1.jar
--------------------------------------------------------------------------------
/lib/mp3agic-0.9.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/lib/mp3agic-0.9.0.jar
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/App$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/App$1.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/App.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/App.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/MusicPlayer$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayer$1.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/MusicPlayer$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayer$2.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/MusicPlayer.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayer.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/MusicPlayerGUI$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$1.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/MusicPlayerGUI$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$2.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/MusicPlayerGUI$3.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$3.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/MusicPlayerGUI$4.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$4.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/MusicPlayerGUI$5.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$5.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/MusicPlayerGUI$6.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$6.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/MusicPlayerGUI$7.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$7.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/MusicPlayerGUI$8.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI$8.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/MusicPlayerGUI.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlayerGUI.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/MusicPlaylistDialog$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlaylistDialog$1.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/MusicPlaylistDialog$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlaylistDialog$2.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/MusicPlaylistDialog.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/MusicPlaylistDialog.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/Song.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/Song.class
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/assets/Auld Lang Syne (Instrumental) - Jingle Punks.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/Auld Lang Syne (Instrumental) - Jingle Punks.mp3
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/assets/Tropic Fuse - French Fuse.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/Tropic Fuse - French Fuse.mp3
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/assets/Wind Riders - Asher Fulero.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/Wind Riders - Asher Fulero.mp3
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/assets/next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/next.png
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/assets/pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/pause.png
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/assets/play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/play.png
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/assets/playlist.txt:
--------------------------------------------------------------------------------
1 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Auld Lang Syne (Instrumental) - Jingle Punks.mp3
2 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Tropic Fuse - French Fuse.mp3
3 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Wind Riders - Asher Fulero.mp3
4 |
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/assets/playlist2.txt:
--------------------------------------------------------------------------------
1 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Auld Lang Syne (Instrumental) - Jingle Punks.mp3
2 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Tropic Fuse - French Fuse.mp3
3 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Wind Riders - Asher Fulero.mp3
4 |
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/assets/playlist3.txt:
--------------------------------------------------------------------------------
1 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Auld Lang Syne (Instrumental) - Jingle Punks.mp3
2 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Tropic Fuse - French Fuse.mp3
3 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Wind Riders - Asher Fulero.mp3
4 |
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/assets/previous.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/previous.png
--------------------------------------------------------------------------------
/out/production/MP3MusicPlayer/assets/record.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/out/production/MP3MusicPlayer/assets/record.png
--------------------------------------------------------------------------------
/src/App.java:
--------------------------------------------------------------------------------
1 | import javax.swing.*;
2 |
3 | public class App {
4 | public static void main(String[] args) {
5 | SwingUtilities.invokeLater(new Runnable(){
6 | @Override
7 | public void run(){
8 | new MusicPlayerGUI().setVisible(true);
9 |
10 | // Song song = new Song("src/assets/Wind Riders - Asher Fulero.mp3");
11 | // System.out.println(song.getSongTitle());
12 | // System.out.println(song.getSongArtist());
13 | }
14 | });
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/MusicPlayer.java:
--------------------------------------------------------------------------------
1 | import javazoom.jl.player.advanced.AdvancedPlayer;
2 | import javazoom.jl.player.advanced.PlaybackEvent;
3 | import javazoom.jl.player.advanced.PlaybackListener;
4 |
5 | import java.io.*;
6 | import java.util.ArrayList;
7 |
8 | public class MusicPlayer extends PlaybackListener {
9 | // this will be used to update isPaused more synchronously
10 | private static final Object playSignal = new Object();
11 |
12 | // need reference so that we can update the gui in this class
13 | private MusicPlayerGUI musicPlayerGUI;
14 |
15 | // we will need a way to store our song's details, so we will be creating a song class
16 | private Song currentSong;
17 | public Song getCurrentSong(){
18 | return currentSong;
19 | }
20 |
21 | private ArrayList playlist;
22 |
23 | // we will need to keep track the index we are in the playlist
24 | private int currentPlaylistIndex;
25 |
26 | // use JLayer library to create an AdvancedPlayer obj which will handle playing the music
27 | private AdvancedPlayer advancedPlayer;
28 |
29 | // pause boolean flag used to indicate whether the player has been paused
30 | private boolean isPaused;
31 |
32 | // boolean flag used to tell when the song has finished
33 | private boolean songFinished;
34 |
35 | private boolean pressedNext, pressedPrev;
36 |
37 | // stores in teh last frame when the playback is finished (used for pausing and resuming)
38 | private int currentFrame;
39 | public void setCurrentFrame(int frame){
40 | currentFrame = frame;
41 | }
42 |
43 | // track how many milliseconds has passed since playing the song (used for updating the slider)
44 | private int currentTimeInMilli;
45 | public void setCurrentTimeInMilli(int timeInMilli){
46 | currentTimeInMilli = timeInMilli;
47 | }
48 |
49 | // constructor
50 | public MusicPlayer(MusicPlayerGUI musicPlayerGUI){
51 | this.musicPlayerGUI = musicPlayerGUI;
52 | }
53 |
54 | public void loadSong(Song song){
55 | currentSong = song;
56 | playlist = null;
57 |
58 | // stop the song if possible
59 | if(!songFinished)
60 | stopSong();
61 |
62 | // play the current song if not null
63 | if(currentSong != null){
64 | // reset frame
65 | currentFrame = 0;
66 |
67 | // reset current time in milli
68 | currentTimeInMilli = 0;
69 |
70 | // update gui
71 | musicPlayerGUI.setPlaybackSliderValue(0);
72 |
73 | playCurrentSong();
74 | }
75 | }
76 |
77 | public void loadPlaylist(File playlistFile){
78 | playlist = new ArrayList<>();
79 |
80 | // store the paths from the text file into the playlist array list
81 | try{
82 | FileReader fileReader = new FileReader(playlistFile);
83 | BufferedReader bufferedReader = new BufferedReader(fileReader);
84 |
85 | // reach each line from the text file and store the text into the songPath variable
86 | String songPath;
87 | while((songPath = bufferedReader.readLine()) != null){
88 | // create song object based on song path
89 | Song song = new Song(songPath);
90 |
91 | // add to playlist array list
92 | playlist.add(song);
93 | }
94 | }catch(Exception e){
95 | e.printStackTrace();
96 | }
97 |
98 | if(playlist.size() > 0){
99 | // reset playback slider
100 | musicPlayerGUI.setPlaybackSliderValue(0);
101 | currentTimeInMilli = 0;
102 |
103 | // update current song to the first song in the playlist
104 | currentSong = playlist.get(0);
105 |
106 | // start from the beginning frame
107 | currentFrame = 0;
108 |
109 | // update gui
110 | musicPlayerGUI.enablePauseButtonDisablePlayButton();
111 | musicPlayerGUI.updateSongTitleAndArtist(currentSong);
112 | musicPlayerGUI.updatePlaybackSlider(currentSong);
113 |
114 | // start song
115 | playCurrentSong();
116 | }
117 | }
118 |
119 | public void pauseSong(){
120 | if(advancedPlayer != null){
121 | // update isPaused flag
122 | isPaused = true;
123 |
124 | // then we want to stop the player
125 | stopSong();
126 | }
127 | }
128 |
129 | public void stopSong(){
130 | if(advancedPlayer != null){
131 | advancedPlayer.stop();
132 | advancedPlayer.close();
133 | advancedPlayer = null;
134 | }
135 | }
136 |
137 | public void nextSong(){
138 | // no need to go to the next song if there is no playlist
139 | if(playlist == null) return;
140 |
141 | // check to see if we have reached the end of the playlist, if so then don't do anything
142 | if(currentPlaylistIndex + 1 > playlist.size() - 1) return;
143 |
144 | pressedNext = true;
145 |
146 | // stop the song if possible
147 | if(!songFinished)
148 | stopSong();
149 |
150 | // increase current playlist index
151 | currentPlaylistIndex++;
152 |
153 | // update current song
154 | currentSong = playlist.get(currentPlaylistIndex);
155 |
156 | // reset frame
157 | currentFrame = 0;
158 |
159 | // reset current time in milli
160 | currentTimeInMilli = 0;
161 |
162 | // update gui
163 | musicPlayerGUI.enablePauseButtonDisablePlayButton();
164 | musicPlayerGUI.updateSongTitleAndArtist(currentSong);
165 | musicPlayerGUI.updatePlaybackSlider(currentSong);
166 |
167 | // play the song
168 | playCurrentSong();
169 | }
170 |
171 | public void prevSong(){
172 | // no need to go to the next song if there is no playlist
173 | if(playlist == null) return;
174 |
175 | // check to see if we can go to the previous song
176 | if(currentPlaylistIndex - 1 < 0) return;
177 |
178 | pressedPrev = true;
179 |
180 | // stop the song if possible
181 | if(!songFinished)
182 | stopSong();
183 |
184 | // decrease current playlist index
185 | currentPlaylistIndex--;
186 |
187 | // update current song
188 | currentSong = playlist.get(currentPlaylistIndex);
189 |
190 | // reset frame
191 | currentFrame = 0;
192 |
193 | // reset current time in milli
194 | currentTimeInMilli = 0;
195 |
196 | // update gui
197 | musicPlayerGUI.enablePauseButtonDisablePlayButton();
198 | musicPlayerGUI.updateSongTitleAndArtist(currentSong);
199 | musicPlayerGUI.updatePlaybackSlider(currentSong);
200 |
201 | // play the song
202 | playCurrentSong();
203 | }
204 |
205 | public void playCurrentSong(){
206 | if(currentSong == null) return;
207 |
208 | try{
209 | // read mp3 audio data
210 | FileInputStream fileInputStream = new FileInputStream(currentSong.getFilePath());
211 | BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
212 |
213 | // create a new advanced player
214 | advancedPlayer = new AdvancedPlayer(bufferedInputStream);
215 | advancedPlayer.setPlayBackListener(this);
216 |
217 | // start music
218 | startMusicThread();
219 |
220 | // start playback slider thread
221 | startPlaybackSliderThread();
222 |
223 | }catch(Exception e){
224 | e.printStackTrace();
225 | }
226 | }
227 |
228 | // create a thread that will handle playing the music
229 | private void startMusicThread(){
230 | new Thread(new Runnable() {
231 | @Override
232 | public void run() {
233 | try{
234 | if(isPaused){
235 | synchronized(playSignal){
236 | // update flag
237 | isPaused = false;
238 |
239 | // notify the other thread to continue (makes sure that isPaused is updated to false properly)
240 | playSignal.notify();
241 | }
242 |
243 | // resume music from last frame
244 | advancedPlayer.play(currentFrame, Integer.MAX_VALUE);
245 | }else{
246 | // play music from the beginning
247 | advancedPlayer.play();
248 | }
249 | }catch(Exception e){
250 | e.printStackTrace();
251 | }
252 | }
253 | }).start();
254 | }
255 |
256 | // create a thread that will handle updating the slider
257 | private void startPlaybackSliderThread(){
258 | new Thread(new Runnable() {
259 | @Override
260 | public void run() {
261 | if(isPaused){
262 | try{
263 | // wait till it gets notified by other thread to continue
264 | // makes sure that isPaused boolean flag updates to false before continuing
265 | synchronized(playSignal){
266 | playSignal.wait();
267 | }
268 | }catch(Exception e){
269 | e.printStackTrace();
270 | }
271 | }
272 |
273 | while(!isPaused && !songFinished && !pressedNext && !pressedPrev){
274 | try{
275 | // increment current time milli
276 | currentTimeInMilli++;
277 |
278 | // calculate into frame value
279 | int calculatedFrame = (int) ((double) currentTimeInMilli * 2.08 * currentSong.getFrameRatePerMilliseconds());
280 |
281 | // update gui
282 | musicPlayerGUI.setPlaybackSliderValue(calculatedFrame);
283 |
284 | // mimic 1 millisecond using thread.sleep
285 | Thread.sleep(1);
286 | }catch(Exception e){
287 | e.printStackTrace();
288 | }
289 | }
290 | }
291 | }).start();
292 | }
293 |
294 | @Override
295 | public void playbackStarted(PlaybackEvent evt) {
296 | // this method gets called in the beginning of the song
297 | System.out.println("Playback Started");
298 | songFinished = false;
299 | pressedNext = false;
300 | pressedPrev = false;
301 | }
302 |
303 | @Override
304 | public void playbackFinished(PlaybackEvent evt) {
305 | // this method gets called when the song finishes or if the player gets closed
306 | System.out.println("Playback Finished");
307 | if(isPaused){
308 | currentFrame += (int) ((double) evt.getFrame() * currentSong.getFrameRatePerMilliseconds());
309 | }else{
310 | // if the user pressed next or prev we don't need to execute the rest of the code
311 | if(pressedNext || pressedPrev) return;
312 |
313 | // when the song ends
314 | songFinished = true;
315 |
316 | if(playlist == null){
317 | // update gui
318 | musicPlayerGUI.enablePlayButtonDisablePauseButton();
319 | }else{
320 | // last song in the playlist
321 | if(currentPlaylistIndex == playlist.size() - 1){
322 | // update gui
323 | musicPlayerGUI.enablePlayButtonDisablePauseButton();
324 | }else{
325 | // go to the next song in the playlist
326 | nextSong();
327 | }
328 | }
329 | }
330 | }
331 | }
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
--------------------------------------------------------------------------------
/src/MusicPlayerGUI.java:
--------------------------------------------------------------------------------
1 | import javax.imageio.ImageIO;
2 | import javax.swing.*;
3 | import javax.swing.filechooser.FileNameExtensionFilter;
4 | import java.awt.*;
5 | import java.awt.event.ActionEvent;
6 | import java.awt.event.ActionListener;
7 | import java.awt.event.MouseAdapter;
8 | import java.awt.event.MouseEvent;
9 | import java.awt.image.BufferedImage;
10 | import java.io.File;
11 | import java.util.Hashtable;
12 |
13 | public class MusicPlayerGUI extends JFrame {
14 | // color configurations
15 | public static final Color FRAME_COLOR = Color.BLACK;
16 | public static final Color TEXT_COLOR = Color.WHITE;
17 |
18 | private MusicPlayer musicPlayer;
19 |
20 | // allow us to use file explorer in our app
21 | private JFileChooser jFileChooser;
22 |
23 | private JLabel songTitle, songArtist;
24 | private JPanel playbackBtns;
25 | private JSlider playbackSlider;
26 |
27 | public MusicPlayerGUI(){
28 | // calls JFrame constructor to configure out gui and set the title heaader to "Music Player"
29 | super("Music Player");
30 |
31 | // set the width and height
32 | setSize(400, 600);
33 |
34 | // end process when app is closed
35 | setDefaultCloseOperation(EXIT_ON_CLOSE);
36 |
37 | // launch the app at the center of the screen
38 | setLocationRelativeTo(null);
39 |
40 | // prevent the app from being resized
41 | setResizable(false);
42 |
43 | // set layout to null which allows us to control the (x, y) coordinates of our components
44 | // and also set the height and width
45 | setLayout(null);
46 |
47 | // change the frame color
48 | getContentPane().setBackground(FRAME_COLOR);
49 |
50 | musicPlayer = new MusicPlayer(this);
51 | jFileChooser = new JFileChooser();
52 |
53 | // set a default path for file explorer
54 | jFileChooser.setCurrentDirectory(new File("src/assets"));
55 |
56 | // filter file chooser to only see .mp3 files
57 | jFileChooser.setFileFilter(new FileNameExtensionFilter("MP3", "mp3"));
58 |
59 | addGuiComponents();
60 | }
61 |
62 | private void addGuiComponents(){
63 | // add toolbar
64 | addToolbar();
65 |
66 | // load record image
67 | JLabel songImage = new JLabel(loadImage("src/assets/record.png"));
68 | songImage.setBounds(0, 50, getWidth() - 20, 225);
69 | add(songImage);
70 |
71 | // song title
72 | songTitle = new JLabel("Song Title");
73 | songTitle.setBounds(0, 285, getWidth() - 10, 30);
74 | songTitle.setFont(new Font("Dialog", Font.BOLD, 24));
75 | songTitle.setForeground(TEXT_COLOR);
76 | songTitle.setHorizontalAlignment(SwingConstants.CENTER);
77 | add(songTitle);
78 |
79 | // song artist
80 | songArtist = new JLabel("Artist");
81 | songArtist.setBounds(0, 315, getWidth() - 10, 30);
82 | songArtist.setFont(new Font("Dialog", Font.PLAIN, 24));
83 | songArtist.setForeground(TEXT_COLOR);
84 | songArtist.setHorizontalAlignment(SwingConstants.CENTER);
85 | add(songArtist);
86 |
87 | // playback slider
88 | playbackSlider = new JSlider(JSlider.HORIZONTAL, 0, 100, 0);
89 | playbackSlider.setBounds(getWidth()/2 - 300/2, 365, 300, 40);
90 | playbackSlider.setBackground(null);
91 | playbackSlider.addMouseListener(new MouseAdapter() {
92 | @Override
93 | public void mousePressed(MouseEvent e) {
94 | // when the user is holding the tick we want to the pause the song
95 | musicPlayer.pauseSong();
96 | }
97 |
98 | @Override
99 | public void mouseReleased(MouseEvent e) {
100 | // when the user drops the tick
101 | JSlider source = (JSlider) e.getSource();
102 |
103 | // get the frame value from where the user wants to playback to
104 | int frame = source.getValue();
105 |
106 | // update the current frame in the music player to this frame
107 | musicPlayer.setCurrentFrame(frame);
108 |
109 | // update current time in milli as well
110 | musicPlayer.setCurrentTimeInMilli((int) (frame / (2.08 * musicPlayer.getCurrentSong().getFrameRatePerMilliseconds())));
111 |
112 | // resume the song
113 | musicPlayer.playCurrentSong();
114 |
115 | // toggle on pause button and toggle off play button
116 | enablePauseButtonDisablePlayButton();
117 | }
118 | });
119 | add(playbackSlider);
120 |
121 | // playback buttons (i.e. previous, play, next)
122 | addPlaybackBtns();
123 | }
124 |
125 | private void addToolbar(){
126 | JToolBar toolBar = new JToolBar();
127 | toolBar.setBounds(0, 0, getWidth(), 20);
128 |
129 | // prevent toolbar from being moved
130 | toolBar.setFloatable(false);
131 |
132 | // add drop down menu
133 | JMenuBar menuBar = new JMenuBar();
134 | toolBar.add(menuBar);
135 |
136 | // now we will add a song menu where we will place the loading song option
137 | JMenu songMenu = new JMenu("Song");
138 | menuBar.add(songMenu);
139 |
140 | // add the "load song" item in the songMenu
141 | JMenuItem loadSong = new JMenuItem("Load Song");
142 | loadSong.addActionListener(new ActionListener() {
143 | @Override
144 | public void actionPerformed(ActionEvent e) {
145 | // an integer is returned to us to let us know what the user did
146 | int result = jFileChooser.showOpenDialog(MusicPlayerGUI.this);
147 | File selectedFile = jFileChooser.getSelectedFile();
148 |
149 | // this means that we are also checking to see if the user pressed the "open" button
150 | if(result == JFileChooser.APPROVE_OPTION && selectedFile != null){
151 | // create a song obj based on selected file
152 | Song song = new Song(selectedFile.getPath());
153 |
154 | // load song in music player
155 | musicPlayer.loadSong(song);
156 |
157 | // update song title and artist
158 | updateSongTitleAndArtist(song);
159 |
160 | // update playback slider
161 | updatePlaybackSlider(song);
162 |
163 | // toggle on pause button and toggle off play button
164 | enablePauseButtonDisablePlayButton();
165 | }
166 | }
167 | });
168 | songMenu.add(loadSong);
169 |
170 | // now we will add the playlist menu
171 | JMenu playlistMenu = new JMenu("Playlist");
172 | menuBar.add(playlistMenu);
173 |
174 | // then add the items to the playlist menu
175 | JMenuItem createPlaylist = new JMenuItem("Create Playlist");
176 | createPlaylist.addActionListener(new ActionListener() {
177 | @Override
178 | public void actionPerformed(ActionEvent e) {
179 | // load music playlist dialog
180 | new MusicPlaylistDialog(MusicPlayerGUI.this).setVisible(true);
181 | }
182 | });
183 | playlistMenu.add(createPlaylist);
184 |
185 | JMenuItem loadPlaylist = new JMenuItem("Load Playlist");
186 | loadPlaylist.addActionListener(new ActionListener() {
187 | @Override
188 | public void actionPerformed(ActionEvent e) {
189 | JFileChooser jFileChooser = new JFileChooser();
190 | jFileChooser.setFileFilter(new FileNameExtensionFilter("Playlist", "txt"));
191 | jFileChooser.setCurrentDirectory(new File("src/assets"));
192 |
193 | int result = jFileChooser.showOpenDialog(MusicPlayerGUI.this);
194 | File selectedFile = jFileChooser.getSelectedFile();
195 |
196 | if(result == JFileChooser.APPROVE_OPTION && selectedFile != null){
197 | // stop the music
198 | musicPlayer.stopSong();
199 |
200 | // load playlist
201 | musicPlayer.loadPlaylist(selectedFile);
202 | }
203 | }
204 | });
205 | playlistMenu.add(loadPlaylist);
206 |
207 | add(toolBar);
208 | }
209 |
210 | private void addPlaybackBtns(){
211 | playbackBtns = new JPanel();
212 | playbackBtns.setBounds(0, 435, getWidth() - 10, 80);
213 | playbackBtns.setBackground(null);
214 |
215 | // previous button
216 | JButton prevButton = new JButton(loadImage("src/assets/previous.png"));
217 | prevButton.setBorderPainted(false);
218 | prevButton.setBackground(null);
219 | prevButton.addActionListener(new ActionListener() {
220 | @Override
221 | public void actionPerformed(ActionEvent e) {
222 | // go to the previous song
223 | musicPlayer.prevSong();
224 | }
225 | });
226 | playbackBtns.add(prevButton);
227 |
228 | // play button
229 | JButton playButton = new JButton(loadImage("src/assets/play.png"));
230 | playButton.setBorderPainted(false);
231 | playButton.setBackground(null);
232 | playButton.addActionListener(new ActionListener() {
233 | @Override
234 | public void actionPerformed(ActionEvent e) {
235 | // toggle off play button and toggle on pause button
236 | enablePauseButtonDisablePlayButton();
237 |
238 | // play or resume song
239 | musicPlayer.playCurrentSong();
240 | }
241 | });
242 | playbackBtns.add(playButton);
243 |
244 | // pause button
245 | JButton pauseButton = new JButton(loadImage("src/assets/pause.png"));
246 | pauseButton.setBorderPainted(false);
247 | pauseButton.setBackground(null);
248 | pauseButton.setVisible(false);
249 | pauseButton.addActionListener(new ActionListener() {
250 | @Override
251 | public void actionPerformed(ActionEvent e) {
252 | // toggle off pause button and toggle on play button
253 | enablePlayButtonDisablePauseButton();
254 |
255 | // pause the song
256 | musicPlayer.pauseSong();
257 | }
258 | });
259 | playbackBtns.add(pauseButton);
260 |
261 | // next button
262 | JButton nextButton = new JButton(loadImage("src/assets/next.png"));
263 | nextButton.setBorderPainted(false);
264 | nextButton.setBackground(null);
265 | nextButton.addActionListener(new ActionListener() {
266 | @Override
267 | public void actionPerformed(ActionEvent e) {
268 | // go to the next song
269 | musicPlayer.nextSong();
270 | }
271 | });
272 | playbackBtns.add(nextButton);
273 |
274 | add(playbackBtns);
275 | }
276 |
277 | // this will be used to update our slider from the music player class
278 | public void setPlaybackSliderValue(int frame){
279 | playbackSlider.setValue(frame);
280 | }
281 |
282 | public void updateSongTitleAndArtist(Song song){
283 | songTitle.setText(song.getSongTitle());
284 | songArtist.setText(song.getSongArtist());
285 | }
286 |
287 | public void updatePlaybackSlider(Song song){
288 | // update max count for slider
289 | playbackSlider.setMaximum(song.getMp3File().getFrameCount());
290 |
291 | // create the song length label
292 | Hashtable labelTable = new Hashtable<>();
293 |
294 | // beginning will be 00:00
295 | JLabel labelBeginning = new JLabel("00:00");
296 | labelBeginning.setFont(new Font("Dialog", Font.BOLD, 18));
297 | labelBeginning.setForeground(TEXT_COLOR);
298 |
299 | // end will vary depending on the song
300 | JLabel labelEnd = new JLabel(song.getSongLength());
301 | labelEnd.setFont(new Font("Dialog", Font.BOLD, 18));
302 | labelEnd.setForeground(TEXT_COLOR);
303 |
304 | labelTable.put(0, labelBeginning);
305 | labelTable.put(song.getMp3File().getFrameCount(), labelEnd);
306 |
307 | playbackSlider.setLabelTable(labelTable);
308 | playbackSlider.setPaintLabels(true);
309 | }
310 |
311 | public void enablePauseButtonDisablePlayButton(){
312 | // retrieve reference to play button from playbackBtns panel
313 | JButton playButton = (JButton) playbackBtns.getComponent(1);
314 | JButton pauseButton = (JButton) playbackBtns.getComponent(2);
315 |
316 | // turn off play button
317 | playButton.setVisible(false);
318 | playButton.setEnabled(false);
319 |
320 | // turn on pause button
321 | pauseButton.setVisible(true);
322 | pauseButton.setEnabled(true);
323 | }
324 |
325 | public void enablePlayButtonDisablePauseButton(){
326 | // retrieve reference to play button from playbackBtns panel
327 | JButton playButton = (JButton) playbackBtns.getComponent(1);
328 | JButton pauseButton = (JButton) playbackBtns.getComponent(2);
329 |
330 | // turn on play button
331 | playButton.setVisible(true);
332 | playButton.setEnabled(true);
333 |
334 | // turn off pause button
335 | pauseButton.setVisible(false);
336 | pauseButton.setEnabled(false);
337 | }
338 |
339 | private ImageIcon loadImage(String imagePath){
340 | try{
341 | // read the image file from the given path
342 | BufferedImage image = ImageIO.read(new File(imagePath));
343 |
344 | // returns an image icon so that our component can render the image
345 | return new ImageIcon(image);
346 | }catch(Exception e){
347 | e.printStackTrace();
348 | }
349 |
350 | // could not find resource
351 | return null;
352 | }
353 | }
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
--------------------------------------------------------------------------------
/src/MusicPlaylistDialog.java:
--------------------------------------------------------------------------------
1 | import javax.swing.*;
2 | import javax.swing.filechooser.FileNameExtensionFilter;
3 | import java.awt.*;
4 | import java.awt.event.ActionEvent;
5 | import java.awt.event.ActionListener;
6 | import java.io.BufferedWriter;
7 | import java.io.File;
8 | import java.io.FileWriter;
9 | import java.util.ArrayList;
10 |
11 | public class MusicPlaylistDialog extends JDialog {
12 | private MusicPlayerGUI musicPlayerGUI;
13 |
14 | // store all of the paths to be written to a txt file (when we load a playlist)
15 | private ArrayList songPaths;
16 |
17 | public MusicPlaylistDialog(MusicPlayerGUI musicPlayerGUI){
18 | this.musicPlayerGUI = musicPlayerGUI;
19 | songPaths = new ArrayList<>();
20 |
21 | // configure dialog
22 | setTitle("Create Playlist");
23 | setSize(400, 400);
24 | setResizable(false);
25 | getContentPane().setBackground(MusicPlayerGUI.FRAME_COLOR);
26 | setLayout(null);
27 | setModal(true); // this property makes it so that the dialog has to be closed to give focus
28 | setLocationRelativeTo(musicPlayerGUI);
29 |
30 | addDialogComponents();
31 | }
32 |
33 | private void addDialogComponents(){
34 | // container to hold each song path
35 | JPanel songContainer = new JPanel();
36 | songContainer.setLayout(new BoxLayout(songContainer, BoxLayout.Y_AXIS));
37 | songContainer.setBounds((int)(getWidth() * 0.025), 10, (int)(getWidth() * 0.90), (int) (getHeight() * 0.75));
38 | add(songContainer);
39 |
40 | // add song button
41 | JButton addSongButton = new JButton("Add");
42 | addSongButton.setBounds(60, (int) (getHeight() * 0.80), 100, 25);
43 | addSongButton.setFont(new Font("Dialog", Font.BOLD, 14));
44 | addSongButton.addActionListener(new ActionListener() {
45 | @Override
46 | public void actionPerformed(ActionEvent e) {
47 | // open file explorer
48 | JFileChooser jFileChooser = new JFileChooser();
49 | jFileChooser.setFileFilter(new FileNameExtensionFilter("MP3", "mp3"));
50 | jFileChooser.setCurrentDirectory(new File("src/assets"));
51 | int result = jFileChooser.showOpenDialog(MusicPlaylistDialog.this);
52 |
53 | File selectedFile = jFileChooser.getSelectedFile();
54 | if(result == JFileChooser.APPROVE_OPTION && selectedFile != null){
55 | JLabel filePathLabel = new JLabel(selectedFile.getPath());
56 | filePathLabel.setFont(new Font("Dialog", Font.BOLD, 12));
57 | filePathLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
58 |
59 | // add to the list
60 | songPaths.add(filePathLabel.getText());
61 |
62 | // add to container
63 | songContainer.add(filePathLabel);
64 |
65 | // refreshes dialog to show newly added JLabel
66 | songContainer.revalidate();
67 | }
68 | }
69 | });
70 | add(addSongButton);
71 |
72 | // save playlist button
73 | JButton savePlaylistButton = new JButton("Save");
74 | savePlaylistButton.setBounds(215, (int) (getHeight() * 0.80), 100, 25);
75 | savePlaylistButton.setFont(new Font("Dialog", Font.BOLD, 14));
76 | savePlaylistButton.addActionListener(new ActionListener() {
77 | @Override
78 | public void actionPerformed(ActionEvent e) {
79 | try{
80 | JFileChooser jFileChooser = new JFileChooser();
81 | jFileChooser.setCurrentDirectory(new File("src/assets"));
82 | int result = jFileChooser.showSaveDialog(MusicPlaylistDialog.this);
83 |
84 | if(result == JFileChooser.APPROVE_OPTION){
85 | // we use getSelectedFile() to get reference to the file that we are about to save
86 | File selectedFile = jFileChooser.getSelectedFile();
87 |
88 | // convert to .txt file if not done so already
89 | // this will check to see if the file does not have the ".txt" file extension
90 | if(!selectedFile.getName().substring(selectedFile.getName().length() - 4).equalsIgnoreCase(".txt")){
91 | selectedFile = new File(selectedFile.getAbsoluteFile() + ".txt");
92 | }
93 |
94 | // create the new file at the destinated directory
95 | selectedFile.createNewFile();
96 |
97 | // now we will write all of the song paths into this file
98 | FileWriter fileWriter = new FileWriter(selectedFile);
99 | BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
100 |
101 | // iterate through our song paths list and write each string into the file
102 | // each song will be written in their own row
103 | for(String songPath : songPaths){
104 | bufferedWriter.write(songPath + "\n");
105 | }
106 | bufferedWriter.close();
107 |
108 | // display success dialog
109 | JOptionPane.showMessageDialog(MusicPlaylistDialog.this, "Successfully Created Playlist!");
110 |
111 | // close this dialog
112 | MusicPlaylistDialog.this.dispose();
113 | }
114 | }catch(Exception exception){
115 | exception.printStackTrace();
116 | }
117 | }
118 | });
119 | add(savePlaylistButton);
120 | }
121 | }
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/src/Song.java:
--------------------------------------------------------------------------------
1 | import com.mpatric.mp3agic.Mp3File;
2 | import org.jaudiotagger.audio.AudioFile;
3 | import org.jaudiotagger.audio.AudioFileIO;
4 | import org.jaudiotagger.tag.FieldKey;
5 | import org.jaudiotagger.tag.Tag;
6 |
7 | import java.io.File;
8 |
9 | // class used to describe a song
10 | public class Song {
11 | private String songTitle;
12 | private String songArtist;
13 | private String songLength;
14 | private String filePath;
15 | private Mp3File mp3File;
16 | private double frameRatePerMilliseconds;
17 |
18 | public Song(String filePath){
19 | this.filePath = filePath;
20 | try{
21 | mp3File = new Mp3File(filePath);
22 | frameRatePerMilliseconds = (double) mp3File.getFrameCount() / mp3File.getLengthInMilliseconds();
23 | songLength = convertToSongLengthFormat();
24 |
25 | // use the jaudiotagger library to create an audiofile obj to read mp3 file's information
26 | AudioFile audioFile = AudioFileIO.read(new File(filePath));
27 |
28 | // read through the meta data of the audio file
29 | Tag tag = audioFile.getTag();
30 | if(tag != null){
31 | songTitle = tag.getFirst(FieldKey.TITLE);
32 | songArtist = tag.getFirst(FieldKey.ARTIST);
33 | }else{
34 | // could not read through mp3 file's meta data
35 | songTitle = "N/A";
36 | songArtist = "N/A";
37 | }
38 | }catch(Exception e){
39 | e.printStackTrace();
40 | }
41 | }
42 |
43 | private String convertToSongLengthFormat(){
44 | long minutes = mp3File.getLengthInSeconds() / 60;
45 | long seconds = mp3File.getLengthInSeconds() % 60;
46 | String formattedTime = String.format("%02d:%02d", minutes, seconds);
47 |
48 | return formattedTime;
49 | }
50 |
51 | // getters
52 | public String getSongTitle() {
53 | return songTitle;
54 | }
55 |
56 | public String getSongArtist() {
57 | return songArtist;
58 | }
59 |
60 | public String getSongLength() {
61 | return songLength;
62 | }
63 |
64 | public String getFilePath() {
65 | return filePath;
66 | }
67 |
68 | public Mp3File getMp3File(){return mp3File;}
69 | public double getFrameRatePerMilliseconds(){return frameRatePerMilliseconds;}
70 | }
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/src/assets/Auld Lang Syne (Instrumental) - Jingle Punks.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/Auld Lang Syne (Instrumental) - Jingle Punks.mp3
--------------------------------------------------------------------------------
/src/assets/Tropic Fuse - French Fuse.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/Tropic Fuse - French Fuse.mp3
--------------------------------------------------------------------------------
/src/assets/Wind Riders - Asher Fulero.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/Wind Riders - Asher Fulero.mp3
--------------------------------------------------------------------------------
/src/assets/next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/next.png
--------------------------------------------------------------------------------
/src/assets/pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/pause.png
--------------------------------------------------------------------------------
/src/assets/play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/play.png
--------------------------------------------------------------------------------
/src/assets/playlist.txt:
--------------------------------------------------------------------------------
1 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Auld Lang Syne (Instrumental) - Jingle Punks.mp3
2 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Tropic Fuse - French Fuse.mp3
3 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Wind Riders - Asher Fulero.mp3
4 |
--------------------------------------------------------------------------------
/src/assets/playlist2.txt:
--------------------------------------------------------------------------------
1 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Auld Lang Syne (Instrumental) - Jingle Punks.mp3
2 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Tropic Fuse - French Fuse.mp3
3 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Wind Riders - Asher Fulero.mp3
4 |
--------------------------------------------------------------------------------
/src/assets/playlist3.txt:
--------------------------------------------------------------------------------
1 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Auld Lang Syne (Instrumental) - Jingle Punks.mp3
2 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Tropic Fuse - French Fuse.mp3
3 | D:\Programming\Youtube Videos\Java\MP3MusicPlayer\src\assets\Wind Riders - Asher Fulero.mp3
4 |
--------------------------------------------------------------------------------
/src/assets/previous.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/previous.png
--------------------------------------------------------------------------------
/src/assets/record.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/curadProgrammer/Java-Swing-MusicPlayer/c56f05f668adb7f372bd60499a6a3c00b2c7d9ae/src/assets/record.png
--------------------------------------------------------------------------------