视频 Android SDK

更新时间:2019-07-22 11:50:43

Link Visual音视频模块使用说明:包含视频播放、语音对讲

工程配置

  • build.gradle依赖引入
// 1. 根build.gradle添加对aliyun maven仓库的引用
allprojects {
    repositories {
        maven {
            url "http://maven.aliyun.com/nexus/content/repositories/releases"
        }
    }
}

// 2. app build.gradle中添加依赖
implementation('com.aliyun.iotx:linkvisual-media:1.1.0')
  • 混淆文件配置(proguard-rules.pro)
# keep linkvisual

-keep class com.aliyun.iotx.linkvisual.media.** { *; }

# keep netty

-keepattributes Signature,InnerClasses

-keepclasseswithmembers class io.netty.** {
    *;
}

-dontwarn io.netty.**

-dontwarn sun.**

视频播放器

播放器按功能分为三种:
直播播放器

  • 用于RTMP直播源,具有时延低的特点.

  • 支持P2P(需使用接入LinkVisual设备端SDK的摄像头).

点播播放器

  • 用于设备录像回放的播放,可调整播放进度.

  • 支持P2P(需使用接入LinkVisual设备端SDK的摄像头).

HLS播放器

  • 用于云端录像回放的播放,支持AES-128加密的ts文件的播放.

FFmpeg使用版本为n4.0.1.
音频编码支持AAC_LC和G711a.
视频编码支持H264.
Android SDK封装ExoPlayer作为HLS的播放器,版本为2.8.3.

功能列表:

功能 直播播放器 设备录像播放器 HLS播放器
视频播放
音频播放
暂停/恢复 X
跳至指定位置播放 X
总时长 X
当前播放进度 X
播放器状态变更通知
设置播放音量
变速播放 X X
循环播放 X X
画面缩放模式设置
播放器截图 X
边播边录 X

使用指南

直播播放器

// 构造播放器实例
LivePlayer player = new LivePlayer();

// 设置surfaceview, 必须为GLSurfaceView
// 注意:GLSurfaceView必须在Activity的onResume和onPause回调方法中调用GLSurfaceView的onResume和onPause方法
player.setSurfaceView(GLSurfaceView);
// 设置必要的状态监听
player.setOnPlayerStateChangedListener(new OnPlayerStateChangedListener() {
    @Override
    public void onPlayerStateChange(int playerState) {
        Log.d(TAG, "play state= " + playerState);
        switch (playerState) {
            case Player.STATE_BUFFERING:
                break;
            case Player.STATE_IDLE:
                break;
            case Player.STATE_READY:
                break;
            case Player.STATE_ENDED:
                break;
            default:
                break;
        }
    }
});
// 设置错误监听
player.setOnErrorListener(new OnErrorListener() {
    @Override
    public void onError(PlayerException exception) {
        makeToast("errorcode: " + exception.getCode() + "\n" + exception.getMessage());
    }
});

// 设置rtmp地址.
player.setDataSource("rtmp://live.hkstv.hk.lxdns.com/live/hks2");
// 设置数据源就绪监听器
player.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared() {
        // 数据源就绪后开始播放
        player.start();
    }
});
player.prepare();
...
// 停止播放
player.stop();
...
// 释放播放器资源
player.release();

点播播放器

// 构造播放器实例
VodPlayer player = new VodPlayer();

// 设置surfaceview, 必须为GLSurfaceView
// 注意:GLSurfaceView必须在Activity的onResume和onPause回调方法中调用GLSurfaceView的onResume和onPause方法
player.setSurfaceView(GLSurfaceView);
// 设置必要的状态监听
player.setOnPlayerStateChangedListener(new OnPlayerStateChangedListener() {
    @Override
    public void onPlayerStateChange(int playerState) {
        Log.d(TAG, "play state= " + playerState);
        switch (playerState) {
            case Player.STATE_BUFFERING:
                break;
            case Player.STATE_IDLE:
                break;
            case Player.STATE_READY:
                break;
            case Player.STATE_ENDED:
                break;
            default:
                break;
        }
    }
});
// 设置错误监听
player.setOnErrorListener(new OnErrorListener() {
    @Override
    public void onError(PlayerException exception) {
        makeToast("errorcode: " + exception.getCode() + "\n" + exception.getMessage());
    }
});

