直播Android推流外部数据采集


1. 如果您想自己加工视频数据

有些研发能力比较强的客户,会有自定义图像处理的需求(比如自定义图像滤镜),同时又希望复用rtmp sdk的整体流程,如果是这样,您可以按照如下攻略进行定制。

  • Step1. 实现一个图像处理的so
    您需要自己实现一个so,比如test.so,然后按照如下定义导出一个C风格的函数,之所以强制使用C而不是java是因为图像处理的效率C和C++比较容易胜任。您实现的PVideoProcessHookFunc 处理时间不能过长,试想,如果该函数的处理时间超过50ms,那就意味着SDK推出的视频流,其帧率不可能达到20FPS。

    /* @brief 客户自定义的视频预处理函数原型
    * @param yuv_buffer:视频YUV数据,格式固定是YUV420 Planar
    * @param len_buffer:数据长度
    * @param width:     视频width
    * @param height:    视频height
    * @return
    * @remark (1)该函数会被SDK同步调用,故您需要同步返回预处理后的数据
    *         (2)处理后的数据长度必须和处理前保持一致
    *         (3)您或者直接处理yuv_buffer,或者将处理后的数据memcpy到yuv_buffer所指的内存区域,
    *             这块内存的生命期由SDK负责管理(也就是释放)
    */
    typedef void (*PVideoProcessHookFunc)(unsigned char * yuv_buffer, int len_buffer, int width, int height);
    
  • Step2. 设置 setCustomModeType + setCustomVideoPreProcessLibrary
    它们是位于PushConfig中的两个设置项:
    setCustomModeType设置项用来声明“您希望自定义滤镜”,setCustomVideoPreProcessLibrary用来指定您自己的so的文件路径以及导出函数的名字。

    //libtest.so是step1中您自己用C/C++实现的图像处理函数库
    //MyVideoProcessFunc是该so导出的函数的名字,该函数必须符合step1中的PVideoProcessHookFunc定义
    int customMode |= TXLiveConstants.CUSTOM_MODE_VIDEO_PREPROCESS;
    String path = this.getActivity().getApplicationInfo().dataDir + "/lib";
    mLivePushConfig.setCustomModeType(customMode);
    mLivePushConfig.setCustomVideoPreProcessLibrary(path +"/libtest.so", "MyVideoProcessFunc");
    

2. 如果您想自己加工音频数据

类似视频数据处理思路,但是具体的函数和参数名称要换成音频相关的,java层示例代码如下:

customMode |= TXLiveConstants.CUSTOM_MODE_AUDIO_PREPROCESS; //可以和VIDEO_PREPROCESS一起设置
String path = this.getActivity().getApplicationInfo().dataDir + "/lib";
mLivePushConfig.setCustomModeType(customMode);
mLivePushConfig.setCustomAudioPreProcessLibrary(path +"/libtest.so", "MyAudioProcessFunc");

其中MyAudioProcessFunc应当遵循如下的函数声明:

/* @brief 客户自定义的音频预处理函数原型
 * @param pcm_buffer:   音频PCM数据
 * @param len_buffer:   数据长度
 * @param sample_rate:  采样频率
 * @param channels:     声道数
 * @param bit_size:     采样位宽
 * @return
 * @remark (1)该函数会被SDK同步调用,故您需要同步返回预处理后的数据
 *         (2)处理后的数据长度必须和处理前保持一致
 *         (3)您或者直接处理pcm_buffer,或者将处理后的数据memcpy到pcm_buffer所指的内存区域,
 *             这块内存的生命期由SDK负责管理(也就是释放)
 */
typedef void (*PAudioProcessHookFunc)(unsigned char * pcm_buffer, int len_buffer,
                                          int sample_rate, int channels, int bit_size);

3. 如果您只用SDK来推流

也有客户只是希望拿SDK用来推流,音视频采集部分由自己的代码控制,SDK用来做音视频编码和推流就可以了。
如果是这样,您可以按如下步骤实现:

  • Step1. 设置 setCustomModeType 和相关参数
    这里需要将CustomMode设置为CUSTOM_MODE_VIDEO_CAPTURE,含义是“不需要SDK采集音视频数据”,同时还需要设置视频分辨率。

    // (1)将 CustomMode 设置为:自己采集视频数据,SDK只负责编码发送
    int customMode |= TXLiveConstants.CUSTOM_MODE_VIDEO_CAPTURE; 
    mLivePushConfig.setCustomModeType(customMode);
    //
    // (2)设置视频编码参数,比如720p,相比如普通模式,VIDEO_CAPTURE模式您有六种分辨率可供选择
    //  VIDEO_RESOLUTION_TYPE_360_640:  pYUVBuff的分辨率必须符合360*640
    //  VIDEO_RESOLUTION_TYPE_540_960:  pYUVBuff的分辨率必须符合540*960
    //  VIDEO_RESOLUTION_TYPE_720_1280: pYUVBuff的分辨率必须符合720*1280
    //  VIDEO_RESOLUTION_TYPE_640_360:  pYUVBuff的分辨率必须符合640*360
    //  VIDEO_RESOLUTION_TYPE_960_540:  pYUVBuff的分辨率必须符合960*540
    //  VIDEO_RESOLUTION_TYPE_1280_720: pYUVBuff的分辨率必须符合1280*720
    mLivePushConfig.setVideoResolution(TXLiveConstants.VIDEO_RESOLUTION_TYPE_1280_720);
    
  • Step2. 使用 sendCustomYUVData 向SDK填充数据
    之后的工作就是向SDK塞入您自己准备好的视频数据(YUV420 Planar),剩下的编码和网络发送等工作交给SDK来解决。

    //(1)先启动推流,不然您给SDK数据它也不会处理
    mLivePusher.startPusher(rtmpUrl.trim());
    //
    //(2)此处示例代码我们用一个线程来模拟YUV数据发送
    new Thread() {
    @Override
    public void run() {
        while (true) {
            try {
                FileInputStream in = new FileInputStream("/sdcard/test_1280_720.yuv");
                int len = 1280 * 720 * 3 / 2;  //yuv格式为i420
                byte buffer[] = new byte[len];
                int count = 0;
                while ((count = in.read(buffer)) != -1) {
                    if (len == count) {
                        mLivePusher.sendCustomYUVData(buffer);
                    } else {
                        break;
                    }
                    sleep(50, 0);
                }
                in.close();
            }catch (Exception e) { 
                e.printStackTrace(); 
            }
         }
       }
    }.start();
    
  • Step3. 音频也是一样的
    音频也是同样的处理思路,只是使用对应的 CustomMode 应当设置为 CUSTOM_MODE_AUDIO_CAPTURE,于此同时,您也需要指定声音采样率等和声道数等关键信息。
    // (1)将 CustomMode 设置为:自己采集音频数据,SDK只负责编码&发送
    int customMode |= TXLiveConstants.CUSTOM_MODE_AUDIO_PREPROCESS; 
    mLivePushConfig.setCustomModeType(customMode);
    //
    // (2)设置音频编码参数:音频采样率和声道数
    mLivePushConfig.setAudioSampleRate(44100); 
    mLivePushConfig.setAudioChannels(1);
    
    之后,调用sendCustomPCMData向SDK塞入您自己的PCM数据即可。

你可能感兴趣的:(音视频开发,直播)