Android 音视频通话

音视频通话的数据流量

实时语音和实时视频的数据流量如下:

  • 实时语音:双向 150k bytes/minute
  • 实时视频:双向 2.2M~5M bytes/minute

CallService 获取

UserAgentProxy proxy = UserAgentProxy.getInstance();
......
CallService callService = proxy.getCallService();

监听呼入通话和通话状态

通过注册相应 listener 来监听呼叫过来的通话。

public synchronized void setCallListener(new CallListener(){    
    @Override public void videoIncoming(int status, String peer_name,byte[] extraData);
    @Override public void audioIncoming(int status, String peer_name,byte[] extraData);
    @Override public void videoAccept(int status, String peer_name, byte[] extraData);
    @Override public void audioAccept(int status, String peer_name, byte[] extraData);
    @Override public void reject(int status, String peer_name);
    @Override public void hangup(int status, String peer_name);
    @Override public void busy(int status, String peer_name);
    @Override public void missVideoCall(int status, String peer_name,byte[] extraData, String roomId);
    @Override public void missAudioCall(int status, String peer_name,byte[] extraData, String roomId);
    @Override public void groupAccept(int status, String groupId, byte[] extraData);
    @Override public void groupReject(int status, String groupId, byte[] extraData);
    @Override public void groupHangup(int status, String groupId, byte[] extraData);
 
    @Override public void sendMediaDataStart(int status, String peer_name, CallType call_type, NetworkType peer_nettype, int cpuLevel, int screen_aspect, String peer_sdp, String peer_os, String voip_sdp, int recommendBitrate);
 
    @Override public void waitingData(int status, String peer_name, int timeOut); 
    @Override public void recoverData(int status, String peer_name);
    @Override public void setQosParameter(String voipQos);
 
});

拨打语音通话

public class CallService {
    /**
    * 拨打语音通话
    * @param peerName
    * @param roomID
    */
    boolean audioCall(String peerName, String[] roomID, byte[] extraData);;
}

拨打视频通话

public class CallService {
    /**
    * 拨打视频通话
    * @param peerName
    * @param roomID
    */
    boolean videoCall(String peerName, String[] roomID, byte[] extraData);
}

视频通话需要显示自己和对方的图像,需要设置相应 surfaceview

接听通话

public class CallService {
    /**
    * 接听通话,视频呼叫也可以选择语音接听
    */
    boolean acceptVideo(byte[] extraData);
    boolean acceptAudio(byte[] extraData);
}

拒绝接听

public class CallService {
    /**
    * 拒绝接听
    */
    boolean reject();
}

挂断通话

public class CallService {
    /**
    * 挂断通话
    */
    boolean hangup();
}

音视频媒体

摄像头操作

public class VoipVideoCapture {
    /**
     * VoipVideoCapture构造函数
     * @param callback 此参数应传入VoipAndroid对象
     * @param param 包含采集的宽高值
     */
    public VoipVideoCapture(VideoCaptureCallback callback, CaptureParam param);
 
    /**
     * 开启摄像头
     * @param frontCamera 是否前置摄像头
     * @param config 设备相关的配置,可从服务器获取得
     * @param parentView 采集所用的SurfaceView的父View
     * @return
     *     0: 成功
     *    -1: 摄像头已经启动
     *    -2: 摄像头被禁用
     *    -3: 打开摄像头失败
     *    -4: 无法访问摄像头
     */
    public int start(boolean frontCamera,VoipConfig config, ViewGroup parentView);
 
    /**
     * 停止摄像头
     */
    public void stop();
 
    /**
     * 暂时丢弃采集到的视频数据不处理
     */
    public void pause();
 
    /**
     * 恢复对采集到的视频数据的处理
     */
    public void resume();
}

媒体库初始化

public class VoipAndroid {
    /**
     * VoipAndroid构造函数
     * @param handle 目前已弃用该参数,可忽略
     * @param context context对象
     * @param jsonConfig 设备相关的配置,可从服务器获得
     */
    public VoipAndroid(Handler handler, Context context, JSONObject jsonConfig);
 
    /**
     * VoipAndriod初始化
     * @param cpu CPU能力级别
     * @param videoCapture VoipVideoCapture对象
     * @param localAspectRatio 本地窗口宽高比:1024*高/宽
     */
    public void init(int cpu, VoipVideoCapture videoCapture, int localAspectRatio);
 