// 设置支持点播的rtmp地址
player.setDataSource("rtmp://xxxx");
// 设置数据源就绪监听器
player.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared() {
        // 数据源就绪后开始播放
        player.start();
    }
});
player.prepare();
...
// 暂停播放
player.pause();
...
// 恢复播放
player.resume();
...
// 停止播放
player.stop();
...
// 释放播放器资源
player.release();

HLS播放器

ExoHlsPlayer player = new ExoHlsPlayer(getApplicationContext());

// 使用Exo的SimpleExoPlayerView来作为播放器的UI组件, 也可以自己实现UI组件
simpleExoPlayerView.setPlayer(player.getExoPlayer());
simpleExoPlayerView.requestFocus();
// 设置错误监听
player.setOnErrorListener(new OnErrorListener() {
    @Override
    public void onError(PlayerException exception) {
        makeToast("errorcode: " + exception.getCode() + "\n" + exception.getMessage());
    }
});
// 设置状态监听
player.setOnPlayerStateChangedListener(new OnPlayerStateChangedListener() {
    @Override
    public void onPlayerStateChange(int playerState) {
        switch (playerState) {
            case Player.STATE_BUFFERING:
                break;
            case Player.STATE_IDLE:
                break;
            case Player.STATE_READY:
                break;
            case Player.STATE_ENDED:
                break;
            default:
                break;
        }
    }
});

// 设置m3u8地址
player.setDataSource("http://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear3/prog_index.m3u8");
// 设置数据源就绪监听器
player.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared() {
        // 数据源就绪后开始播放
        player.start();
    }
});
player.prepare();
...
// 暂停播放
player.pause();
...
// 恢复播放
player.resume();
...
// 停止播放
player.stop();
...
// 释放播放器资源
player.release();

播放器状态

通过设置播放器状态监听器, 可接收到状态变更事件, 用于相关UI元素的变更.

  • IDLE: 播放器没有任何内容播放时的状态.

  • BUFFERING: 播放器正在缓冲, 当前的位置还不可以播放.

  • 状态变更事件如: 开始播放的缓冲、seek后重新缓冲.

  • READY: 播放器已经有内容在播放.

  • 状态变更事件如: 首帧数据已经渲染.

  • ENDED: 播放器已结束播放.

  • 状态变更事件如: 播放中发生错误、主动停止播放、内容播放完毕.

接口说明

LivePlayer

  • 构造方法
/**
     * 对于一般rtmp数据源,使用该构造方法初始化
     * 支持{@link #setDataSource(String)}
     * {@link #setDataSource(String, boolean, byte[], byte[])}的源
     */    
    LivePlayer();


    /**
     * 如需要支持IPC直播源,请使用该构造方法初始化
     *
     * @param context  application context
     * @param appKey   应用的appKey
     * @param authCode 安全图片auth code
     */
    LivePlayer(Context context, String appKey, String authCode);
  • 设置非加密播放源
/**
     * 设置播放源
     * @param url RTMP地址
     */
    void setDataSource(String url) throws IllegalArgumentException;
  • 设置加密播放源
/**
     * 设置加密播放源(请确保源是做过AES加密)
     * @param url         rtmp源地址
     * @param isEncrypted 是否是加密源
     * @param decryptIv   解密向量,16 byte array
     * @param decryptKey  解密密钥, 16 byte array
     * @throws IllegalArgumentException
     */
    void setDataSource(String url, boolean isEncrypted, byte[] decryptIv, byte[] decryptKey) throws IllegalArgumentException;
  • 设置IPC直播数据源(需使用LivePlayer(Context context, String appKey, String authCode)来初始化播放器)
/**
     * 设置IPC直播数据源.
     *
     * @param iotId            IPC设备的iotId
     * @param streamType       流的类型: 0-主码流,1-辅码流
     * @param relayEncrypted   云转是否加密
     * @param relayEncryptType 云转加密类型: 0-AES128
     * @param forceIFrame      是否需要强制I帧
     */
     void setIPCLiveDataSource(String iotId, int streamType, boolean relayEncrypted, int relayEncryptType, boolean forceIFrame);
  • 校验和准备数据
/**
     * 校验和准备数据
     */
    void prepare();
  • 开始播放视频
/**
     * 开始播放视频
     */
    void start();
  • 停止播放
