2013-07-18 84 views
5

我有一个流式传输网址在我的应用程序流,我也记录相同的文件也可以离线听。我可以在媒体播放器和服务的帮助下流式传输URL,但现在我正在寻找同一个文件的记录逻辑。如何录制和保存为MP3在线流媒体音频

如何记录实时流并将文件保存到SD卡上?

+0

在http://stackoverflow.com/questions/6959930/android-need-to-record-mic可能回答-input – tuxnani

+5

And http://stackoverflow.com/questions/5381969/android-how-to-record-mp3-radio-audio-stream – tuxnani

回答

0

如果你正在处理的音频数据,那么用它代替MediaRecorderAudioRecord类。

有一个在线示例代码,您可以下载并测试您的应用程序。

如前所述,

的这篇文章记录音频的示例应用程序并将其保存到 的SD卡。该文件将为WAV文件,并将以文件名 的名称与当前毫秒放置在 “/ SDCard/AudioRecorder”文件夹中。

检查文章android-audio-recording-part-2/

侧面说明:

如果你想保存在MP3格式录制的文件,然后修改源代码文件RecorderActivity.java。在那里你会看到行private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".wav";

更改它作为private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".mp3";

OR

您可以修改变量名太或需要由应用程序相关的代码。

祝你好运!

2

我假设你不想使用你的麦克风录制音频流,而是下载原始音频文件,那么你正在寻找什么叫做渐进式下载,here是一个很好的教程来设置它与MediaController,基本上你首先开始下载文件,当你下载它的时候,你用本地播放器读取缓冲文件作为数据源。

从上面的链接,你可以使用StreamingMediaPlayer,原来的安卓系统MediaPlayer还不支持从外部URL流媒体,所以这个类提供了一个伪流功能,通过增量下载内容&播放,只要我们获得足够的音频临时存储。