    /**
     * 注册音频回调函数
     * @param audioCallback 实现了AudioCallback接口的对象
     */
    public void registerAudioCallback(AudioCallback audioCallback);
 
    /**
     * 注册视频回调函数
     * @param videoCallback 实现了VideoCallback接口的对象
     */
    public void registerVideoCallback(VideoCallback videoCallback);
 
    /**
     * 反初始化
     */
    public void uninit();
 
    /**
     * 获取版本号
     * @return 版本字符串 
     */
    public static native String version();
 
    /**
     * 设置日志级别
     * @param logLevel 日志的级别,0:ERROR; 1:WARNING; 2:INFO; 3:DEBUG
     */
    public void setLogLevel(int logLevel);
}

音视频传输的启动停止

public class VoipAndroid {
    /**
     * 设置通话质量相关的参数
     * @param qosJson 根据网络类型等信息从服务器获得
     */
    public void setQosParam(String qosJson);
 
    /**
     * 准备媒体的收发
     * @param remote “group”表示群呼叫,否则为个人呼叫
     * @param audioSdp 音频能力集
     * @param videoSdp 视频能力集
     * @param selfUserIdInGroup 本用户在群中的ID(csrc)
     */
    public void startCall(String remote, String audioSdp, String videoSdp, int selfUserIdInGroup);
 
    /**
     * 启动音频传输
     * @param activity Activity对象,用于调节音量等
     * @param audioParam 音频参数
     * @param userEarpiece 为TRUE时从听筒播放声音,为FALSE时从扬声器播放声音
     */
    public void startAudioPipeline(Activity activity, AudioParameter audioParam, boolean useEarpiece);
 
    /**
     * 启动视频传输
     * @param videoParam 视频参数
     */
    public void startVideoPipeline(VideoParameter videoParam);
 
    /**
     * 停止媒体传输
     */
    public void stopCall();
 
    /**
     * 起停音频的发送
     * @param audioRecvOnly 为TRUE时,只接收不发送;为FALSE时,既接收又发送
     */
    public void setAudioRecvOnly(boolean audioRecvOnly);
 
    /**
     * 起停视频的发送
     * @param videoRecvOnly 为TRUE时,只接收不发送;为FALSE时,既接收又发送
     */
    public void setVideoRecvOnly(boolean videoRecvOnly);
 
    /**
     * 暂停视频的传输
     */
    public void holdVideoPipeline();
 
    /**
     * 恢复之前暂停的视频传输
     */
    public void resumeVideoPipeline();
}

群视频信息更新

public class VoipAndroid {
    /**
     * 更新群视频中的观察者人数
     * @param observerCount 观察者人数
     */
    public void updateObserverCountInGroupCall(int observerCount);
 
    /**
     * 新的表演者加入群视频
     * @param userId 新加入表演者的群内ID(csrc)
     */
    public void performerJoinInGroupCall(int userId);
 
    /**
     * 表演者离开群视频
     * @param userId 离开的表演者的群内ID(csrc)
     */
    public void performerQuitGroupCall(int userId);
}

显示窗口信息设置

public class VoipAndroid {
    /**
     * 设置自己预览视频的窗口参数
     * @param sizeLevel 窗口的大小等级
     * @param aspect 窗口的宽高比:1024*高/宽
     */
    public void setLocalWindow(WindowSizeLevel sizeLevel, int aspect);
 
    /**
     * 设置远端视频的窗口参数
     * @param sizeLevel 窗口的大小等级
     */
    public void setRemoteWindow(WindowSizeLevel sizeLevel);
}

音频设置

public class VoipAndroid {
    /**
     * 停止音频设备
     */
    public void disableAudioIO();
 
    /**
     * 启动音频设备
     */
    public void enableAudioIO();
 
    /**
     * 重设音频的播放模式
     * @param useEarpiece 之前保存的状态:为TRUE时从听筒播放;为FALSE时从扬声器播放
     */
    public void resetSpecialAudioDevice(boolean useEarpiece);
 
    /**
     * 将麦克风静音
     */
    public void muteMicrophone();
 
    /**
     * 取消麦克风的静音
     */
    public void unmuteMicrophone();
 
    /**
     * 当在通话中时,静音播放
     */
    public void muteSpeaker();
 
    /**
     * 取消通话中的静音播放
     */
    public void unmuteSpeaker();
 
    /**
     * 通话中时,将收到的对方声音静音播放
     */
    public void muteVoice();
 
    /**
     * 取消通话中的对方声音的静音播放
     */
    public void unmuteVoice();
 