/**
     * 停止播放
     */
    void stop();
  • 重置播放器
/**
     * 重置播放器
     */
    void reset();
  • 释放播放器资源
/**
     * 释放播放器资源
     */
    void release();
  • 截图
/**
     * 当前视频画面截图
     *
     * @return 如果当前无画面则返回 null
     */
    Bitmap snapShot();
  • 开始录屏
/**
     * 开始录制当前播放内容,生成MPEG-4格式转存到指定的文件中
     * 文件名后缀必须为.mp4
     * 须在{@link PlayerState#STATE_READY}时调用有效
     *
     * @param contentFile
     * @return 操作成功与否
     */
    boolean startRecordingContent(File contentFile) throws IOException;
  • 结束录屏
/**
     * 停止记录播放内容
     * @return 操作成功与否
     */
    boolean stopRecordingContent();
  • 设置播放器音量
/**
     * 设置播放器音量
     * @param audioVolume 范围 0-1, 0为静音
     */
    void setVolume(float audioVolume);
  • 设置音频流通道类型
/**
     * 设置音频流通道类型,see {@link android.media.AudioManager}
     * 如果音频正在播放,则会因为重新创建AudioTrack导致有短暂停顿.
     * @param streamType
     */
    void setAudioStreamType(int streamType);
  • 设置画面缩放模式
/**
     * 设置视频画面缩放模式, 默认为{@link android.media.MediaCodec#VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING}
     * @param videoScalingMode 参考:
     * {@link android.media.MediaCodec#VIDEO_SCALING_MODE_SCALE_TO_FIT}
     * {@link android.media.MediaCodec#VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING}
     */
    void setVideoScalingMode(int videoScalingMode);
  • 设置surfaceview
/**
     * 设置SurfaceView, 必须为GLSurfaceView
     * @param surfaceview
     */
    void setSurfaceView(SurfaceView surfaceview);
  • 清除surfaceview
/**
     * 清除surfaceview
     */
    void clearSurfaceView();
  • 设置数据源准备就绪事件监听器
/**
     * 设置数据源准备就绪事件监听器
     *
     * @param listener
     */
    void setOnPreparedListener(OnPreparedListener listener);
  • 设置播放器错误事件监听器
/**
     * 设置播放器错误事件监听器,错误类型参考:
     * {@link PlayerException.SOURCE_ERROR}
     * {@link PlayerException.RENDER_ERROR}
     * {@link PlayerException.UNEXPECTED_ERROR}
     * @param listener
     */
    void setOnErrorListener(OnErrorListener listener);
  • 设置播放状态变更事件监听器
/**
     * 设置播放状态变更事件监听器
     * @param listener
     */
    void setOnPlayerStateChangedListener(OnPlayerStateChangedListener listener);
  • 设置首帧被渲染事件监听器
/**
     * 设置首帧被渲染事件监听器
     * @param listener
     */
    void setOnRenderedFirstFrameListener(OnRenderedFirstFrameListener listener);
  • 获取音量
/**
     * 获取音量
     * @return 范围0-1
     */
    float getVolume();
  • 获取播放器状态
/**
     * 获取播放状态
     * @return 状态枚举,参考:
     * {@link PlayerState#STATE_IDLE} 播放器初始状态
     * {@link PlayerState#STATE_BUFFERING} 缓冲中状态
     * {@link PlayerState#STATE_READY} 缓冲结束开始播放状态
     * {@link PlayerState#STATE_ENDED} 播放完成状态
     */
    int getPlayState();
  • 获取播放器当前流的连接类型
/**
     * 获取播放器当前流的连接类型
     * 播放器状态为{@link PlayerState#STATE_READY}时调用有效
     *
     * @return {@link StreamConnectType}
     */
    StreamConnectType getStreamConnectType();
  • 获取播放器当前的帧率/码率等信息
/**
     * 获取播放器当前的帧率/码率等信息
     * 播放器状态为{@link PlayerState#STATE_READY}时调用有效
     *
     * @return 包含帧率/码率等信息的json string
     */
    PlayInfo getCurrentPlayInfo();

VodPlayer

  • 构造方法
