linphone錄音分析--添加錄音按鈕
接上一節
第一節分析了linphone安卓端如何進行錄音,本節希望在通話界面上增加一個錄音按鈕,當通話開始時,按下錄音按鈕開始錄音,再次按下錄音按鈕停止錄音,而且,任何情況下的通話結束都要停止錄音。已知的停止通話的情況包括:
- 本方中止通話
- 對方中止通話
- 通話意外中斷
- …
但是也可能在某個地方存在回調函數,比如相應Call的State,變換爲某個狀態時,調用stopRecord()即可正常停止錄音。目前我們就只考慮前面兩種情況,能解決正常場景的問題。
UI:添加按鈕相關資源
- 按鈕圖片:推薦去Iconfont裏搜索想要的圖標,可以下載不同格式、大小、顏色的,十分方便。
- 在
res/layout/call.xml
中添加一個ImageView id=record
,然後指定一個src=@drawable/record
,爲了方便,將原來的add_call
按鈕刪除. - 在
res/drawable/
中添加上面的record.xml
文件,並指定drawable="@drawable/recording_default".
- 添加兩個.png格式的錄音按鈕,放在
res/drawable-xhdpi
目錄下,命名爲recording_default.png
和recording_ongoing.png
. - 把
CallActivity.java
中的addCall變量替換爲record. - 重新編譯生成apk,可以看到替換後的圖標。
- 下一步就開始添加按鈕的功能。
在通話界面上點擊按鈕,實現開始和結束錄音
在CallActivity.java
中創建一個boolean類型的變量isRecording
,記錄當前是否正在錄音,初始值設爲false
。
下面是點擊錄音按鈕時執行的代碼。
/**
* @author wlf
* @date 1128
* 開始或者停止錄音
*/
private void recording() {
if(!isRecording) {
Log.i("wlf"," CallActivity#recording.!isRecording");
Call call = LinphoneManager.getLc().getCurrentCall();
Log.i("wlf"," call.state = " + call.getState());
if (call!= null) {
call.startRecording();
Log.i("wlf","after startIncallActivity!");
record.setImageResource(R.drawable.recording_ongoing);
}
} else {
Log.i("wlf"," CallActivity#recording.isRecording");
Call currentCall = LinphoneManager.getLc().getCurrentCall();
currentCall.stopRecording();//wlf 1127
Log.i("wlf"," CallActivity#recording.stopRecording!");
record.setImageResource(R.drawable.recording_default);
}
isRecording = !isRecording;
}
邏輯很清晰。判斷當前是否正在錄音,如果結果爲否表示此次點擊是想要開始錄音。此時,仍然通過getCurrentCall()
獲取到當前的Call對象,直接調用call的startRecording()
方法開始錄音,然後將錄音圖標更改爲正在錄音的形狀。否則,如果當前正在錄音,而按下了錄音按鈕,則表示停止錄音,調用stopRecording()
,更改圖片。最後每一次條件執行後都要將狀態標誌取反。
這裏需要注意的是,想要調用startRecording()
方法,必須在初始化CallParam參數時設置存儲文件的路徑,否則將不會生成錄音文件。初始化CallParam的操作放在CallIncomingActivity.java的answer()
中,就是上一節中棄用的方法,這裏重新啓用,只是要設置param的錄音路徑,代碼如下:
private void answer() {
if (alreadyAcceptedOrDeniedCall) {
return;
}
alreadyAcceptedOrDeniedCall = true;
CallParams params = LinphoneManager.getLc().createCallParams(mCall);
boolean isLowBandwidthConnection = !LinphoneUtils.isHighBandwidthConnection(LinphoneService.instance().getApplicationContext());
if (params != null) {
params.enableLowBandwidth(isLowBandwidthConnection);
String filePath = FileUtils.getCallRecordingFilename(LinphoneService.instance().getApplicationContext(), mCall.getRemoteAddress());
Log.i("wlf","filePath = " + filePath);
params.setRecordFile(filePath);//wlf 1128
} else {
Log.e("Could not create call params for call");
}
if (params == null || !LinphoneManager.getInstance().acceptCallWithParams(mCall, params)) {
// the above method takes care of Samsung Galaxy S
Toast.makeText(this, R.string.couldnt_accept_call, Toast.LENGTH_LONG).show();
} else {
if (!LinphoneActivity.isInstanciated()) {
return;
}
LinphoneManager.getInstance().routeAudioToReceiver();
LinphoneActivity.instance().startIncallActivity(mCall);
}
}
按下掛斷鍵結束錄音
這一部分功能在第一節中已經實現,沿用就可以CallActivity.java#hangUp()
對方按下掛斷鍵結束錄音
經測試,本方開始錄音,然後對方掛斷電話後,本方退出通話界面,錄音文件能夠正常播放。所以暫時不處理。
本方主叫時,開始通話
找了兩天才找到設置Param參數的位置。
當像其他用戶撥打電話時,會調用LinphoneManager.java中的newOutgoingCall()方法,在參數中指定對方地址等信息。
在newOutgoingCall()方法中,調用了CallManager的inviteAddress()方法.在該方法中就能看到熟悉的CallParams參數配置。在這裏把setRecordFile()相關的代碼粘進去就可以啦。
//wlf 1203
if (params != null) {
String filePath = FileUtils.getCallRecordingFilename(LinphoneService.instance().getApplicationContext(), lAddress);
Log.i("wlf","filePath = " + filePath);
params.setRecordFile(filePath);//wlf 1128
} else {
Log.e("Could not create call params for call");
}
只有一個地方需要改動,FileUtils.getCallRecordingFilename的第二個參數,這裏不能傳入call參數獲取地址,因爲此時並沒有初始化一個Call對象,但是inviteAddress()方法的第一個參數就是一個Address地址,直接傳進去就OK。