    /**
     * 设置播放模式
     * @param use 为TRUE时从听筒播放;为FALSE时从扬声器播放
     */
    public void setUseEarpiece(boolean use);
 
    /**
     * 蓝牙音频设备的设置
     * @param on 为TRUE时表示链接了蓝牙音频设备,为FALSE时表示断开蓝牙音频设备
     */
    public void setBluetooth(boolean on);
 
    /**
     * 获取当前是否在吹气
     * @return TRUE表示目前正在吹气;FALSE表示没有监测到吹气
     */
    public boolean audioIsWind();
 
    /**
     * 获取当前语音的音量
     * @return 当前音量的分贝值
     */
    public int audioDB();
 
    /**
     * 设置游戏模式下的特殊音频处理
     * @param isGameMode 是否在游戏模式下
     */
    public void setGameMode(boolean isGameMode);
}

音效播放

public class VoipAndroid {
    /**
     * 播放MP3文件
     * @param activity Activity对象,用于调节音量
     * @param uri MP3文件的URI地址
     * @param fileName MP3文件的绝对路径
     * @param cache 播放时是否缓存解码数据
     * @param repeat 是否循环播放
     * @param crescendo 是否渐强效果
     * @param force 该参数已弃用
     * @param useEarpiece 为TRUE表示从听筒播放,为FALSE表示从扬声器播放
     * @param type 声音类型:提示音/铃声/音乐
     */
    public void playMp3File(Activity activity, final Uri uri, String fileName, boolean cache, final boolean repeat, boolean crescendo, boolean force, boolean useEarpiece, MP3_TYPE type);
 
    /**
     * 停止MP3文件的播放
     * @param fileName MP3文件的绝对路径
     */
    public void stopMp3File(String fileName);
 
    /**
     * 停止所有的MP3文件播放
     */
    public void stopAllMp3Files();
 
    /**
     * 暂停MP3文件的播放
     */
    public void pauseMp3();
 
    /**
     * 恢复暂停播放的MP3文件
     */
    public void resumeMp3();
 
    /**
     * 播放音效文件
     * @param path 音效文件的绝对路径
     * @param cache 是否缓存解码数据
     * @param repeat 是否循环播放
     * @param crescendo 是否渐强效果
     * @param volume 音量
     */
    public void  playAudioEffect(String path, boolean cache, boolean repeat, boolean crescendo, float volume);
 
    /**
     * 释放在playAudioEffect时获取的资源
     */
    public void  releaseAudioEffect();
}

视频特效

public class VoipAndroid {
    /**
     * 设置滤镜模式
     * @param mode 0,关闭;1,自然;2,阳光;3,甜蜜;4,淡雅
     */
    public void setFaceBeautyMode(int mode);
 
    /**
     * 设置亮度和色彩
     * @param light 亮度值,0~20
     * @param color 色彩值,自然模式下,范围为0~20;其他模式下,需设置为-1
     */
    public void setFaceBeautyLightAndColor(int light, int color);
 
    /**
     * 设置模版强度,仅在非“自然”模式时设置
     * @param templateStrength 模版强度值,50~125,仅在非“自然”模式时设置
     */
    public void setFaceBeautyTemplateStrength(int templateStrength);
 
    /**
     * 设置滤镜的效果强度
     * @param strength 强度值,0~5
     */
    public void setFaceBeautyStrength(int strength);
 
    /**
     * 设置模糊效果
     * @param enable 是否开启模糊效果
     * @param radius 模糊效果的强度值,0~5
     */
    public void setGaussBlur(boolean enable, int radius);
 
    /**
     * 将一帧YUV图像进行模糊处理
     * @param image 待处理的图像
     * @param radius 模糊效果的强度,0~15
     */
    public void gaussBlurImage(VoipImage image, int radius);
 
    /**
     * 将一帧YUV图像的一部分进行模糊处理
     * @param image 待处理的图像
     * @param radius 模糊效果的强度,0~15
     * @param left 待处理部分的相对坐标,左
     * @param top 待处理部分的相对坐标,上
     * @param right 待处理部分的相对坐标,右
     * @param bottom 待处理部分的相对坐标,下
     */
    public void gaussBlurImagePart(VoipImage image, int radius, int left, int top, int right, int bottom);
 