/**
     * 对于一般rtmp数据源,使用该构造方法初始化
     * 支持{@link #setDataSource(String)}
     * {@link #setDataSource(String, boolean, byte[], byte[])}的源
     */    
    VodPlayer();


    /**
     * 如需支持IPC点播源,请使用该构造方法初始化,传入授权相关参数
     * 
     * @param context  application context
     * @param appKey   应用的appKey
     * @param authCode 安全图片auth code
     */
    VodPlayer(Context context, String appKey, String authCode);
  • 设置非加密播放源
/**
     * 设置播放源
     * @param url RTMP地址
     */
    void setDataSource(String url) throws IllegalArgumentException;
  • 设置加密播放源
/**
     * 设置加密播放源(请确保源是做过AES加密)
     * @param url         rtmp源地址
     * @param isEncrypted 是否是加密源
     * @param decryptIv   解密向量,16 byte array
     * @param decryptKey  解密密钥, 16 byte array
     * @throws IllegalArgumentException
     */
    void setDataSource(String url, boolean isEncrypted, byte[] decryptIv, byte[] decryptKey) throws IllegalArgumentException;
  • 设置播放源为IPC录像(按录像文件名).(需使用VodPlayer(Context context, String appKey, String authCode)来初始化播放器)
/**
     * 设置播放源为IPC录像(按录像文件名)
     *
     * @param iotId         设备iotId
     * @param fileName      录像文件名
     * @param encrypted     是否流需要加密
     * @param encryptType   流加密类型
     */
     void setDataSourceByIPCRecordFileName(String iotId, String fileName, boolean encrypted, int encryptType);
  • 设置播放源为IPC录像(按录像时间段). (需使用VodPlayer(Context context, String appKey, String authCode)来初始化播放器)
/** 
     * 设置播放源为IPC录像(按录像时间段)
     *
     * @param iotId         设备iotId
     * @param beginTime     开始时间 unix timestamp 精度到S
     * @param endTime       结束时间 unix timestamp 精度到S
     * @param encrypted     是否流需要加密
     * @param encryptType   流加密类型
     */
    public void setDataSourceByIPCRecordTime(String iotId, String beginTime, String endTime, boolean encrypted, int encryptType);
  • 校验和准备数据
/**
     * 校验和准备数据
     */
    void prepare();
  • 开始或恢复播放视频
/**
     * 开始播放或恢复播放视频
     */
    void start();
  • 暂停播放
/**
     * 暂停播放, 调用start()恢复播放
     */
    void pause();
  • seek到指定位置
/**
     * seek到指定位置
     * @param position 毫秒
     */
    void seekTo(long positionInMs);
  • 停止播放
/**
     * 停止播放
     */
    void stop();
  • 重置播放器
/**
     * 重置播放器
     */
    void reset();
  • 释放播放器资源
/**
     * 释放播放器资源
     */
    void release();
  • 截图
/**
     * 当前视频画面截图
     *
     * @return 如果当前无画面则返回 null
     */
    Bitmap snapShot();
  • 开始录屏
/**
     * 开始录制当前播放内容,生成MPEG-4格式转存到指定的文件中
     * 文件名后缀必须为.mp4
     * 须在{@link PlayerState#STATE_READY}时调用有效
     *
     * @param contentFile
     * @return 操作成功与否
     */
    boolean startRecordingContent(File contentFile) throws IOException;
  • 结束录屏
/**
     * 停止记录播放内容
     * @return 操作成功与否
     */
    boolean stopRecordingContent();
  • 设置播放器音量
/**
     * 设置播放器音量
     * @param audioVolume 范围 0-1, 0为静音
     */
    void setVolume(float audioVolume);
  • 设置音频流通道类型
/**
     * 设置音频流通道类型,see {@link android.media.AudioManager}
     * 如果音频正在播放,则会因为重新创建AudioTrack导致有短暂停顿.
     * @param streamType
     */
    void setAudioStreamType(int streamType);
  • 设置画面缩放模式
/**
     * 设置视频画面缩放模式, 默认为{@link android.media.MediaCodec#VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING}
     * @param videoScalingMode 参考:
     * {@link android.media.MediaCodec#VIDEO_SCALING_MODE_SCALE_TO_FIT}
     * {@link android.media.MediaCodec#VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING}
     */
    void setVideoScalingMode(int videoScalingMode);
  • 设置surfaceview
/**
     * 设置SurfaceView, 必须为GLSurfaceView
     * @param surfaceview
     */
    void setSurfaceView(SurfaceView surfaceview);
  • 清除surfaceview
