前言
該文章面向對WebRTC有一定基礎的碼農,如果完全沒了解過WebRTC的朋友,可以點贊并私信我進行一對一輔導哦,
WebRTC-Android SDK自帶的實作方式
其實WebRTC已經提供了一個org.webrtc.VideoFileRenderer.java的渲染器,專門用于把畫面資料存盤到本地檔案,該渲染器與SurfaceViewRenderer.java一樣實作了VideoSink介面,
通過VideoTrack.addSink(VideoSink sink)方法把渲染器添加到畫面軌道中,即開始錄制畫面,
通過VideoTrack.removeSink(VideoSink sink)方法可把渲染器從畫面軌道中移除,即停止錄制畫面,
mStartRecordBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 開始錄制
String filePath = getExternalFilesDir(null).getAbsolutePath() + File.separator + System.currentTimeMillis() + ".y4m";
try {
mVideoFileRenderer = new VideoFileRenderer(filePath, 480, 640, mEglContext);
} catch (IOException e) {
e.printStackTrace();
mVideoFileRenderer = null;
return;
}
mVideoTrack.addSink(mVideoFileRenderer);
}
});
mStopRecordBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 停止錄制
if (mVideoFileRenderer != null) {
mVideoTrack.removeSink(mVideoFileRenderer);
mVideoFileRenderer.release();
mVideoFileRenderer = null;
}
}
});
但這種方式有2個重大的缺陷:
- 只能錄制畫面,沒有實作聲音的錄制
- 錄制的畫面是YUV裸流,每一幀都是完整幀,所以會導致檔案非常大(10幾秒的視頻就可以超過上百MB)
flutter-webrtc的實作方式
WebRTC-Android SDK自帶的實作方式因為有兩個重大的缺陷,導致正常的業務基本用不上這種實作方式,
但萬幸的是flutter-webrtc專案早已看透了這一切,然后大喊一聲我自己來,然后com.cloudwebrtc.webrtc.record.VideoFileRenderer.java這個類就出來了,
跟WebRTC-Android SDK的VideoFileRenderer一樣,該渲染器也實作了VideoSink介面,并且額外實作了SamplesReadyCallback介面,實作VideoSink介面是為了獲取畫面資料,SamplesReadyCallback則是為了獲取音頻資料,
廢話不多,直接上代碼
mInitPeerConnectionFactoryBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 初始化PeerConnectionFactory
......
mPeerConnectionFactory = new PeerConnectionFactory.Builder()
......
.setAudioDeviceModule(JavaAudioDeviceModule.builder(context)
.setSamplesReadyCallback(new JavaAudioDeviceModule.SamplesReadyCallback() {
@Override
public void onWebRtcAudioRecordSamplesReady(JavaAudioDeviceModule.AudioSamples audioSamples) {
if (mVideoFileRenderer != null) {
// 把音頻資料傳給VideoFileRenderer
mVideoFileRenderer.onWebRtcAudioRecordSamplesReady(audioSamples);
}
}
})
......
.createAudioDeviceModule());
......
}
});
mStartRecordBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 開始錄制
String filePath = getExternalFilesDir(null).getAbsolutePath() + File.separator + System.currentTimeMillis() + ".mp4";
try {
mVideoFileRenderer = new VideoFileRenderer(filePath, mEglContext, true);
} catch (IOException e) {
e.printStackTrace();
mVideoFileRenderer = null;
return;
}
mVideoTrack.addSink(mVideoFileRenderer);
}
});
mStopRecordBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 停止錄制
if (mVideoFileRenderer != null) {
mVideoTrack.removeSink(mVideoFileRenderer);
mVideoFileRenderer.release();
mVideoFileRenderer = null;
}
}
});
至此,我們就可以邊直播邊錄像了!而且錄制出來的是mp4檔案,視頻經過了壓縮,檔案大小就是正常的mp4檔案大小了,
但是,flutter-webrtc的VideoFileRenderer還是有點小問題,就是對于音頻的時間計算有點問題,里面直接固定寫死音頻的采樣率是48000Hz,所以我們還需要對VideoFileRenderer進行一點小修改:
@Override
public void onWebRtcAudioRecordSamplesReady(JavaAudioDeviceModule.AudioSamples audioSamples) {
if (!isRunning)
return;
audioThreadHandler.post(() -> {
......
if (bufferIndex >= 0) {
......
// presTime += data.length * 125 / 12; // 1000000 microseconds / 48000hz / 2 bytes
presTime += data.length * (1_000_000 / audioSamples.getSampleRate() / 2); //16位最后那個數字是2,8位是1
}
drainAudio();
});
}
完美結束~
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/274494.html
標籤:其他
下一篇:iOS 判斷是否插了耳機