    /**
     * 将一帧ARGB图像的一部分进行模糊处理
     * @param image 待处理的ARGB图像
     * @param radius 模糊效果的强度,0~15
     * @param left 待处理部分的相对坐标,左
     * @param top 待处理部分的相对坐标,上
     * @param right 待处理部分的相对坐标,右
     * @param bottom 待处理部分的相对坐标,下
     */
    public void gaussBlurARGB(byte[] data, int radius, int width, int height, int left, int top, int right, int bottom)}

语音短信录制和播放

public class VoipAndroid {
    /**
     * 设置语音短信录制的最大时长,默认为60s
     * @param seconds 最大时长的秒数
     */
    public void setAudioMessageMaxDuration(int seconds);
 
    /**
     * 开始录制语音短信
     * @param fileName 存储语音短信的本地文件的绝对路径
     * @param version 文件格式版本
     * @param callback 录制语音短信过程中的回调
     */
    public void startRecordingAudioMessage(String fileName, int version, AudioMsgRecorderCallback callback);
 
    /**
     * 停止语音短信的录制
     */
    public void stopRecordingAudioMessage();
 
    /**
     * 获取语音短信的时长
     * @param fileName 存储语音短信的本地文件的绝对路径
     * @return int 语音短信的时长,单位毫秒
     */
    public int getAudioMessageDuration(String fileName);
 
    /**
     * 开始播放语音短信
     * @param activity Activity对象,用于调整音量
     * @param fileName 存储语音短信的本地文件的绝对路径
     * @param callback 播放语音短信过程中的回调
     * @param useEarpiece 为TRUE时,从听筒播放;为FALSE时,从扬声器播放
     */
    public void startPlayingAudioMessage(Activity activity, String fileName, AudioMsgPlayerCallback callback, boolean useEarpiece);
 
    /**
     * 停止语音短信的播放
     */
    public void stopPlayingAudioMessage();
}

小视频录制和播放

public class VoipAndroid {
    /**
     * 设置小视频录制的最大时长,默认为60秒
     * @param seconds 最大时长的秒数
     */
    public void setVideoMessageMaxDuration(int seconds);
 
    /**
     * 准备开始录制小视频
     * @param isAvatar FALSE
     * @param srcFileDir “”
     * @param avatarDir “”
     * @return 0: 成功; Other: 失败
     */
    public int prepareRecordingVideoMessage(boolean isAvatar, String srcFileDir, String avatarDir);
 
    /**
     * 开始录制小视频
     * @param fileName 存储小视频的本地文件的绝对路径
     * @param callback 录制小视频过程中的回调
     */
    public void startRecordingVideoMessage(String fileName, VideoMsgRecorderCallback callback);
 
    /**
     * 停止小视频的录制
     */
    public void stopRecordingVideoMessage();
 
    /**
     * 取消录制小视频的准备
     */
    public void unprepareRecordingVideoMessage();
 
    /**
     * 获取小视频文件的时长
     * @param fileName 存储小视频的本地文件的绝对路径
     * @return int 小视频的时长,单位毫秒
     */
    public int getVideoMessageDuration(String fileName);
 
    /**
     * 开始播放小视频,开始后视频内容循环播放,若播放语音,语音只播一遍
     * @param activity Acitivity对象,用于调整音量
     * @param fileName 存储小视频的本地文件的绝对路径
     * @param withAudio 是否播放声音
     * @param callback 播放小视频过程中的回调
     * @param useEarpiece 为TRUE时,使用听筒播放;为FALSE时,使用扬声器播放
     */
    public void startPlayingVideoMessage(Activity activity, String fileName, boolean withAudio, VideoMsgPlayerCallback callback, boolean useEarpiece);
 
    /**
     * 停止小视频的播放
     * @param fileName 存储小视频的本地文件的绝对路径
     * @param remainVideoPreview 是否保留视频的继续循环播放
     * @param stopAudio 尝试停止Audio设备
     * @param callback 播放小视频过程中的回调,作为区分同一文件在不同窗口中播放时的ID
     */
    public void stopPlayingVideoMessage(String fileName, boolean remainVideoPreview, boolean stopAudio, VideoMsgPlayerCallback callback);
 
    /**
     * 暂停或停止所有小视频的播放
     * @param removeCallbacks 为true时,将彻底停止所有小视频的播放;为false时,仅仅暂停,还可以通过restartAllPlayingVideoMessage()来恢复
     */
    public void stopAllPlayingVideoMessage(boolean removeCallbacks);
 
    /**
     * 尝试重新恢复之前暂停的所有小视频
     */
    public void restartAllPlayingVideoMessage();
}