/**
     * 清除surfaceview
     */
    void clearSurfaceView();
  • 设置数据源准备就绪事件监听器
/**
     * 设置数据源准备就绪事件监听器
     *
     * @param listener
     */
    void setOnPreparedListener(OnPreparedListener listener);
  • 设置播放器错误事件监听器
/**
     * 设置播放器错误事件监听器,错误类型参考:
     * {@link PlayerException.SOURCE_ERROR}
     * {@link PlayerException.RENDER_ERROR}
     * {@link PlayerException.UNEXPECTED_ERROR}
     * @param listener
     */
    void setOnErrorListener(OnErrorListener listener);
  • 设置播放状态变更事件监听器
/**
     * 设置播放状态变更事件监听器
     * @param listener
     */
    void setOnPlayerStateChangedListener(OnPlayerStateChangedListener listener);
  • 设置首帧被渲染事件监听器
/**
     * 设置首帧被渲染事件监听器
     * @param listener
     */
    void setOnRenderedFirstFrameListener(OnRenderedFirstFrameListener listener);
  • 获取当前播放进度
/**
     * 获取当前播放进度
     * 播放器状态为{@link PlayerState#STATE_READY}时调用有效
     * @return 单位MS
     */
    long getCurrentPosition();
  • 获取视频总时长
/**
     * 获取视频总时长
     * 播放器状态为{@link #STATE_READY}时调用有效
     * @return 单位MS
     */
    long getDuration();
  • 获取音量
/**
     * 获取音量
     * @return 范围0-1
     */
    float getVolume();
  • 获取播放器状态
/**
     * 获取播放状态
     * @return 状态枚举,参考:
     * {@link PlayerState#STATE_IDLE} 播放器初始状态
     * {@link PlayerState#STATE_BUFFERING} 缓冲中状态
     * {@link PlayerState#STATE_READY} 缓冲结束开始播放状态
     * {@link PlayerState#STATE_ENDED} 播放完成状态
     */
    int getPlayState();
  • 获取播放器当前流的连接类型
/**
     * 获取播放器当前流的连接类型
     * 播放器状态为{@link PlayerState#STATE_READY}时调用有效
     *
     * @return {@link StreamConnectType}
     */
    StreamConnectType getStreamConnectType();
  • 获取播放器当前的帧率/码率等信息
/**
     * 获取播放器当前的帧率/码率等信息
     * 播放器状态为{@link PlayerState#STATE_READY}时调用有效
     *
     * @return 包含帧率/码率等信息的json string
     */
    PlayInfo getCurrentPlayInfo();

ExoHlsPlayer

  • 构造方法
ExoHlsPlayer(Context context);
  • 设置m3u8播放地址
/**
     * 设置播放源
     * @param url m3u8地址
     */
    void setDataSource(String url);
  • 设置播放地址为IPC云存录像(按文件名)
/**
     * 设置播放地址为IPC云存录像(按文件名)
     *
     * @param iotId    设备iotId
     * @param fileName 录像文件名
     */
     void setDataSourceByIPCRecordFileName(String iotId, String fileName);
  • 校验和准备数据
/**
     * 校验和准备数据
     */
    void prepare();
  • 开始或恢复播放视频
/**
     * 开始播放或恢复播放视频
     */
    void start();
  • 暂停播放
/**
     * 暂停播放, 调用start()恢复播放
     */
    void pause();
  • seek到指定位置
/**
     * seek到指定位置
     * @param position 毫秒
     */
    void seekTo(long positionInMs);
  • 停止播放
/**
     * 停止播放
     */
    void stop();
  • 重置播放器
/**
     * 重置播放器
     */
    void reset();
  • 释放播放器资源
/**
     * 释放播放器资源
     */
    void release();
  • 设置是否循环播放
/**
    * 设置是否循环播放
    * @param circlePlay true 为循环播放
    */
    void setCirclePlay(boolean circlePlay);
  • 设置回放速率
/**
    * 设置回放的播放速率
    * @param speed 速率因子,需大于0
    */
    void setPlaybackSpeed(float speed);
  • 设置播放器音量
/**
     * 设置播放器音量
     * @param audioVolume 范围 0-1, 0为静音
     */
    void setVolume(float audioVolume);
  • 设置音频流通道类型
