Uses 885K of libraries. Click here for Pure Java version (3253L/22K/78K).
1 | !759 |
2 | |
3 | static int songDuration, seekValue; |
4 | static long songBytes; |
5 | static int position; |
6 | static File mp3; |
7 | static BasicPlayer player; |
8 | static Int seekTo; |
9 | |
10 | static JFrame frame; |
11 | static new JSlider seeker; |
12 | static new JLabel text; |
13 | static new JTable table; |
14 | static new JTable lastPlayed; |
15 | static L<File> tableData, lastPlayedData; |
16 | |
17 | p-awt { |
18 | substanceLAF("Moderate"); |
19 | |
20 | // Fixing the classpath for Java Sound (MP3 + OGG) |
21 | fixContextClassLoader(); |
22 | |
23 | thread "Searching Music..." { |
24 | updateLastPlayed(); |
25 | tableData = findMusicFiles(); |
26 | dataToTable_uneditable(table, musicFilesTable(tableData)); |
27 | } |
28 | |
29 | onDoubleClick(table, voidfunc(int row) { |
30 | play(tableData.get(row)); |
31 | }); |
32 | |
33 | onDoubleClick(lastPlayed, voidfunc(int row) { |
34 | play(lastPlayedData.get(row)); |
35 | }); |
36 | |
37 | // init seeker |
38 | seeker.setMajorTickSpacing(10000); // 10 seconds |
39 | seeker.setMinorTickSpacing(10000); // 10 seconds |
40 | seeker.setPaintTicks(true); |
41 | seeker.setMaximum(1); |
42 | seeker.setValue(0); |
43 | seeker.setEnabled(false); |
44 | seeker.addChangeListener(new ChangeListener { |
45 | public void stateChanged(ChangeEvent e) { |
46 | bool adjusting = seeker.getValueIsAdjusting(); |
47 | if (adjusting) |
48 | seekTo = seeker.getValue(); |
49 | else if (seekTo != null) { |
50 | seek(seekTo); |
51 | seekTo = null; |
52 | } |
53 | } |
54 | }); |
55 | |
56 | frame = showFrame( |
57 | centerAndNorth(jtabs( |
58 | "Library", table, |
59 | "Last played", lastPlayed), |
60 | centerAndSouth( |
61 | centerAndEast(seeker, text), |
62 | hgrid(jbutton("play again", "playAgain")) |
63 | ))); |
64 | frame.pack(); |
65 | setFrameIconLater(frame, "#1003635"); |
66 | setFrameWidth(frame, 500); |
67 | exitOnFrameClose(frame); // To immediately stop playback |
68 | hideConsole(); |
69 | |
70 | player = makeBasicMP3Player(); |
71 | |
72 | player.addBasicPlayerListener(new BasicPlayerListener { |
73 | public void opened(Object stream, Map properties) { |
74 | for (Object key : properties.keySet()) |
75 | print("opened: " + key + "=" + properties.get(key)); |
76 | |
77 | // Try to find duration of song |
78 | final Number bytes = (Number) properties.get("audio.length.bytes"); |
79 | long microseconds = 0; |
80 | O duration = properties.get("duration"); |
81 | |
82 | if (duration instanceof Number) |
83 | microseconds = ((Number) duration).longValue(); |
84 | else pcall { |
85 | long frames = asLong(properties.get("audio.length.frames")); |
86 | long fps = asLong(properties.get("audio.framerate.fps")); |
87 | microseconds = frames*1000000/fps; |
88 | } |
89 | |
90 | final long _microseconds = microseconds; |
91 | |
92 | awt { |
93 | songDuration = (int) (_microseconds / 1000); |
94 | seeker.setMaximum(songDuration); |
95 | seeker.setEnabled(true); |
96 | seeker.setMajorTickSpacing(10000); // 10 seconds |
97 | updateText(); |
98 | songBytes = bytes.longValue(); |
99 | } |
100 | } |
101 | |
102 | public void progress(int bytesread, final long microseconds, byte[] pcmdata, Map properties) { |
103 | awt { |
104 | if (!seeker.getValueIsAdjusting()) { |
105 | int ms = (int) (microseconds / 1000) + seekValue; |
106 | seeker.setValue(ms); |
107 | position = ms; |
108 | updateText(); |
109 | } |
110 | } |
111 | } |
112 | |
113 | public void stateUpdated(BasicPlayerEvent event) { |
114 | awt { |
115 | updateStateStuff(); |
116 | } |
117 | } |
118 | |
119 | public void setController(BasicController controller) {} |
120 | }); |
121 | } |
122 | |
123 | svoid play(File f) { |
124 | if (f == null) ret; |
125 | mp3 = f; |
126 | setFrameTitle(frame, f.getName() + " - " + getProgramTitle()); |
127 | logStructure("player.log", litlist(now(), "Playing", f.getAbsolutePath())); |
128 | play(); |
129 | updateLastPlayed(); |
130 | } |
131 | |
132 | svoid playAgain { |
133 | logStructure("player.log", litlist(now(), "Playing again")); |
134 | play(); |
135 | } |
136 | |
137 | svoid play() ctex { |
138 | seekValue = 0; |
139 | player.open(mp3); |
140 | player.play(); |
141 | } |
142 | |
143 | svoid updateStateStuff {} |
144 | |
145 | svoid updateText { |
146 | text.setText(formatMinuteAndSeconds(position/1000) + " / " + formatMinuteAndSeconds(songDuration/1000)); |
147 | } |
148 | |
149 | svoid seek(int milliseconds) { |
150 | if (mp3 == null) ret; |
151 | long bytes = (long) (milliseconds*((double) songBytes)/songDuration); |
152 | print("ms=" + milliseconds + ", songBytes=" + songBytes + ", duration=" + songDuration + ", bytes=" + bytes); |
153 | |
154 | pcall { |
155 | seekValue = milliseconds; |
156 | player.open(mp3); |
157 | player.seek(bytes); |
158 | player.play(); |
159 | } |
160 | } |
161 | |
162 | static L<File> findLastPlayed() { |
163 | new L<File> l; |
164 | new Set<S> seen; |
165 | for (S s : reversedList(scanLog("player.log"))) pcall { |
166 | L line = unstructureList(s); |
167 | if (eq(get(line, 1), "Playing")) { |
168 | S file = getString(line, 2); |
169 | if (seen.add(file)) |
170 | l.add(new File(file)); |
171 | } |
172 | } |
173 | ret l; |
174 | } |
175 | |
176 | static void updateLastPlayed() { |
177 | dataToTable_uneditable(lastPlayed, musicFilesTable(lastPlayedData = findLastPlayed())); |
178 | } |
Began life as a copy of #1003617
download show line numbers debug dex old transpilations
Travelled to 16 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, ddnzoavkxhuk, etmzoiygucik, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1003634 |
Snippet name: | Music Player v2 |
Eternal ID of this version: | #1003634/1 |
Text MD5: | 14d0247d0c471ba213e4c2e5188583e1 |
Transpilation MD5: | 5467fc92c2d9e5fbef1c14fe347de555 |
Author: | stefan |
Category: | javax |
Type: | JavaX source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-07-25 22:16:25 |
Source code size: | 4804 bytes / 178 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 908 / 1418 |
Referenced in: | [show references] |