如何从网络存储中检索音频

时间:2014-11-26 10:40:06

标签: java swing javasound jcifs

以下代码旨在从网络存储中读取音频文件并在swing应用程序中播放

代码使用java SourceDataLine和jcifs来检索音频

问题是我需要为缓冲区定义标记/重置

错误:

java.io.IOException: mark/reset not supported
    at java.io.InputStream.reset(InputStream.java:347)
    at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(SoftMidiAudioFileReader.java:135)
    at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1111)
    at SoundJCIFSLineTest.main(SoundJCIFSLineTest.java:36)
Exception in thread "main" java.lang.NullPointerException
    at SoundJCIFSLineTest.main(SoundJCIFSLineTest.java:71)

代码:

import java.io.*;
import javax.sound.sampled.*;
import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileInputStream;

public class SoundJCIFSLineTest 
{
   public static void main(String[] args) 
   {
      SourceDataLine soundLine = null;

      int BUFFER_SIZE = 64*1024;  // 64 KB

      // Set up an audio input stream piped from the sound file.
      try 
      {
         //Maked the connection fast 
         jcifs.Config.setProperty("resolveOrder", "DNS");

         String originPath="smb://192.168.1.2/server/audiofile.wav";        

         NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("", "username", "password");

         //This is the audio file the needs to be downloaded from the network storage   
         SmbFile audioFile = new SmbFile(originPath, auth);
         SmbFileInputStream smbFileInputStream = new SmbFileInputStream(audioFile);

         AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(smbFileInputStream);
         AudioFormat audioFormat = audioInputStream.getFormat();

         DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
         soundLine = (SourceDataLine) AudioSystem.getLine(info);
         soundLine.open(audioFormat);
         soundLine.start();

         int nBytesRead = 0;
         byte[] sampledData = new byte[BUFFER_SIZE];

         while (nBytesRead != -1) 
         {
            nBytesRead = audioInputStream.read(sampledData, 0, sampledData.length);
            if (nBytesRead >= 0) 
            {
               // Writes audio data to the mixer via this source data line.
               soundLine.write(sampledData, 0, nBytesRead);
            }
         }
      } 
      catch (UnsupportedAudioFileException ex) 
      {
         ex.printStackTrace();
      } 
      catch (IOException ex) 
      {
         ex.printStackTrace();
      } 
      catch (LineUnavailableException ex) 
      {
         ex.printStackTrace();
      } 
      finally 
      {
         soundLine.drain();
         soundLine.close();
      }
   }
}

2 个答案:

答案 0 :(得分:1)

我刚刚添加了BufferedInputStream,这解决了问题

BufferedInputStream buf = new BufferedInputStream(smbFileInputStream);

答案 1 :(得分:1)

如果您可以通过URL或FileName寻址您的网络文件,则可以使用不需要标记性/可重新性的getAudioInputStream形式。仅当InputStream用作输入参数时才执行此测试。如果是这样,您可以消除InputStream和BufferedInputStream步骤。

但是,我没有通过网络获取文件的经验,因此我不完全确定URL(我最常用的打开音频数据文件的方法)是否有效。看起来应该是这样。