我使用的是https://github.com/nonameentername/soundtouch-android/blob/master/src/org/tecunhuman/ExtAudioRecorder.java中的AudioRecord
類,但稍作修改。獲取Android AudioRecord開始錄製時間延遲
在start()
方法中,我開始用AudioRecord
類記錄。我也開始MediaPlayer
發揮工具。爲了讓人聲和樂器在服務器上的正確位置混合,我發送了樂器延遲,以開始時用沉默(padDelayInSeconds - MediaPlayer
延遲從開始被調用到實際播放時的延遲,因爲存在延遲當啓動媒體播放器時)。
我的邏輯必須是錯誤的,因爲人聲和樂器的播放時序在設備上是關閉的。有些時候錄音速度太快,有時會比樂器演奏時慢。有什麼建議麼。任何幫助將不勝感激。
爲了更好的解釋:
錄音開始
| ------------------------------ ---------- |
節拍/器樂開始播放後
[X] | -------------------------------- --------------- |
我想找到X,所以我可以發送到startPlayback()方法beatDelayInSeconds和服務器。 X是聲音開始錄製到節拍實際開始播放之間的時間。目前在我的startPlayback()方法中,同時播放節拍和人聲,它們不像錄製的那樣同步。希望這是有道理的。
注意:我不得不在延遲處理程序中放置一些Jelly Bean設備,因爲AudioRecord
偵聽程序沒有被調用。
public void start()
{
if (state == State.READY)
{
if (rUncompressed)
{
payloadSize = 0;
RecordReadDelayInSeconds = 0;
RecordDelayInSeconds = 0;
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(mp3Path);
mPlayer.prepare();
} catch (IllegalArgumentException e) {e.printStackTrace();}
catch (SecurityException e) {e.printStackTrace();}
catch (IllegalStateException e) {e.printStackTrace();}
catch (IOException e) { e.printStackTrace();}
final long recordstarted = System.nanoTime() + 1500000000; //handler delay
audioRecorder.startRecording();
//Fix for recording issue with Samsung s3 Sprint phones.Doing a delayed first read
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
long recordstopped = System.nanoTime();
long recordDelay = recordstopped - recordstarted;
double RecordDelayInSeconds = recordDelay/1000000.0;
Log.i("StartRecording() Delay in seconds",
String.valueOf(RecordDelayInSeconds));
long recordreadstarted = System.nanoTime();
int bytesReceived = audioRecorder.read(buffer, 0, buffer.length);
Log.d(TAG,"Delayed first read: bytes recieved "+ bytesReceived);
long recordreadstopped = System.nanoTime();
long recordreadDelay = recordreadstopped - recordreadstarted;
RecordReadDelayInSeconds = recordreadDelay/1000000.0;
Log.i("Record read() Delay in seconds",
String.valueOf(RecordReadDelayInSeconds));
long mediastarted = System.nanoTime();
mPlayer.start();
long mediastopped = System.nanoTime();
long beatDelay = mediastopped - mediastarted;
beatDelayInSeconds = 0;
beatDelayInSeconds = (beatDelay)/1000000000.0;
Log.i("Beat Delay in seconds",
String.valueOf(beatDelayInSeconds));
}
}, 1500);
}
這是用戶在向服務器發送信息之前偵聽的回放代碼。它首先開始播放用戶剛錄製的wav,然後根據另一種方法的beatDelayInSeconds變量播放樂器。
private void startPlayback() {
wavPlayer.start();
RefreshHandler mp3PlaybackHandler = new RefreshHandler();
mp3PlaybackHandler.sleep((long) (beatDelayInSeconds * 1000));
}
class RefreshHandler extends Handler {
@Override
public void handleMessage(Message msg) {
mp3Player.start();
}
public void sleep(long delayMillis) {
this.removeMessages(0);
Log.i(TAG, "Beat delayed for " + delayMillis + " milliseconds");
sendMessageDelayed(obtainMessage(0), delayMillis);
}
};
@nawlrus ..在你的問題中,你引用了「讓它們在服務器上同步」。我知道您正在嘗試錄製並同時播放內容。我無法理解轉載的評論的背景。你能澄清一下嗎? – Ganesh
對不起Ganesh。我編輯並添加了更多信息。我發送beatDelayInseconds和一個recordDelay,它等於RecordReadDelayInSeconds + RecordDelayInSeconds。服務器負責從那裏進行媒體處理,但我不認爲我得到了正確的延遲處理和錄製後的回放。 – nawlrus
@nawlrus ..所以,如果我理解正確,你正試圖記錄一些數據,將其流式傳輸到服務器,從服務器接收相同的數據並在同一設備上播放。這種理解是否正確?如果這是真的,如果在回放過程中記錄會話是開啓的,你會不會遇到迴路內回聲或背景回聲?這可以接受嗎?還有一點。即使錄像機存在啓動延遲,一旦它開始流出數據,它必須遵守一些比特率規定,所以即使您的媒體播放器啓動較晚,它也不應該有理想的下溢。不是這樣嗎? – Ganesh