public class StreamingMediaPlayer { 

private static final int INTIAL_KB_BUFFER = 96*10/8;//assume 96kbps*10secs/8bits per byte 

private TextView textStreamed; 

private ImageButton playButton; 

private ProgressBar progressBar; 

// Track for display by progressBar 
private long mediaLengthInKb, mediaLengthInSeconds; 
private int totalKbRead = 0; 

// Create Handler to call View updates on the main UI thread. 
private final Handler handler = new Handler(); 

private MediaPlayer  mediaPlayer; 

private File downloadingMediaFile; 

private boolean isInterrupted; 

private Context context; 

private int counter = 0; 

public StreamingMediaPlayer(Context context,TextView textStreamed, ImageButton playButton, Button streamButton,ProgressBar progressBar) 
{ 
    this.context = context; 
    this.textStreamed = textStreamed; 
    this.playButton = playButton; 
    this.progressBar = progressBar; 
} 

/** 
* Progressivly download the media to a temporary location and update the MediaPlayer as new content becomes available. 
*/ 
public void startStreaming(final String mediaUrl, long mediaLengthInKb, long mediaLengthInSeconds) throws IOException { 

    this.mediaLengthInKb = mediaLengthInKb; 
    this.mediaLengthInSeconds = mediaLengthInSeconds; 

    Runnable r = new Runnable() { 
     public void run() { 
      try { 
       downloadAudioIncrement(mediaUrl); 
      } catch (IOException e) { 
       Log.e(getClass().getName(), "Unable to initialize the MediaPlayer for fileUrl=" + mediaUrl, e); 
       return; 
      } 
     } 
    }; 
    new Thread(r).start(); 
} 

/** 
* Download the url stream to a temporary location and then call the setDataSource 
* for that local file 
*/ 
public void downloadAudioIncrement(String mediaUrl) throws IOException { 

    URLConnection cn = new URL(mediaUrl).openConnection(); 
    cn.connect(); 
    InputStream stream = cn.getInputStream(); 
    if (stream == null) { 
     Log.e(getClass().getName(), "Unable to create InputStream for mediaUrl:" + mediaUrl); 
    } 

    downloadingMediaFile = new File(context.getCacheDir(),"downloadingMedia_" + (counter++) + ".dat"); 
    FileOutputStream out = new FileOutputStream(downloadingMediaFile); 
    byte buf[] = new byte[16384]; 
    int totalBytesRead = 0, incrementalBytesRead = 0; 
    do { 
     int numread = stream.read(buf); 
     if (numread <= 0) 
      break; 
     out.write(buf, 0, numread); 
     totalBytesRead += numread; 
     incrementalBytesRead += numread; 
     totalKbRead = totalBytesRead/1000; 

     testMediaBuffer(); 
     fireDataLoadUpdate(); 
    } while (validateNotInterrupted()); 

    stream.close(); 
    if (validateNotInterrupted()) { 
     fireDataFullyLoaded(); 
    } 
} 

private boolean validateNotInterrupted() { 
    if (isInterrupted) { 
     if (mediaPlayer != null) { 
      mediaPlayer.pause(); 
      //mediaPlayer.release(); 
     } 
     return false; 
    } else { 
     return true; 
    } 
} 


/** 
* Test whether we need to transfer buffered data to the MediaPlayer. 
* Interacting with MediaPlayer on non-main UI thread can causes crashes to so perform this using a Handler. 
*/ 
private void testMediaBuffer() { 
    Runnable updater = new Runnable() { 
     public void run() { 
      if (mediaPlayer == null) { 
       // Only create the MediaPlayer once we have the minimum buffered data 
       if (totalKbRead >= INTIAL_KB_BUFFER) { 
        try { 
         startMediaPlayer(); 
        } catch (Exception e) { 
         Log.e(getClass().getName(), "Error copying buffered conent.", e);    
        } 
       } 
      } else if (mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition() <= 1000){ 
       // NOTE: The media player has stopped at the end so transfer any existing buffered data 
       // We test for < 1second of data because the media player can stop when there is still 
       // a few milliseconds of data left to play 
       transferBufferToMediaPlayer(); 
      } 
     } 
    }; 
    handler.post(updater); 
} 

private void startMediaPlayer() { 
    try { 
     File bufferedFile = new File(context.getCacheDir(),"playingMedia" + (counter++) + ".dat"); 
     moveFile(downloadingMediaFile,bufferedFile); 

     Log.e("Player",bufferedFile.length()+""); 
     Log.e("Player",bufferedFile.getAbsolutePath()); 

     mediaPlayer = new MediaPlayer(); 
     mediaPlayer.setDataSource(bufferedFile.getAbsolutePath()); 
     mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
     mediaPlayer.prepare(); 
     fireDataPreloadComplete(); 

    } catch (IOException e) { 
     Log.e(getClass().getName(), "Error initializing the MediaPlaer.", e); 
     return; 
    } 
} 

/** 
* Transfer buffered data to the MediaPlayer. 
* Interacting with MediaPlayer on non-main UI thread can causes crashes to so perform this using a Handler. 
*/ 
private void transferBufferToMediaPlayer() { 
    try { 
     // First determine if we need to restart the player after transferring data...e.g. perhaps the user pressed pause 
     boolean wasPlaying = mediaPlayer.isPlaying(); 
     int curPosition = mediaPlayer.getCurrentPosition(); 
     mediaPlayer.pause(); 

     File bufferedFile = new File(context.getCacheDir(),"playingMedia" + (counter++) + ".dat"); 
     //FileUtils.copyFile(downloadingMediaFile,bufferedFile); 

     mediaPlayer = new MediaPlayer(); 
     mediaPlayer.setDataSource(bufferedFile.getAbsolutePath()); 
     //mediaPlayer.setAudioStreamType(AudioSystem.STREAM_MUSIC); 
     mediaPlayer.prepare(); 
     mediaPlayer.seekTo(curPosition); 

     // Restart if at end of prior beuffered content or mediaPlayer was previously playing. 
     // NOTE: We test for < 1second of data because the media player can stop when there is still 
     // a few milliseconds of data left to play 
     boolean atEndOfFile = mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition() <= 1000; 
     if (wasPlaying || atEndOfFile){ 
      mediaPlayer.start(); 
     } 
    }catch (Exception e) { 
     Log.e(getClass().getName(), "Error updating to newly loaded content.", e);     
    } 
} 

private void fireDataLoadUpdate() { 
    Runnable updater = new Runnable() { 
     public void run() { 
      textStreamed.setText((CharSequence) (totalKbRead + " Kb read")); 
      float loadProgress = ((float)totalKbRead/(float)mediaLengthInKb); 
      progressBar.setSecondaryProgress((int)(loadProgress*100)); 
     } 
    }; 
    handler.post(updater); 
} 

/** 
* We have preloaded enough content and started the MediaPlayer so update the buttons & progress meters. 
*/ 
private void fireDataPreloadComplete() { 
    Runnable updater = new Runnable() { 
     public void run() { 
      mediaPlayer.start(); 
      startPlayProgressUpdater(); 
      playButton.setEnabled(true); 
      //streamButton.setEnabled(false); 
     } 
    }; 
    handler.post(updater); 
} 

private void fireDataFullyLoaded() { 
    Runnable updater = new Runnable() { 
     public void run() { 
      transferBufferToMediaPlayer(); 
      textStreamed.setText((CharSequence) ("Audio full loaded: " + totalKbRead + " Kb read")); 
     } 
    }; 
    handler.post(updater); 
} 

public MediaPlayer getMediaPlayer() { 
    return mediaPlayer; 
} 

public void startPlayProgressUpdater() { 
    float progress = (((float)mediaPlayer.getCurrentPosition()/1000)/(float)mediaLengthInSeconds); 
    progressBar.setProgress((int)(progress*100)); 

    if (mediaPlayer.isPlaying()) { 
     Runnable notification = new Runnable() { 
      public void run() { 
       startPlayProgressUpdater(); 
      } 
     }; 
     handler.postDelayed(notification,1000); 
    } 
}  

public void interrupt() { 
    playButton.setEnabled(false); 
    isInterrupted = true; 
    validateNotInterrupted(); 
} 

public void moveFile(File oldLocation, File newLocation) 
throws IOException { 

    if (oldLocation.exists()) { 
     BufferedInputStream reader = new BufferedInputStream(new FileInputStream(oldLocation)); 
     BufferedOutputStream writer = new BufferedOutputStream(new FileOutputStream(newLocation, false)); 
     try { 
      byte[] buff = new byte[8192]; 
      int numChars; 
      while ((numChars = reader.read( buff, 0, buff.length)) != -1) { 
       writer.write(buff, 0, numChars); 
      } 
     } catch(IOException ex) { 
      throw new IOException("IOException when transferring " + oldLocation.getPath() + " to " + newLocation.getPath()); 
     } finally { 
      try { 
       if (reader != null){ 
        writer.close(); 
        reader.close(); 
       } 
      } catch(IOException ex){ 
       Log.e(getClass().getName(),"Error closing files when transferring " + oldLocation.getPath() + " to " + newLocation.getPath()); 
      } 
     } 
    } else { 
     throw new IOException("Old location does not exist when transferring " + oldLocation.getPath() + " to " + newLocation.getPath()); 
    } 
} 

}

然后你就可以轻松地使用它像:

private void startStreamingAudio() { 
    try { 
     final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress_bar); 
     if (audioStreamer != null) { 
      audioStreamer.interrupt(); 
     } 
     audioStreamer = new StreamingMediaPlayer(this,textStreamed, playButton, streamButton,progressBar); 
     audioStreamer.startStreaming("http://www.pocketjourney.com/downloads/pj/tutorials/audio.mp3",1677, 214); 
     //streamButton.setEnabled(false); 
    } catch (IOException e) { 
     Log.e(getClass().getName(), "Error starting to stream audio.", e);     
    }