/** Play a random http stream. */ public void playStream() throws EncoderException, LineUnavailableException, IOException, UnsupportedAudioFileException, InterruptedException { String source; SourceDataLine line; DataLine.Info info; // The source stream source = "http://mp3.streampower.be/stubru-high.mp3"; source = "http://mp3.streampower.be/klara-high.mp3"; // Set the transcoding to WAV PCM, 16bits LE, 16789Hz (to make sure resampling is done). Attributes attributes = DefaultAttributes.WAV_PCM_S16LE_STEREO_44KHZ.getAttributes(); attributes.setSamplingRate(16789); // Stream the same file with on the fly decoding: AudioInputStream streamedAudioInputStream = Streamer.stream(source, attributes); AudioFormat audioFormat = Streamer.streamAudioFormat(attributes); byte[] streamBuffer = new byte[1024]; info = new DataLine.Info(SourceDataLine.class, audioFormat); line = (SourceDataLine) AudioSystem.getLine(info); line.open(audioFormat); line.start(); while (streamedAudioInputStream.available() > streamBuffer.length) { int bytesRead = streamedAudioInputStream.read(streamBuffer); int bytesWrote = line.write(streamBuffer, 0, streamBuffer.length); assertEquals( "The number of bytes read should match the number of bytes written to the dataline", bytesRead, bytesWrote); } line.close(); streamedAudioInputStream.close(); }
/** * Streaming and transcoding the same file should yield the exact same results. To test this an * mp3 is decoded and resampled and via transcoding and via streaming. */ public void compareTranscodingAndStreaming(String source) throws EncoderException, LineUnavailableException, IOException, UnsupportedAudioFileException, InterruptedException { System.out.println("Testing: " + source); // Set the transcoding to WAV PCM, 16bits LE, 16789Hz (to make sure resampling is done). Attributes attributes = DefaultAttributes.WAV_PCM_S16LE_STEREO_44KHZ.getAttributes(); attributes.setSamplingRate(16789); // Save the transcoded file: File temporaryTranscoded = File.createTempFile("temporaryTranscoded", ".wav"); Transcoder.transcode(source, temporaryTranscoded.getAbsolutePath(), attributes); AudioInputStream transcodedAudioInputStream = AudioSystem.getAudioInputStream(temporaryTranscoded); // Stream the same file with on the fly decoding: AudioInputStream streamedAudioInputStream = Streamer.stream(source, attributes); byte[] streamBuffer = new byte[1024]; byte[] transcodedBuffer = new byte[streamBuffer.length]; int sampleCounter = 0; while (streamedAudioInputStream.available() > streamBuffer.length && transcodedAudioInputStream.available() > streamBuffer.length) { streamedAudioInputStream.read(streamBuffer); transcodedAudioInputStream.read(transcodedBuffer); for (int i = 0; i < streamBuffer.length; i++) { sampleCounter++; assertEquals( "Difference at sample: " + sampleCounter, transcodedBuffer[i], streamBuffer[i]); } } streamedAudioInputStream.close(); transcodedAudioInputStream.close(); temporaryTranscoded.delete(); }
public AudioInputStream pipe(Attributes attributes) throws EncoderException { String pipeEnvironment; String pipeArgument; File pipeLogFile; int pipeBuffer; if (System.getProperty("os.name").indexOf("indows") > 0) { pipeEnvironment = "cmd.exe"; pipeArgument = "/C"; } else { pipeEnvironment = "/bin/bash"; pipeArgument = "-c"; } pipeLogFile = new File("decoder_log.txt"); // buffer 1/4 second of audio. pipeBuffer = attributes.getSamplingRate() / 4; AudioFormat audioFormat = Encoder.getTargetAudioFormat(attributes); String command = toString(); ProcessBuilder pb = new ProcessBuilder(pipeEnvironment, pipeArgument, command); pb.redirectError(Redirect.appendTo(pipeLogFile)); LOG.fine("Starting piped decoding process"); final Process process; try { process = pb.start(); } catch (IOException e1) { throw new EncoderException("Problem starting piped sub process: " + e1.getMessage()); } InputStream stdOut = new BufferedInputStream(process.getInputStream(), pipeBuffer); // read and ignore the 46 byte wav header, only pipe the pcm samples to the audioinputstream byte[] header = new byte[46]; double sleepSeconds = 0; double timeoutLimit = 20; // seconds try { while (stdOut.available() < header.length) { try { Thread.sleep(100); sleepSeconds += 0.1; } catch (InterruptedException e) { e.printStackTrace(); } if (sleepSeconds > timeoutLimit) { throw new Error("Could not read from pipe within " + timeoutLimit + " seconds: timeout!"); } } int bytesRead = stdOut.read(header); if (bytesRead != header.length) { throw new EncoderException( "Could not read complete WAV-header from pipe. This could result in mis-aligned frames!"); } } catch (IOException e1) { throw new EncoderException("Problem reading from piped sub process: " + e1.getMessage()); } final AudioInputStream audioStream = new AudioInputStream(stdOut, audioFormat, AudioSystem.NOT_SPECIFIED); // This thread waits for the end of the subprocess. new Thread( new Runnable() { public void run() { try { process.waitFor(); LOG.fine("Finished piped decoding process"); } catch (InterruptedException e) { LOG.severe("Interrupted while waiting for sub process exit."); e.printStackTrace(); } } }, "Decoding Pipe Reader") .start(); return audioStream; }