How to play a wav file using Java? - java

I would like to play a wav file and after I googled it I found this script but it doesn't work.
(It didn't throw any exceptions nor have compiling problems)
import java.io.File;
import films.Film;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
public class MusicStorage {
/**
* Opens a wav file and plays it
* #param args
*/
public void play(Film song) {
try {
Clip sound = AudioSystem.getClip();
sound.open(AudioSystem.getAudioInputStream(new File(song.getClip())));
sound.start();
while (sound.isRunning())
Thread.sleep(1000);
sound.close();
} catch (Exception e) {
System.out.println("Whatever" + e);
}
}
}
import audio.MusicStorage;
import films.Film;
public class Aplication {
private static Film gladiator = new Film("Gladiator", "gladiator.wav");
private static MusicStorage storage = new MusicStorage();
public static void main(String[] args) {
storage.play(gladiator);
}
}
public class Film {
private String name;
private String clip;
public Film(String name, String clip) {
this.name = name;
this.clip = clip;
}
public String getClip() {
return clip;
}
public String getName() {
return name;
}
}
I have added all the code that I have so I hope it would be clear to solve my problem

Just remove the while loop from your code and it should be fixed. The while loop is making the thread sleep so it can't play the audio file.
public void play(Film song) {
try {
Clip sound = AudioSystem.getClip();
sound.open(AudioSystem.getAudioInputStream(new File(song.getClip())));
sound.start();
} catch (Exception e) {
System.out.println("Whatever" + e);
}
}
}

Related

Minecraft plugin hanging on "Enabling plugin" and producing out of memory errors

