This topic describes how to use AliLive SDK for Android.

Stream ingest over RTMP

Note ApsaraVideo Live does not support multiple streams ingested to a URL at the same time. If you ingest multiple streams, the second stream is rejected.
  1. Create an AliLiveEngine object.
    // Create an AliLiveRTMPConfig object.
    AliLiveRTMPConfig rtmpConfig = new AliLiveRTMPConfig();
    // Initialize the bitrate settings.
    rtmpConfig.videoInitBitrate = 1000;
    rtmpConfig.videoTargetBitrate = 1500;
    rtmpConfig.videoMinBitrate = 600;
    // Create an AliLiveConfig object.
    AliLiveConfig mAliLiveConfig = new AliLiveConfig(rtmpConfig);
    // Initialize the resolution and frame rate, specify whether to enable high-definition preview, and then specify the default image to be displayed after a pause.
    mAliLiveConfig.videoFPS = 20;
    mAliLiveConfig.videoPushProfile = AliLiveConstants.AliLiveVideoPushProfile.AliLiveVideoProfile_540P;
    mAliLiveConfig.enableHighDefPreview = false;
    mAliLiveConfig.pauseImage = bitmap;
    mAliLiveConfig.accountId = "";
    AliLiveEngine mAliLiveEngine = AliLiveEngine.create(PushActivity.this, mAliLiveConfig);
  2. Start preview.
    // Create a preview view.
    AliLiveRenderView mAliLiveRenderView = mAliLiveEngine.createRenderView(false);
    // Add the preview view to the layout.
    addSubView(mAliLiveRenderView);
    // Set the preview mode.
    mAliLiveEngine.setPreviewMode(AliLiveRenderModeAuto, AliLiveRenderMirrorModeOnlyFront);
    // Start the preview.
    mAliLiveEngine.startPreview(mAliLiveRenderView);
  3. Start to ingest streams.
    mAliLiveEngine.startPush(mPushUrl);
  4. Stop pulling streams.
    // Stop the preview.
    mAliLiveEngine.stopPreview();
    // Stop ingesting streams.
    mAliLiveEngine.stopPush();
    // Destroy the AliLiveEngine object.
    mAliLiveEngine.destroy();
    mAliLiveEngine = null;

Stream pulling over RTMP

  1. Create a player.
    // Create a player.
    mAliPlayer = AliPlayerFactory.createAliPlayer(this.getApplicationContext());
    // Enable autoplay.
    mAliPlayer.setAutoPlay(true);
    // Set the mMaxDelayTime parameter. We recommend that you set the parameter to a value in the range of 500 to 5000. A smaller value indicates a smaller live streaming latency, but a greater chance of stuttering. Set the parameter as needed.
    PlayerConfig config = mAliPlayer.getConfig();
    config.mMaxDelayTime = 1000;
    mAliPlayer.setConfig(config);
  2. Add the SurfaceView view.
        mSurfaceView.getHolder().addCallback(this);
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            if (mAliPlayer!=null){
                mAliPlayer.setSurface(holder.getSurface());
            }
        }
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            if (mAliPlayer!=null){
                mAliPlayer.surfaceChanged();
            }
        }
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            if (mAliPlayer!=null){
                mAliPlayer.setSurface(null);
            }
        }
  3. Start to pull streams.
    // Set the source URL for the player.
    UrlSource source = new UrlSource();
    source.setUri(mPullUrl);
    mAliPlayer.setDataSource(source);
    // Start to pull streams.
    mAliPlayer.prepare();
  4. Stop pulling streams.
    mAliPlayer.stop();
    mAliPlayer.setSurface(null);
    mAliPlayer.release();
    mAliPlayer = null;

Streamer challenge

  1. Streamer A sends a request to the AppServer to query other online streamers who allow co-stream requests.
    mSocketHandler.send(getSendMessage(CMD_GET_ROOM_LIST));

    Streamer A renders the obtained list of streamers to the UI of the application.

    mOnlineRoomView.setRoomList(onlineRoomList);
  2. Streamer A sends a challenge request to Streamer B in the list.
    mSocketHandler.send(getSendMessage(CMD_APPLY_PK,room.getUserId(),room.getRoomId()));
  3. Streamer B receives a notification about the challenge request from Streamer A.
    showApplyPkDialog(applyPkNoticeBean);
  4. Streamer B accepts the challenge request from Streamer A, starts to pull RTC streams, and then sends a message indicating that the challenge request is accepted.
    // Subscribe to the RTC streams that are ingested by Streamer A.
    startPk(mLastApplyPkNotice.getFromRtcPullUrl());
    // Send a message indicating that the challenge request is accepted.
    mSocketHandler.send(getSendMessage(CMD_APPROVE_PK,true ,mLastApplyPkNotice.getFromUserId(),mLastApplyPkNotice.getFromRoomId() ));
  5. After Streamer A receives the message indicating that Streamer B accepts the challenge request, Streamer A starts to pull RTC streams.
    // Start the challenge.
    startPk(approvePkNoticeBean.getRtcPullUrl());
  6. After the onSubscribeResult callback indicating successful subscription is received, Streamer A adjusts the layout of the preview view and subscription view.
    showPkSurfaceView(true);
  7. The RTMP streaming URL on the audience clients changes. After the NotifyPublish message is received, the audience clients construct a new streaming URL for the player.
    // Check whether the source URL is the same as the previous source URL used by Streamer A. If they are different, reingest streams.
    if (!mRoomInfo.getRtmpPullUrl().equals(noticePublish.getAnchorRtmpPullUrl())){
        mRoomInfo.setRtmpPullUrl(noticePublish.getAnchorRtmpPullUrl());
        startPlayRTMP();
    }
  8. Streamer B stops the challenge, sends a message indicating that the challenge is stopped, stops pulling RTC streams, and then restores the UI before the challenge.
    // Send a message indicating that the challenge is stopped.
    mSocketHandler.send(getSendMessage(CMD_CANCEL_PK));
    // Restore the UI before the challenge.
    showPkSurfaceView(false);
  9. The RTMP streaming URL on the audience clients changes. After the NotifyPublish message is received, the audience clients construct a new streaming URL for the player.
    // Check whether the source URL is the same as the previous source URL used by Streamer A. If they are different, reingest streams.
    if (!mRoomInfo.getRtmpPullUrl().equals(noticePublish.getAnchorRtmpPullUrl())){
        mRoomInfo.setRtmpPullUrl(noticePublish.getAnchorRtmpPullUrl());
        startPlayRTMP();
    }