Files
UniversalMusicPlayer/interface/src/main/java/edu/regis/universeplayer/localPlayer/Player.java
Markil3 77c0b4fa67 Added better logging and browser support.
We still need to work on the Linux browser a bit.
2021-07-25 14:09:06 -07:00

188 lines
5.4 KiB
Java

/*
* Copyright (c) 2021 William Hubbard. All Rights Reserved.
*/
package edu.regis.universeplayer.localPlayer;
import com.intervigil.wave.WaveReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
/**
* This allows for the control of playback of files on the local file system
*
* @author William Hubbard
* @version 0.1
*/
public class Player
{
private static final Logger logger = LoggerFactory.getLogger(Player.class);
static
{
System.loadLibrary("player");
}
private int currentId;
private AudioFile currentFile;
/**
* Sets the file currently being used.
*
* @param file - The current audio file.
*/
public void setCurrentFile(AudioFile file)
{
WaveReader header = file.getHeader();
this.currentFile = file;
// TODO - Ensure that bytes per sample and bits per sample don't bother things
this.currentId = this.setCurrentFile(this.currentFile, (short) header.getChannels(), (short) header
.getPcmFormat(), header.getSampleRate());
}
/**
* Updates the file currently being played.
*
* @param stream - A reference to the audio data stream.
* @param numChannels - The number of audio channels contained in the file.
* @param bitsPerSample - The number if bits in every sample.
* @param sampleRate - How many samples need to play every second.
* @return An ID for the current song.
*/
private native int setCurrentFile(InputStream stream, short numChannels, short bitsPerSample, int sampleRate);
/**
* Saves the current file to
*
* @param file - The file to save to.
*/
public native void save(String file);
/**
* Saves the current file as a WAVE file somewhere else. This method is meant for testing only.
*
* @param file - The file to save to.
*/
public void saveJava(String file)
{
try (FileOutputStream out = new FileOutputStream(file))
{
out.write(this.getAudioFile().getByteStream());
byte[] buffer = new byte[256];
int read = this.getAudioFile().read(buffer);
while (read > 0)
{
out.write(buffer, 0, read);
read = this.getAudioFile().read(buffer);
}
}
catch (IOException e)
{
logger.error("Could not save WAVE file", e);
}
}
/**
* Obtains the current file.
*
* @return The current audio file we are working with.
*/
public AudioFile getAudioFile()
{
return this.currentFile;
}
/**
* Plays the current audio file.
*/
public native void play();
/**
* Pauses playback for the current audio file.
*/
public native void pause();
/**
* Checks to see whether the current audio file is paused.
*
* @return True if there is an audio file present and it is paused, false otherwise.
*/
public native boolean isPaused();
/**
* Obtains an input stream for the requested file.
*
* @param file - The file to read
* @return An raw stream for the file
* @throws FileNotFoundException - Thrown should the file not exist.
* @throws IOException - Thrown should an error occur when reading the file
*/
public static AudioFile getAudioStream(File file) throws IOException
{
return new AudioFile(convertFile(file));
}
/**
* Converts any audio file to a stream containing WAV audio file data (courtesy of FFMPEG).
*
* @param file - The file to convert
* @return An input stream containing the file data
* @throws FileNotFoundException - Thrown should the file not exist.
* @throws IOException - Thrown should an error occur when reading the file
*/
protected static Process convertFile(File file) throws FileNotFoundException, IOException
{
LinkedList<String> args = new LinkedList<>();
if (!file.isFile())
{
throw new FileNotFoundException("Must provide a file");
}
args.add("ffmpeg");
args.add("-hide_banner");
args.add("-loglevel");
args.add("error");
args.add("-y");
args.add("-i");
args.add(file.getAbsolutePath());
args.add("-f");
args.add("wav");
args.add("pipe:1");
return Runtime.getRuntime().exec(args.toArray(new String[args.size()]));
}
public static void main(String[] args)
{
byte[] buffer = new byte[200];
int len;
File file = new File(args[0]);
try (AudioFile stream = getAudioStream(new File(args[0])))
{
Player player = new Player();
player.setCurrentFile(stream);
player.save(args[0] + ".wav");
}
catch (IOException e)
{
logger.error("Could not save audio file " + file, e);
}
// Compare JNI vs Java
try (AudioFile stream = getAudioStream(new File(args[0])))
{
Player player = new Player();
player.setCurrentFile(stream);
player.saveJava(args[0] + ".orig.wav");
}
catch (IOException e)
{
logger.error("Could not save audio file " + file, e);
}
}
}