2013-07-18 126 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);     
    }