Why would this code be having memory issues? It runs fine once, and then when I try to run it again it hangs on "Enabling plugin". It'll then give me an OutOfMemoryException such as
"Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Worker-Main-10""
The code I am using is as follows from the Spigot API
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Bat;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.UUID;
public class COVID19 extends JavaPlugin {
private static ArrayList<CovidInfection> infections;
#Override
public void onEnable() {
infections = new ArrayList<CovidInfection>();
System.out.println("1");
try {
readInfections();
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
System.out.println("2");
this.getCommand("getInfected").setExecutor(new CommandGetInfected());
BukkitScheduler scheduler = getServer().getScheduler();
scheduler.scheduleSyncRepeatingTask(this, new Runnable() {
#Override
public void run() {
batCovid();
}
}, 0, 10);
System.out.println(4);
}
#Override
public void onDisable() {
try {
writeInfections();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
public void batCovid() {
System.out.println(3);
for(Player player : Bukkit.getOnlinePlayers()) {
for(Entity nearby : player.getNearbyEntities(6, 6, 6)) {
if (nearby instanceof Bat) {
String name = player.getName();
UUID uuid = player.getUniqueId();
infections.add(new CovidInfection(uuid, name, 14));
}
}
}
}
public void readInfections() throws FileNotFoundException {
File file = new File("infected.txt");
if(file.length() == 0) {
return;
}
Scanner input = new Scanner(file);
String line = input.nextLine();
while (!(line.equals(""))) {
infections.add(parseInfectionLine(line));
}
input.close();
}
public void writeInfections() throws IOException {
//File will be written as UUID,Name,DaysRemaining
FileWriter writer = new FileWriter("infected.txt", false);
for(CovidInfection infection : infections) {
writer.write(infection.toString());
}
writer.close();
}
private CovidInfection parseInfectionLine(String line) {
String[] words = line.replace("\n","").split(",");
return new CovidInfection(UUID.fromString(words[0]), words[1], Integer.parseInt(words[2]));
}
public static String getInfected() {
String compiled = "";
for (CovidInfection infection : infections) {
compiled += infection.toString() + "\n";
}
return compiled;
}
}
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class CommandGetInfected implements CommandExecutor {
#Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
String message = COVID19.getInfected();
if(!(message.equals(""))) {
sender.sendMessage(message);
} else {
sender.sendMessage("There are no infected!");
}
return(true);
}
}
import java.util.UUID;
public class CovidInfection {
private UUID uuid;
private String name;
private int days;
public CovidInfection(UUID uuid, String name, int days) {
this.uuid = uuid;
this.name = name;
this.days = days;
}
public int getDays() {
return days;
}
public String getName() {
return name;
}
public UUID getUuid() {
return uuid;
}
public void newDay() {
days--;
}
public String toString() {
return uuid.toString() + "," + name + "," + days + "\n";
}
}
Any help would be greatly appreciated, thank you!
Firstly, you are make I/O request on main thread.
To fix this issue, use multithreading such as explained here or here
Then, this :
Scanner input = new Scanner(file);
String line = input.nextLine();
Can't be used in a server.
An input like that already exist, it's the console sender.
To do that, I suggest you to use ServerCommandEvent and use spigot's console.

Cannot read file from abstract class

I am trying to make a base file plugin which other threads will inherit. But I am stuck at a point where the file exists and can be read from a normal thread but when I try to read that file from an abstract Base file, it says File not found. Here's my base class :-
package com.evol.fp;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public abstract class BaseFilePlugin extends Thread implements BaseFileReader{
String filename = "";
File file = null;
boolean fileStarted = false;
boolean fileEnded = false;
public BaseFilePlugin() {
file = new File(filename);
}
public void readFile() {
BufferedReader br = null;
System.out.println("Base call: " + filename);
try {
System.out.println("inbside ");
br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
if(br.readLine().trim().isEmpty()) {
endFile();
return;
} else {
startFile(filename);
String record;
while((record = br.readLine().trim()) != null) {
parseRecord(record);
}
endFile();
}
} catch(Exception ioe) {
ioe.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public abstract void parseRecord(String record);
public void startFile(String filename) {
this.fileStarted = true;
this.fileEnded = false;
}
public void endFile() {
file.delete();
this.fileEnded = true;
this.fileStarted = false;
}
public void run() {
while(true) {
System.out.println("Inside run, fileName: " + filename);
System.out.println("Filestarted: " + fileStarted + ", file exists: " + file.exists());
if(!fileStarted) {
readFile();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* #return the filename
*/
public String getFilename() {
return filename;
}
/**
* #param filename the filename to set
*/
public void setFilename(String filename) {
this.filename = filename;
}
}
I am aware of multithreading but never implemented with base class to parse records from a file, if someone tells me what's the problem that will be great. I know that the file exists for sure. Here's my child class: -
package com.evol.fp;
public class FileReaderThread extends BaseFilePlugin {
public FileReaderThread() {
super.setFilename("E:\\soham\\soham.txt");
}
#Override
public void parseRecord(String record) {
System.out.println(record);
}
}
But its not calling the child's parseRecord method, using a simple main method:-
package com.evol.fp;
public class StartProcess {
public static void main(String[] args) {
FileReaderThread thd = new FileReaderThread();
thd.start();
}
}
I think it's because the parent constructor (BaseFilePlugin.class) is called first before you set your filename in super.setFile("E:\\soham\\soham.txt");
If you can remove the parent constructor instead and replace your setFileName into setFile where file is iniatilize .e.g
// public BaseFilePlugin() {
// file = new File(filename);
// }
....
....
/**
* #return the file
*/
public String getFile() {
return file
}
/**
* #param file the file to set
*/
public void setFile(String file) {
file = new File(file);
}
and in your subclass
public FileReaderThread() {
super.setFile("E:\\soham\\soham.txt");
}
BaseFilePlugin's constructor creates its file with an empty string since initially String filename = "";.
The client calls setFilename(...) which updates filename. However, file is still the same instance when the object was first created (which is using an empty string as the file name).
I would suggest to pass the file name as part of the constructor so file is properly initialized:
public BaseFilePlugin(String filename) {
this.filename = filename;
file = new File(filename);
}
Optionally, if it makes sense that an instance can read only 1 file, then make those class attributes final, and remove the setFilename() method.

Better way of resetting java AudioStream

As of now, i am using AudioPlayer to create sound effects for my game, and I am struggling to find an easy way to reset the audio before I begin playing it again. As of now I am just reloading the AudioStream entirely, heres my code, any suggestions are welcome.
package resources;
import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import javax.sound.sampled.Clip;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
public class Audio {
private static HashMap<String, AudioStream> sounds = new HashMap<String, AudioStream>();
private static HashMap<String, Long> times = new HashMap<String, Long>();
Clip c;
public static AudioStream getAudio(String s){
if(sounds.containsKey(s))
return sounds.get(s);
return null;
}
public static void loadAllAudio(){
File f = new File("res/sounds");
String[] files = f.list();
for(String s:files){
if(s.endsWith(".wav")){
loadAudio(s);
System.out.println("Loaded Audio: "+s);
}
}
}
public static double getSoundLength(String sound){
return getAudio(sound).getLength()/192000.0;
}
public static void playSound(String name){
resetSound(name);
times.put(name, System.nanoTime());
AudioPlayer.player.start(sounds.get(name));
}
public static void resetSound(String name){
loadAudio(name);
}
public static void stopSound(String sound){
AudioPlayer.player.stop(sounds.get(sound));
times.put(sound, System.nanoTime());
}
private static void loadAudio(String name){
try {
File f = new File("res/sounds/"+name);
sounds.put(name, new AudioStream(new FileInputStream(f)));
times.put(name, 0L);
} catch (Exception e) {}
}
public static double getTime(String sound) {
long time = times.get(sound);
if(time==0)
return 0;
return (System.nanoTime()-time)/1E9;
}
}
The line I would like to replace is:
public static void playSound(String name){
---------resetSound(name);--------- THIS LINE
times.put(name, System.nanoTime());
AudioPlayer.player.start(sounds.get(name));
}
You can use JLayer which supports .mp3
An example how to play sound with JLayer:
new Thread(()->{
try {
FileInputStream file = new FileInputStream("path ..../audio.mp3"); //initialize the FileInputStream
Player player= new Player(file); //initialize the player
player.play(); //start the player
} catch (Exception e) {
e.printStackTrace();
}
}).start();
Note:
Note that i am using a separate Thread cause if not the App will stack.

Sounds won't play in java.. JFrame and Canvas not Applet

I'm currently working on my first game in java and i'm trying to implement sounds when the spaceship is getting hit.. this is my code . I get a null pointer exception but my sound is in the right place "workspace/project/src/sounds/"
public class GameSounds
{
public static synchronized void hit()
{
try
{
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(GameSounds.class.getResourceAsStream("sounds/8bit_bomb_explosion.wav"));
clip.open(inputStream);
clip.start();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
here is the stacktrace
java.lang.NullPointerException
at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source)
at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
at sound.GameSounds.hit(GameSounds.java:16)
at main.Main.doLogic(Main.java:135)
at main.Main.run(Main.java:101)
at java.lang.Thread.run(Unknown Source)
package sound;
import java.io.InputStream;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
public class GameSounds
{
public static synchronized void hit()
{
try
{
String resPath = "/sounds/8bit_bomb_explosion.wav"; // *** this is the key ***
InputStream audioInStream = GameSounds.class.getResourceAsStream(resPath);
System.out.println("is audioInStream null?: " + (audioInStream == null)); // test it!
AudioInputStream inputStream = AudioSystem.getAudioInputStream(audioInStream); Clip clip = AudioSystem.getClip();
clip.open(inputStream);
clip.start();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
thanks for advices now it works
In all likelihood, you are not getting the resource with the correct path. Understand that resource paths are based on where the class loader looks to load class files and not on where the src or "user.dir" directory is.
Perhaps you want to do:
// almost always better to break up a long code line into smaller lines.
String resPath = "/sounds/8bit_bomb_explosion.wav"; // *** this is the key ***
InputStream audioInStream = GameSounds.class.getResourceAsStream(resPath);
System.out.println("is audioInStream null?: " + (audioInStream == null)); // test it!
AudioInputStream inputStream = AudioSystem.getAudioInputStream(audioInStream);
Again the path String will depend on where your class files are located in relation to your src directory.
I have had the same problems. But after searching for hours I found Javazoom which is a external libery you can import into your project and makes it much more easy to play sounds:
http://www.javazoom.net/index.shtml
You can use it like this:
import javazoom.jl.player.advanced.*;
class SoundJLayer extends PlaybackListener implements Runnable
{
private String filePath;
private AdvancedPlayer player;
private Thread playerThread;
public SoundJLayer(String filePath)
{
this.filePath = filePath;
}
public void play()
{
try
{
String urlAsString =
"file:///"
+ new java.io.File(".").getCanonicalPath()
+ "/"
+ this.filePath;
this.player = new AdvancedPlayer
(
new java.net.URL(urlAsString).openStream(),
javazoom.jl.player.FactoryRegistry.systemRegistry().createAudioDevice()
);
this.player.setPlayBackListener(this);
this.playerThread = new Thread(this, "AudioPlayerThread");
this.playerThread.start();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
public void stop() {
player.stop();
}
// PlaybackListener members
public void playbackStarted(PlaybackEvent playbackEvent)
{
}
public void playbackFinished(PlaybackEvent playbackEvent)
{
}
// Runnable members
public void run()
{
try
{
this.player.play();
}
catch (javazoom.jl.decoder.JavaLayerException ex)
{
ex.printStackTrace();
}
}
}
After that you just have to create a new SoundJLayer-Object and start ir with play()
Hope this is helpful,
Jan

Android External File Inconsistently Appearing

I'm using an IntentService to append single NMEA strings to a log file stored in the external public storage on an Android device, but I'm getting inconsistent behavior.
First off the log file does not appear when the device is connected for USB debugging. I read that many Android devices cannot write to external storage when connected via USB, but even when it is run disconnected from USB, it may take several times of turning it on and off and rerunning the applications before the log file appears in the file system. If I do not clear the log, I still have to restart the phone before it will begin appending to the file again.
How can I get the file to appear consistently everytime?
import android.app.IntentService;
import android.content.Intent;
public class LogFileService extends IntentService {
DebugLog debug = new DebugLog("LogFileService");
public static final String GPS_STR = "GPS_STR";
public static final String FILE_PATH = "FILE_PATH";
public static final String FILE_NAME = "gps_data.txt";
public LogFileService() {
super("LogFileService");
}
#Override
protected void onHandleIntent(Intent intent) {
debug.log("Handling intent");
String data = intent.getStringExtra(GPS_STR);
debug.log("Writing " + data);
GpsLogFile logFile = new GpsLogFile(FILE_NAME);
logFile.open();
logFile.write(data);
logFile.close();
}
#Override
public void onCreate() {
super.onCreate();
debug.log("Created");
}
}
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import android.content.Context;
import android.os.Environment;
public class GpsLogFile {
DebugLog debug = new DebugLog("LogFile");
private File filePath = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS
);
private File logFile = null;
private String fileName = null;
private PrintWriter fileOut = null;
public GpsLogFile(String name) {
fileName = name;
}
public void open() {
try {
filePath.mkdirs();
if (!isExternalMediaAvailable()) {
throw new IOException("External media not available.");
}
logFile = new File(filePath, fileName);
//logFile.mkdirs();
if (!logFile.exists()) {
logFile.createNewFile();
}
fileOut = new PrintWriter(
new FileOutputStream(logFile.getAbsolutePath(), true)
);
} catch (IOException e) {
debug.log("Unable to open file.");
debug.log(e.getMessage());
}
}
public void write(String data) {
debug.log("Writing to " + logFile.getAbsolutePath() + " " + data);
try {
fileOut.write(data);
//fileOut.newLine();
checkPrintWriterError(fileOut);
fileOut.flush();
} catch (IOException e) {
debug.log("Unable to write");
debug.log(e.getMessage());
}
}
public void close() {
if (null != fileOut) {
try {
fileOut.close();
checkPrintWriterError(fileOut);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void checkPrintWriterError(PrintWriter writer) throws IOException {
if (true == writer.checkError()) {
throw new IOException("Print writer error.");
}
}
}

Categories

Resources