📜  语音和视频通话如何在 Android 中工作?(1)

📅  最后修改于: 2023-12-03 15:41:47.015000             🧑  作者: Mango

语音和视频通话如何在 Android 中工作?

在 Android 中实现语音和视频通话有多种方式。下面将介绍几种常用的方式。

使用 Android 自带的 API

Android 提供了自带的 android.media 包来实现语音和视频通话。其中,语音通话可以使用 AudioRecordAudioTrack 类来实现录音和播放;视频通话可以使用 SurfaceViewCamera 类实现视频采集和显示。示例代码如下:

// 初始化录音器
mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
    SAMPLE_RATE_IN_HZ, CHANNEL_CONFIG, AUDIO_FORMAT, bufferSize);
// 开始录音
mRecorder.startRecording();

// 初始化播放器
mPlayer = new AudioTrack(AudioManager.STREAM_VOICE_CALL,
    SAMPLE_RATE_IN_HZ, AudioFormat.CHANNEL_OUT_MONO, AUDIO_FORMAT, bufferSize,
    AudioTrack.MODE_STREAM);
// 开始播放
mPlayer.play();

// 初始化 SurfaceView 和 Camera
mCamera = Camera.open();
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();

需要注意的是,音视频通话需要进行网络传输,因此需要使用 TCP 或 UDP 协议来传输音视频数据。

使用第三方库

另外,还可以使用一些第三方库来实现语音和视频通话。常用的库包括:

  • Agora
  • PJSIP
  • WebRTC

这些库都提供了高度封装的 API,不仅支持音视频通话,还支持屏幕共享和直播等功能。示例代码如下:

// Agora
private static final IAgoraAPI mAgoraAPI = AGApplicationTheOne.getInstance().getmAgoraAPI();

// 加入频道
mAgoraAPI.channelJoin(channelKey, channelName);

// 发送视频流
VideoFrame videoFrame = new VideoFrame();
videoFrame.format = new I420Buffer(width, height);
videoFrame.timestampMs = System.currentTimeMillis();
byte[] data = new byte[width * height * 3 / 2]; // I420 数据
videoFrame.buffer = new ByteBuffer[] {ByteBuffer.wrap(data)};
mAgoraAPI.pushExternalVideoFrame(videoFrame);

// PJSIP
// 初始化 SIP 账号
AccountConfig cfg = new AccountConfig();
cfg.setIdUri(String.format("sip:%s@%s", username, domain));
cfg.getRegConfig().setRegistrarUri(String.format("sip:%s", domain));
AuthCredInfo cred = new AuthCredInfo("digest", "*", password);
cfg.getSipConfig().getAuthCreds().add(cred);
Account account = new Account();
account.create(cfg);

// 发起 SIP 通话
CallOpParam prm = new CallOpParam(true);
Call call = acc.makeCall(String.format("sip:%s@%s", callee, domain), prm);

// WebRTC
// 初始化 PeerConnection
PeerConnectionFactory.initialize(PeerConnectionFactory.InitializationOptions.builder(mContext).createInitializationOptions());
PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
options.disableEncryption = true;
PeerConnectionFactory pcFactory = PeerConnectionFactory.builder().setOptions(options).createPeerConnectionFactory();

// 创建 PeerConnection
List<PeerConnection.IceServer> iceServers = new ArrayList<>();
iceServers.add(PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer());
PeerConnection.RTCConfiguration rtcConfig = new PeerConnection.RTCConfiguration(iceServers);
PeerConnection peerConnection = pcFactory.createPeerConnection(rtcConfig, new CustomPeerConnectionObserver("localPeerConnection"));

// 创建并发送视频流
VideoCapturer videoCapturer = createCameraCapturer(new Camera1Enumerator(false));
SurfaceTextureHelper surfaceTextureHelper = SurfaceTextureHelper.create("CaptureThread", eglBase.getEglBaseContext());
VideoSource videoSource = pcFactory.createVideoSource(false);
SurfaceTexture surfaceTexture = surfaceTextureHelper.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(640, 480);
Surface surface = new Surface(surfaceTexture);
videoCapturer.initialize(surfaceTextureHelper, mContext, videoSource.getCapturerObserver());
videoCapturer.startCapture(640, 480, 30);

VideoTrack videoTrack = pcFactory.createVideoTrack("local_video", videoSource);
videoTrack.addSink(localVideoView);

MediaStream stream = pcFactory.createLocalMediaStream("local_stream");
stream.addTrack(videoTrack);

peerConnection.addStream(stream);

以上是一些简单的示例,具体实现方式需要根据具体需求进行调整。

总结

Android 中实现语音和视频通话可以使用 Android 自带的 API 或者第三方库。使用自带 API 相对简单,但是需要自己实现音视频数据的传输;而第三方库封装度更高,支持更多的功能,但是需要引入额外的库,并且集成相对复杂。在选择实现方式时需要根据具体需求进行选择。