/**
     * 设置音频流通道类型,see {@link android.media.AudioManager}
     * 如果音频正在播放,则会因为重新创建AudioTrack导致有短暂停顿.
     * @param streamType
     */
    void setAudioStreamType(int streamType);
  • 设置画面缩放模式
/**
     * 设置视频画面缩放模式, 默认为{@link android.media.MediaCodec#VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING}
     * @param videoScalingMode 参考:
     * {@link android.media.MediaCodec#VIDEO_SCALING_MODE_SCALE_TO_FIT}
     * {@link android.media.MediaCodec#VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING}
     */
    void setVideoScalingMode(int videoScalingMode);
  • 设置surfaceview
/**
     * 设置SurfaceView
     * @param surfaceview
     */
    void setSurfaceView(SurfaceView surfaceview);
  • 清除surfaceview
/**
     * 清除surfaceview
     */
    void clearSurfaceView();
  • 设置数据源准备就绪事件监听器
/**
     * 设置数据源准备就绪事件监听器
     *
     * @param listener
     */
    void setOnPreparedListener(OnPreparedListener listener);
  • 设置播放器错误事件监听器
/**
     * 设置播放器错误事件监听器,错误类型参考:
     * {@link PlayerException.SOURCE_ERROR}
     * {@link PlayerException.RENDER_ERROR}
     * {@link PlayerException.UNEXPECTED_ERROR}
     * @param listener
     */
    void setOnErrorListener(OnErrorListener listener);
  • 设置播放状态变更事件监听器
/**
     * 设置播放状态变更事件监听器
     * @param listener
     */
    void setOnPlayerStateChangedListener(OnPlayerStateChangedListener listener);
  • 设置首帧被渲染事件监听器
/**
     * 设置首帧被渲染事件监听器
     * @param listener
     */
    void setOnRenderedFirstFrameListener(OnRenderedFirstFrameListener listener);
  • 获取当前播放进度
/**
     * 获取当前播放进度
     * 播放器状态为{@link PlayerState#STATE_READY}时调用有效
     * @return 单位MS
     */
    long getCurrentPosition();
  • 获取视频总时长
/**
     * 获取视频总时长
     * 播放器状态为{@link #STATE_READY}时调用有效
     * @return 单位MS
     */
    long getDuration();
  • 获取音量
/**
     * 获取音量
     * @return 范围0-1
     */
    float getVolume();
  • 获取播放器状态
/**
     * 获取播放状态
     * @return 状态枚举,参考:
     * {@link PlayerState#STATE_IDLE} 播放器初始状态
     * {@link PlayerState#STATE_BUFFERING} 缓冲中状态
     * {@link PlayerState#STATE_READY} 缓冲结束开始播放状态
     * {@link PlayerState#STATE_ENDED} 播放完成状态
     */
    int getPlayState();

错误列表

错误枚举 描述
PlayerException.SOURCE_ERROR 数据源错误
PlayerException.RENDER_ERROR 渲染错误
PlayerException.UNEXPECTED_ERROR 不符合预期的错误

语音对讲

提供App和IPC设备之间端到端的双向实时音频传输能力.

语音对讲支持双工模式. App端需要做: 发起开始语音对讲请求->交换音频参数->音频采集-> 音频编码(可选)-> 上传/接收 -> 音频解码(可选) -> 音频播放->停止语音对讲 这些流程.

音频格式支持情况:

编码 解码
PCM - -
AAC_LC
G711A
G711U

使用指南

语音对讲集成分为以下几个步骤:

  1. 创建语音对讲实例
// 创建语音对讲实例,appkey和authcode参考平台文档
    liveIntercom = new LiveIntercom(getApplicationContext(), appKey,
            authcode);
  1. 注册和处理语音对讲错误回调
  2. 在语音对讲通道建立以及对讲中时都可能发生错误,需要处理,错误类型详见错误列表.
// 设置语音对讲错误回调 
    liveIntercom.setOnErrorListener(new com.aliyun.iotx.linkvisual.media.audio.listener.OnErrorListener() {
        @Override
        public void onError(LiveIntercomException error) {
            showToast(error.getMessage());
            error.printStackTrace();
            // 处理语音对讲错误,如停止录音机, 重置UI元素等
        }
    });
  1. 注册和处理对端音频参数变更回调
  2. 当语音对讲通道建立后,会先收到设备端发送过来的音频参数信息,后续设备端发送的音频数据按照此音频参数来做解码. 该事件是语音对讲通道建立成功的标志. 可以在此时构建播放器实例用于设备端采集音频的实时播放.
