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: | 1177 / 1741 |
| Referenced in: | [show references] |