|
15.07.2017, 20:11
#39489588
Ссылка:
Ссылка на сообщение:
Ссылка с названием темы:
|
|
|
|
Есть проблема с воспроизведением звука. Работаю в IDEA, там всё нормально играет. Если запущу в скомпиленом `jar` файле то не играет ничего. Подскажите почему? Сам файл находится у меня на рабочем столе, не в jar файле.
использую java Layev и mp3spi
Спасибо.
Код:
Music.java:
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. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253. 254. 255. 256. 257. 258. 259. 260. 261. 262. 263. 264. 265. 266. 267. 268. 269. 270. 271. 272. 273. 274. 275. 276. 277. 278. 279. 280. 281. 282. 283. 284. 285. 286. 287. 288. 289. 290. 291. 292. 293. 294. 295. 296. 297. 298. 299. 300. 301. 302. 303. 304. 305. 306. 307. 308. 309. 310. 311. 312. 313. 314. 315. 316. 317. 318. 319. 320. 321. 322. 323. 324. 325. 326. 327. 328. 329. 330. 331. 332.
import com.tsyklop.area.Area;
import org.apache.log4j.Logger;
import java.io.File;
import java.io.InputStream;
import javax.sound.sampled.*;
/**
* @author Connor Mahaffey
* <p>
* This class is a rewrite of the example from: http://www.javazoom.net/mp3spi/documents.html
* <p>
* This class needs the following libraries:
* JLayer - http://www.javazoom.net/javalayer/javalayer.html
* MP3 SPI - http://www.javazoom.net/mp3spi/mp3spi.html
* Tritonus Share (tritonus_share-0.3.6.jar) - http://www.tritonus.org/plugins.html
* <p>
* All credit goes to the creators of JLayer, MP3 SPI, and Tritonus.
* <p>
* This simple re-write adds loop, mute, pause, restart, and stop methods to the example mentioned above.
* <p>
* This code is completely free to use for any purpose whatsoever. JLayer, MP3 SPI, and Tritonus are
* all released under the LGPL.
* <p>
* <p>
* Known Issues:
* <p>
* - Though using .stop() and then .play() *technically* works for restarting the audio, doing this too fast
* causes problems because the old audio stream is never stopped (writing to the audio line takes a bit,
* and it can't be stopped once it's started).
* - Distorted audio (rarely? Problem with code or with audio APIs?)
* - General Efficiency
*/
public class Music implements Runnable {
private File FILE;
private boolean RUNNING, mute, pause, loop, restart, reduce;
private final int byteChunkSize = 1024;//number of bytes to read at one time
private byte[] muteData;
private static Logger LOGGER=Logger.getLogger(Music.class);
private FloatControl gainControl;
/**
* Declares default variable values.
*/
public Music() {
FILE = null;
RUNNING = false;
mute = false;
pause = false;
loop = false;
restart = false;
reduce = false;
muteData = setMuteData();
}
/**
* Creates a FILE object. If the FILE path exists on the system, the given FILE is an mp3, and
* a song is not currently playing in this instance of the program, true is returned.
*
* @param file Path to the FILE.
* @return If the FILE is loaded or not.
*/
public boolean loadFile(File file) {
FILE = file;
if (FILE.exists() && FILE.getName().toLowerCase().endsWith(".mp3") && !RUNNING) {
return true;
} else {
FILE = null;
return false;
}
}
/**
* Starts playing the audio in a new thread.
*/
public void play() {
if (FILE != null && !RUNNING) {
RUNNING = true;
try {
Thread t = new Thread(this);
t.start();
} catch (Exception e) {
System.err.println("Could not start new thread for audio!");
e.printStackTrace();
}
}
}
/**
* Pauses the audio at its current place. Calling this method once pauses the audio stream, calling it
* again unpauses the audio stream.
*/
public void pause() {
if (FILE != null) {
if (pause) {
pause = false;
} else {
pause = true;
}
}
}
/**
* Closes the audio stream. This method takes some time to execute, and as such you should never call
* .stop() followed immediately by .play(). If you need to restart a song, use .restart().
*/
public void stop() {
if (FILE != null) {
RUNNING = false;
}
}
/**
* Stream continues to play, but no sound is heard. Calling this method once mutes the audio stream,
* calling it again unmutes the audio stream.
*/
public void mute() {
if (FILE != null) {
if (mute) {
mute = false;
} else {
mute = true;
}
}
}
public void reduce() {
if (FILE != null) {
reduce = !reduce;
}
}
/**
* Makes a given audio FILE loop back to the beginning when the end is reached. Calling this method once
* will make it loop, calling it again will make it stop looping, but will not stop the audio from playing
* to the end of a given loop.
*/
public void loop() {
if (FILE != null) {
if (loop) {
loop = false;
} else {
loop = true;
}
}
}
/**
* Restarts the current song. Always use this method to restart a song and never .stop() followed
* by .play(), which is not safe.
*/
public void restart() {
restart = true;
}
/**
* Returns whether or not a clip will loop when it reaches the end.
*
* @return Status of the variable loop.
*/
public boolean isLooping() {
return loop;
}
/**
* Returns if the audio is muted or not.
*
* @return Status of mute variable.
*/
public boolean isMuted() {
return mute;
}
/**
* Returns if the audio is paused or not.
*
* @return Status of pause variable.
*/
public boolean isPaused() {
return pause;
}
/**
* Returns if audio is currently playing (if the audio is muted, this will still be true).
*
* @return If the thread is RUNNING or not.
*/
public boolean isPlaying() {
return RUNNING;
}
/**
* Returns if a FILE is loaded or not.
*
* @return File status of null or a FILE.
*/
public boolean isLoaded() {
if (FILE == null) {
return false;
} else {
return true;
}
}
/**
* Retrieves the audio stream information and starts the stream. When the stream ends, this method
* checks to see if it should loop and start again.
*/
public void run() {
try {
do {
restart = false;
LOGGER.info("Audio file - "+FILE);
AudioInputStream in = AudioSystem.getAudioInputStream(FILE);
AudioInputStream din = null;
AudioFormat baseFormat = in.getFormat();
AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
baseFormat.getSampleRate(),
16,
baseFormat.getChannels(),
baseFormat.getChannels() * 2,
baseFormat.getSampleRate(),
false);
din = AudioSystem.getAudioInputStream(decodedFormat, in);
stream(decodedFormat, din);
in.close();
} while ((loop || restart) && RUNNING);
RUNNING = false;
} catch (Exception e) {
System.err.println("Problem getting audio stream!");
e.printStackTrace();
}
}
/**
* Small sections of audio bytes are read off, watching for a call to stop, pause, restart, or mute the audio.
*
* @param targetFormat Format the audio will be changed to.
* @param din The audio stream.
*/
private void stream(AudioFormat targetFormat, AudioInputStream din) {
try {
byte[] data = new byte[byteChunkSize];
SourceDataLine line = getLine(targetFormat);
if (line != null) {
gainControl = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
line.start();
int nBytesRead = 0;
while (nBytesRead != -1 && RUNNING && !restart) {
nBytesRead = din.read(data, 0, data.length);
if (nBytesRead != -1) {
if (mute) {
line.write(muteData, 0, nBytesRead);
} else {
line.write(data, 0, nBytesRead);
}
}
if(reduce) {
gainControl.setValue(-3); // Reduce volume by 10 decibels.
} else {
gainControl.setValue(6); // Reduce volume by 10 decibels.
}
while (pause && RUNNING) {
wait(15);
}
}
line.drain();
line.stop();
line.close();
din.close();
}
} catch (Exception e) {
System.err.println("Problem playing audio!");
e.printStackTrace();
}
}
/**
* Gets the line of audio.
*
* @param audioFormat The format of the audio.
* @return The line of audio.
*/
private SourceDataLine getLine(AudioFormat audioFormat) {
SourceDataLine res = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
try {
res = (SourceDataLine) AudioSystem.getLine(info);
res.open(audioFormat);
res.drain();
} catch (Exception e) {
System.err.println("Could not get audio line!");
e.printStackTrace();
}
return res;
}
/**
* Waits a specified number of milliseconds.
*
* @param time Time to wait (in milliseconds).
*/
private void wait(int time) {
try {
Thread.sleep(time);
} catch (Exception e) {
System.err.println("Could not wait!");
e.printStackTrace();
}
}
/**
* Sets a byte array of all zeros to "play" when audio is muted. This produces no sound.
*
* @return Byte array of all zeros.
*/
private byte[] setMuteData() {
byte[] x = new byte[byteChunkSize];
for (int i = 0; i < x.length; i++) {
x[i] = 0;
}
return x;
}
}
JavaMusicExample.java:
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. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111.
import java.io.File;
import java.util.Scanner;
/**
* @author Connor Mahaffey
*/
public class JavaMusicExample {
/**
* See the Music Class for details.
* <p>
* This is a simple program to show off the capabilities of the Music class.
*
* @param args the command line arguments
*/
public static void main(String[] args) {
String input;
String filePath = "C:\\Users\\Tsyklop\\Desktop\\media\\51.mp3";
Scanner in = new Scanner(System.in);
Music MU = new Music();
if (filePath == null) {
System.out.println("No path to a .mp3 in arguements.");
loadMP3(MU);
} else {
if (!MU.loadFile(new File(filePath))) {
System.err.println("Invalid path!");
loadMP3(MU);
}
}
do {
System.out.println("1. Play");
System.out.println("2. Pause");
System.out.println("3. Mute");
System.out.println("4. Restart");
System.out.println("5. Stop");
System.out.println("6. Load");
System.out.println("7. Loop");
System.out.println("8. Reduce");
System.out.println("9. Exit");
System.out.print("> ");
input = in.nextLine();
if (input.equals("1")) {
MU.play();
} else if (input.equals("2")) {
MU.pause();
} else if (input.equals("3")) {
MU.mute();
} else if (input.equals("4")) {
MU.restart();
} else if (input.equals("5")) {
MU.stop();
} else if (input.equals("6")) {
MU.stop();
loadMP3(MU);
} else if (input.equals("7")) {
MU.loop();
} else if (input.equals("8")) {
MU.reduce();
} else if (input.equals("9")) {
MU.stop();
} else {
System.err.println("Invalid entry.");
}
} while (!input.equals("9"));
System.exit(0);
}
/**
* Gets a file path from the program's arguements.
*
* @param args Arguements.
* @return The path.
*/
private static String getPathFromArgs(String[] args) {
String s = null;
try {
s = args[0];
} catch (Exception e) {
//no arguements
}
return s;
}
/**
* Gets user command-line input and tries to load a MP3 from the path given.
*
* @param MU Music Object Reference
*/
private static void loadMP3(Music MU) {
boolean validPath;
String filePath;
Scanner in = new Scanner(System.in);
do {
System.out.print("Path to .mp3: ");
filePath = in.nextLine();
validPath = MU.loadFile(new File(filePath));
if (!validPath) {
System.out.println("Invalid path!");
}
} while (!validPath);
}
}
|
|
|