// 设置对端音频参数变更回调
    liveIntercom.setOnAudioParamsChangeListener(new OnAudioParamsChangeListener() {
        @Override
        public void onAudioParamsChange(AudioParams audioParams) {
            showToast("可以开始说话了");
            // 收到对端发送的音频参数,有该音频参数说明对端准备就绪,从开始录音到收到该信号之间的录音数据可按产品定义选择是否缓存并发送.
        }
    });
  1. 注册和处理对端音频数据接收回调
  2. 语音对讲中会持续不断的收到对端发送过来的音频数据.
// 设置对端音频数据回调         
    liveIntercom.setOnAudioBufferReceiveListener(new OnAudioBufferReceiveListener() {
            @Override
            public void onAudioBufferRecevie(byte[] bytes, int i) {
            //收到对端发过来的音频数据, 送入播放器播放
            }
        });
  1. 音频采集和发送
  2. SDK提供了录音机(SimpleAudioRecord)和流音频播放器(SimpleStreamAudioTrack), 可用于语音对讲音频采集和播放.作为一种参考实现.
// 创建录音机用于采集pcm数据
    audioRecord = new SimpleAudioRecord(AudioSource.VOICE_COMMUNCATION,AudioParams.AUDIOPARAM_MONO_8K_PCM);
    audioRecord.setAudioRecordListener(new AudioRecordListener() {
        @Override
        public void onRecordStart() {
            Log.d(TAG, "onRecordStart");
            // 录音开始后,再启动语音对讲,指定SDK将音频数据转成G711A格式后再发送
            liveIntercom.start(iotId, AudioParams.AUDIOPARAM_MONO_8K_G711A);
        }

        @Override
        public void onRecordEnd() {
            Log.d(TAG, "onRecordEnd");
            // 录音结束时, 关闭语音对讲
            liveIntercom.stop();
        }

        @Override
        public void onBufferReceived(byte[] buffer, int offset, int size) {
            Log.d(TAG, "onBufferReceived:" + size);
            // 收到录音机PCM数据,调用语音对讲接口发送给对端
            liveIntercom.sendAudioBuffer(buffer, offset, size);
        }

        @Override
        public void onError(int error, String message) {
            Log.e(TAG, "onError:" + error + message);
            showToast("录音机错误:" + error + message);
            // 处理录音机错误,如停止语音对讲、重置UI元素等
        }
    });

    // 启动录音机
    audioRecord.start();

关于回声消除:
Android设备差异较大,即使设置采集源为AudioSource.VOICE_COMMUNCATION或使用AcousticEchoCanceler在有些手机上也并未启用回声抑制,如对效果有较高的要求,可自行实现AEC(如用Speex或WebRTC来实现).

接口说明

LiveIntercom

  • 构造方法
/**
     * 构造语音对讲实例
     *
     * @param context  Application Context
     * @param appKey   应用Appkey
     * @param authCode 安全图片authcode
     */
    LiveIntercom(Context context, final String appKey, final String authCode)
  • 开始语音对讲
/**
     * 建立语音对讲通道
     *
     * @param iotId iotId 设备iotId
     * @param audioParams 指定App端上行音频参数格式,如采样率、通道数、采样位宽、音频格式, 请确保对端能支持该音频参数配置
     */
    void start(String iotId, AudioParams audioParams);
  • 关闭语音对讲
/**
     * 关闭语音对讲通道
     *
     * @return
     */
    void stop();
  • 设置接收对端音频数据回调
/**
     * 设置接收对端音频数据回调
     * 数据格式为PCM
     * @param listener
     */
    void setOnAudioBufferReceiveListener(OnAudioBufferReceiveListener listener);
  • 设置对端音频参数变更回调
/**
     * 设置对端音频参数变更回调接口,语音通道刚建立成功或对端音频参数变更时会被回调
     * @param listener
     */
    void setOnAudioParamsChangeListener(OnAudioParamsChangeListener listener);
  • 发送语音数据
/**
     * 发送音频数据
     * 数据格式为PCM
     * 内部会依据{@link #start(String, AudioParams)}时传入的音频格式来做重新编码
     * 若语音对讲还未建立成功,送入的数据将会被丢弃
     *
     * @param data
     * @param offset
     * @param length
     */
    void sendAudioBuffer(byte[] data, int offset, int length);
  • 设置错误回调
/**
     * 设置错误回调接口
     *
     * @param listener
     */
    void setOnErrorListener(OnErrorListener listener);

SimpleAudioRecord

  • 创建录音机实例
/**

* 按照指定的音频参数创建录音机实例子

* @param audioSource 指定源

* @param audioParams 指定录音机的通道数、采样率、采样位宽

*/
SimpleAudioRecord(int audioSource, AudioParams audioParams);
  • 启动录音
void start();
  • 获取AudioSession id
int getAudioSessionId()
  • 设置录音事件回调
void setAudioRecordListener(AudioRecordListener listener)

public interface AudioRecordListener {

    /**
     * 开始录音
     */
    void onRecordStart();

    /**
     * 结束录音
     */
    void onRecordEnd();

    /**
     * 录音数据回调(PCM数据)
     * @param buffer
     * @param offset
     * @param size
     */
    void onBufferReceived(byte[] buffer, int offset, int size);

    /**
     * 录音机错误
     * {@link SimpleAudioRecord#ERR_INIT_RECORD}
     * {@link SimpleAudioRecord#ERR_READ_BUFFER}
     * {@link SimpleAudioRecord#ERR_START_RECORD}
     * @param error
     * @param message
     */
    void onError(int error, String message);
}
  • 结束录音
void stop();

SimpleStreamAudioTrack

  • 创建播放器实例
/**
     * 创建流播放器
     *
     * @param audioParams     音频参数
     * @param audioStreamType 流类型,见{@link android.media.AudioManager}
     * @param audioBuffer     数据阻塞队列,向该队列中加入数据即播放
     * @param audioSessionId  audio session id,用于回声消除
     * @throws IllegalArgumentException
     */
SimpleStreamAudioTrack(AudioParams audioParams, int audioStreamType, BlockingQueue audioBuffer) throws IllegalArgumentException;
  • 开始播放
void start()
  • 恢复播放
void resume()
  • 暂停播放
void pause()
  • 停止播放
void stop()
  • 获取播放状态,见AudioTrack#PLAYSTATE
int getPlayState()
  • 设置播放音量
void setVolume(float volume)
  • 释放播放器
void release()

错误列表

错误枚举 描述
LiveIntercomException.INVALID_AUDIO_PARAMS 无效的语音对讲音频参数(对端上报的音频参数SDK不支持)
LiveIntercomException.START_LIVE_INTERCOM_REQUEST_FAILED 启动语音对讲失败
LiveIntercomException.CONNECTION_STREAM_FAILED 语音流建立失败
LiveIntercomException.SEND_STREAM_DATA_FAILED 发送语音流数据失败
LiveIntercomException.RECEIVE_STREAM_DATA_FAILED 接收语音流数据失败

ChangeLog

1.0.0:

  • 初始版本

  • 1.1.0:

  • 包名由LinkVision变更为LinkVisual

  • 适配服务端API2.0.0接口

  • 移除ExoHlsPlayer中的void setDataSourceByIPCRecordEventId(String iotId, String eventId)方法

  • 修改按时间请求本地录像播放地址接口入参类型为int

  • 修复前一个播放器实例销毁中下一个实例创建偶现的画面残影问题

  • 修复若干稳定性问题


版权信息

librtmp

Copyright (C) 2005-2008 Team XBMC
     http://www.xbmc.org
     Copyright (C) 2008-2009 Andrej Stepanchuk
     Copyright (C) 2009-2010 Howard Chu

 librtmp is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as
 published by the Free Software Foundation; either version 2.1,
 or (at your option) any later version.

 librtmp is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 GNU General Public License for more details.

 You should have received a copy of the GNU Lesser General Public License
 along with librtmp see the file COPYING.  If not, write to
 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 Boston, MA  02110-1301, USA.
 http://www.gnu.org/copyleft/lgpl.html

FFmpeg

FFmpeg is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

FFmpeg is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with FFmpeg; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

results matching ""

    No results matching ""