All Products
Search
Document Center

:Use Push SDK for Flutter

Last Updated:Mar 22, 2024

This topic describes how to use Push SDK for Flutter and provides examples on relevant features.

Features

  • Supports stream ingest over Real-Time Messaging Protocol (RTMP).

  • Supports stream ingest over Alibaba Real-Time Communication (ARTC) based on User Datagram Protocol (UDP).

  • Adopts H.264 for video encoding and Advanced Audio Coding (AAC) for audio encoding.

  • Supports custom configurations for features such as bitrate control, resolution, and display mode.

  • Supports various camera-related operations.

  • Supports real-time retouching and custom configurations on retouching effects.

  • Allows you to add animated stickers as animated watermarks and remove animated stickers.

  • Supports external audio and video inputs in different formats such as YUV and pulse-code modulation (PCM).

  • Supports ingest of audio-only streams and stream ingest in the background.

  • Supports background music and allows you to manage background music.

  • Supports the capture of video snapshots.

  • Supports automatic reconnection and error handling.

  • Supports the audio 3A algorithm.

  • Allows you to switch between the software and hardware encoding modes for video files. This improves the stability of the encoding module.

Limits

Take note of the following limits when you use Push SDK for Flutter:

  • You must configure screen orientation before stream ingest. You cannot change screen orientation during live streaming.

  • You must disable auto screen rotation for stream ingest in landscape mode.

  • In hardware encoding mode, the value of the output resolution must be a multiple of 16 to be compatible with the encoder. For example, if you set the resolution to 540p, the output resolution is 544 × 960. You must specify a view size for the player based on proportional scaling of the output resolution to prevent black bars.

Procedure

The following table describes the procedure of using Push SDK for Flutter.

Step

Operation

1. Register the SDK.

Configure license-related parameters to register Push SDK for Flutter. The stream ingest feature can be used only after the SDK is registered by calling the registration function.

2. Configure stream ingest parameters.

Configure the settings of the stream ingest feature such as the basic parameters, bitrate control mode, and adaptive resolution.

3. Perform stream ingest.

After you initialize Push SDK for Flutter, register stream ingest callbacks, and create a preview view, you can start steam ingest. You can perform a variety of operations during steam ingest. For example, you can manage streams, configure background music, configure camera settings, ingest external audio sources, and add animated stickers based on your business requirements.

Note

ApsaraVideo Live does not allow you to ingest multiple streams to a URL at the same time. If you attempt to ingest multiple streams at the same time, only the first stream is ingested.

Register the SDK

Push SDK for Flutter uses an all-in-one license. For more information about how to apply for and configure a license, see Integrate a Push SDK license.

You must register Push SDK for Flutter before you can use the stream ingest feature.

  1. Create an AlivcBase instance.

    /// Import a header file.
    import 'package:flutter_livepush_plugin/live_base.dart';
    
    AlivcBase alivcBase = AlivcBase.init();
  2. Register the SDK.

    Important

    Before you call the method to register the SDK, you must configure the license.

    alivcBase.registerSDK();
  3. Configure the listener for callbacks.

    alivcBase.registerSDK();
  4. Configure the callback for license verification.

    alivcBase.setOnLicenceCheck((result, reason) {
        if (result == AlivcLiveLicenseCheckResultCode.success) {
          // The SDK is registered.
        }
    });
  5. Call other methods of AlivcBase.

    /// Obtain the version number of Push SDK.
    String sdkVersion = await AlivcBase.getSdkVersion();
    
    /// Enable logging for the console.
    AlivcBase.setConsoleEnable(true);
    
    /// Set the log level to Debug.
    AlivcBase.setLogLevel(AlivcLivePushLogLevel.debug);
    /// Specify the log path.
    String logPath = "xxxx"; // xxxx indicates the path in the phone.
    int maxPartFileSizeInKB = 100 * 1024 * 1024; // The custom settings.
    AlivcBase.setLogPath(logPath, maxPartFileSizeInKB);

Configure stream ingest parameters

  1. Create an AlivcLivePusher instance.

    /// Import header files.
    import 'package:flutter_livepush_plugin/live_pusher.dart';
    import 'package:flutter_livepush_plugin/live_push_config.dart';
    
    AlivcLivePusher livePusher = AlivcLivePusher.init();
  2. Create a Config object to associate AlivcLivePusherConfig with AlivcLivePusher.

    livePusher.createConfig();
  3. Create an AlivcLivePusherConfig instance.

    AlivcLivePusherConfig pusherConfig = AlivcLivePusherConfig.init();
  4. Configure basic settings for stream ingest based on your business requirements.

    Each parameter in the basic settings has a default value. We recommend that you use the default values. Sample code:

    /// Set the resolution to 540p.
    pusherConfig.setResolution(AlivcLivePushResolution.resolution_540P);
    /// Specify the frame rate. We recommend that you set the frame rate to 20 frames per second (FPS).
    pusherConfig.setFps(AlivcLivePushFPS.fps_20);
    /// Enable adaptive bitrate streaming. The default value is true.
    pusherConfig.setEnableAutoBitrate(true);
    /// Specify the group of pictures (GOP) size. A larger value indicates a higher latency. We recommend that you set the value to 1 or 2.
    pusherConfig.setVideoEncodeGop(AlivcLivePushVideoEncodeGOP.gop_2);
    /// Specify the reconnection interval. The value cannot be less than 1000. Unit: milliseconds. We recommend that you use the default value. 
    pusherConfig.setConnectRetryInterval(2000);
    /// Disable the mirroring mode for preview.
    pusherConfig.setPreviewMirror(false);
    /// Set the stream ingest orientation to portrait.
    pusherConfig.setOrientation(AlivcLivePushOrientation.portrait);
  5. Specify the bitrate control mode.

    You can configure the AlivcLivePushQualityMode parameter to specify the bitrate control mode. The following table describes the bitrate control modes that are supported by Push SDK for Flutter. Configure bitrate control parameters based on your requirements.

    Bitrate control mode

    Description

    Sample code

    AlivcLivePushQualityMode.resolution_first

    The quality-first mode. Push SDK for Flutter configures bitrate parameters to prioritize the quality of video streams.

    pusherConfig.setQualityMode(AlivcLivePushQualityMode.resolution_first);

    AlivcLivePushQualityMode.fluency_first

    The smoothness-first mode. Push SDK for Flutter configures bitrate parameters to prioritize the smoothness of video streams.

    pusherConfig.setQualityMode(AlivcLivePushQualityMode.fluency_first);

    AlivcLivePushQualityMode.custom

    The custom mode. Push SDK for Flutter configures bitrate parameters based on your custom settings. If you use the custom mode, you can select quality-first or smoothness-first based on your business requirements and specify the initial, minimum, and expected bitrates.

    • initialVideoBitrate: the initial bitrate when a live stream starts.

    • minVideoBitrate: In poor network conditions, the bitrate is gradually reduced to the minimum bitrate to prevent stuttering.

    • targetVideoBitrate: In good network conditions, the bitrate is gradually increased to the expected bitrate to improve the quality of a video stream.

    pusherConfig.setQualityMode(AlivcLivePushQualityMode.custom);

    Note
    • If you use the quality-first or smoothness-first mode, you do not need to call setInitialVideoBitrate, setMinVideoBitrate, and setTargetVideoBitrate to specify the initial bitrate, minimum bitrate, and desired bitrate. Push SDK for Flutter automatically ensures the quality or smoothness of video streams if network jitters occur.

    • If you use the custom mode, configure the bitrate parameters based on the recommended settings. The following tables describe the recommended settings.

    Recommended settings for custom bitrate in quality-first mode

    Resolution

    initialVideoBitrate

    minVideoBitrate

    targetVideoBitrate

    360p

    600

    300

    1000

    480p

    800

    300

    1200

    540p

    1000

    600

    1400

    720p

    1500

    600

    2000

    1080p

    1800

    1200

    2500

    Recommended settings for custom bitrate in smoothness-first mode

    Resolution

    initialVideoBitrate

    minVideoBitrate

    targetVideoBitrate

    360p

    400

    200

    600

    480p

    600

    300

    800

    540p

    800

    300

    1000

    720p

    1000

    300

    1200

    1080p

    1500

    1200

    2200

  6. Configure the adaptive resolution feature.

    The adaptive resolution feature is used to dynamically adjust the resolution of a stream. After you enable the adaptive resolution feature, the resolution is automatically reduced to ensure the smoothness and quality of video streams in poor network conditions. Sample code:

    /// Enable the adaptive resolution feature.
    pusherConfig.setEnableAutoResolution(true);
    Important
    • The adaptive resolution feature is not supported by all players. If you need to use this feature, we recommend that you use ApsaraVideo Player.

    • The adaptive resolution feature takes effect only if you use the quality-first or smoothness-first mode by configuring the AlivcLivePushQualityMode parameter. This feature is unavailable if you use the custom mode.

  7. Configure image ingest.

    Push SDK for Flutter allows you to ingest images when your application is switched to the background or the bitrate is low. This improves user experience. When your application is switched to the background, video stream ingest is paused. In this case, only audio streams are ingested. You can also specify an image that you want to ingest. Sample code:

    /// Specify the image that is displayed if stream ingest is paused.
    String pauseImagePath = "xxxx"; // xxxx is the path of the image.
    pusherConfig.setPauseImg(pauseImagePath);

    You can specify a static image for stream ingest in poor network conditions. If the bitrate is low, the image that you specify is ingested to prevent stuttering. Sample code:

    /// Specify the image that is displayed in poor network conditions.
    String networkPoorImagePath = "xxxx"; // xxxx is the path of the image.
    pusherConfig.setNetworkPoorImg(networkPoorImagePath);
  8. Specify the preview mode.

    Push SDK supports three preview modes. The preview mode does not affect stream ingest.

    • AlivcPusherPreviewDisplayMode.preview_scale_fill: In this mode, the video fills the entire preview window. If the aspect ratio of the video is different from that of the preview window, deformation occurs during preview.

    • AlivcPusherPreviewDisplayMode.preview_aspect_fit: In this mode, the original aspect ratio of the video is used during preview. If the aspect ratio of the video is different from that of the preview window, black bars appear in the preview window.

    • AlivcPusherPreviewDisplayMode.preview_aspect_fill: In this mode, the video is cropped to fit the preview window during preview. If the aspect ratio of the video is different from that of the preview window, the video is cropped.

    Sample code:

    /// Set the preview mode to AlivcPusherPreviewDisplayMode.preview_aspect_fit.
    pusherConfig.setPreviewDisplayMode(AlivcPusherPreviewDisplayMode.preview_aspect_fit);
  9. Reset the Config object on iOS.

    You can call this method to clear the settings that are configured by the Config object if you no longer need to use AlivcLivePusherConfig on iOS.

    We recommend that you call this method after you call the destroy method of AlivcLivePusher.

    /// Reset the Config object on iOS.
    livePusher.destroyConfigForIOS();

Perform stream ingest

  1. Create a stream ingest engine.

    livePusher.initLivePusher();
  2. Register stream ingest listeners.

    /// Configure the listener for the stream ingest status.
    livePusher.setInfoDelegate();
    /// Configure the listener for stream ingest errors.
    livePusher.setErrorDelegate();
    /// Configure the listener for the network status during stream ingest.
    livePusher.setNetworkDelegate();
  3. Configure callbacks related to stream ingest.

    /// The callbacks for stream ingest errors.
    /// Configure the callback for SDK errors.
    livePusher.setOnSDKError((errorCode, errorDescription) {});
    /// Configure the callback for system errors.
    livePusher.setOnSystemError((errorCode, errorDescription) {});
    
    /// The callbacks for the stream ingest status.
    /// Configure the callback for preview start.
    livePusher.setOnPreviewStarted(() {});
    /// Configure the callback for preview stop.
    livePusher.setOnPreviewStoped(() {});
    /// Configure the callback for first frame rendering.
    livePusher.setOnFirstFramePreviewed(() {});
    /// Configure the callback for start of stream ingest.
    livePusher.setOnPushStarted(() {});
    /// Configure the callback for pause of stream ingest from the camera.
    livePusher.setOnPushPaused(() {});
    /// Configure the callback for resume of stream ingest from the camera.
    livePusher.setOnPushResumed(() {});
    /// Configure the callback for restart of stream ingest.
    livePusher.setOnPushRestart(() {});
    /// Configure the callback for end of stream ingest.
    livePusher.setOnPushStoped(() {});
    
    /// The callbacks for the network status during stream ingest
    /// Configure the callback for failed connection of stream ingest.
    livePusher.setOnConnectFail((errorCode, errorDescription) {});
    /// Configure the callback for network recovery.
    livePusher.setOnConnectRecovery(() {});
    /// Configure the callback for network disconnection.
    livePusher.setOnConnectionLost(() {});
    /// Configure the callback for poor network conditions.
    livePusher.setOnNetworkPoor(() {});
    /// Configure the callback for failed reconnection.
    livePusher.setOnReconnectError((errorCode, errorDescription) {});
    /// Configure the callback for reconnection start.
    livePusher.setOnReconnectStart(() {});
    /// Configure the callback for successful reconnection.
    livePusher.setOnReconnectSuccess(() {});
  4. Create a preview view for stream ingest.

    var x = 0.0; // The custom value.
    var y = 0.0; // The custom value.
    var width = MediaQuery.of(context).size.width; // The custom value.
    var height = MediaQuery.of(context).size.height; // The custom value.
    AlivcPusherPreview pusherPreviewView = AlivcPusherPreview(
          onCreated: _onPusherPreviewCreated,
          x: x,
          y: y,
          width: width,
          height: height);
      return Container(
            color: Colors.black,
            width: width,
            height: height,
            child: pusherPreviewView);
  5. Start preview.

    /// The callback that is fired when a preview view is created.
    _onPusherPreviewCreated(id) {
         /// Start preview.
        livePusher.startPreview();
    }
    Note

    Assume that the screen orientation of the Flutter project is portrait, and you call setOrientation to set the screen orientation to landscape. After you create a preview view and call startPreview to start preview, if the video does not fill the entire preview view, we recommend that you wait a moment before you call startPreview. For example, you can wait for 100 ms and then call startPreview.

    Future.delayed(Duration(milliseconds: 100));

  6. Start stream ingest. You can start stream ingest only after the preview succeeds.

    String pushURL = "Ingest URL (rtmp://......)"; 
    livePusher.startPushWithURL(pushURL);
  7. Complete other stream ingest configurations.

    /// Pause stream ingest from the camera. Call the pause method to switch from camera ingest to image ingest after you call setPauseImg. The audio stream continues to be ingested. 
    livePusher.pause();
    /// Switch from image ingest to camera ingest. The audio stream continues to be ingested.
    livePusher.resume();
    /// Stop a stream that is being ingested.
    livePusher.stopPush();
    /// Stop preview. However, this operation does not take effect for a stream that is being ingested. After preview is stopped, the preview window is frozen at the last frame.
    livePusher.stopPreview();
    /// Restart stream ingest when the stream is being ingested or when an error callback is received. If an error occurs, you can call only this method or the reconnectPushAsync method to restart stream ingest. You can also call the destroy method to destroy the stream ingest engine. Then, you can restart all AlivcLivePusher resources that are required for operations, such as preview and stream ingest.
    livePusher.restartPush();
    /// Call this method when the stream is being ingested or when an error callback related to setNetworkDelegate is received. If an error occurs, you can call only this method or the restartPush method to restart stream ingest. You can also call the destroy method to destroy the stream ingest engine. Then, you can restart stream ingest over RTMP.
    livePusher.reconnectPushAsync();
    /// Destroy the stream ingest engine. After you call this method, stream ingest and preview are stopped, and the preview window is removed. All resources related to AlivcLivePusher are destroyed.
    livePusher.destory();
  8. Manage background music.

    /// Start the playback of background music.
    String musicPath = "xxxx"; // xxxx is the path of the music resource.
    livePusher.startBGMWithMusicPathAsync(musicPath);
    /// Stop the playback of background music. If you want to change the background music, directly call the startBGMWithMusicPathAsync method. You do not need to stop the playback of the current background music.
    livePusher.stopBGMAsync();
    /// Pause the playback of background music. You can call this method only after the playback of background music starts.
    livePusher.pauseBGM();
    /// Resume the playback of background music. You can call this method only after the playback of background music is paused.
    livePusher.resumeBGM();
    /// Enable looping.
    livePusher.setBGMLoop(true);
    /// Configure noise reduction. If you enable noise reduction, the system filters out non-vocal parts from collected audio. This feature may slightly reduce the volume of the human voice. We recommend that you allow your users to determine whether to enable this feature. By default, this feature is disabled.
    livePusher.setAudioDenoise(true);
    /// Configure in-ear monitoring. In-ear monitoring is suitable for scenarios that involve karaoke. If you enable in-ear monitoring, you can hear your voice on your earphones during streaming. If you disable in-ear monitoring, you cannot hear your voice on your earphones during streaming. This feature does not take effect if no earphones are detected.
    livePusher.setBGMEarsBack(true);
    /// Specify the volume of the background music in the mixed audio.
    livePusher.setBGMVolume(50); // Valid values: 0 to 100. Default value: 50.
    /// Specify the volume of the human voice in the mixed audio.
    livePusher.setCaptureVolume(50); // Valid values: 0 to 100. Default value: 50.
    /// Configure muting. If you enable this feature, both the background music and human voice are muted. To separately mute the background music or human voice, call the setBGMVolume or setCaptureVolume method.
    livePusher.setMute(true);

    Configure callbacks related to background music.

    /// Configure the callback for complete playback of background music.
    livePusher.setOnBGMCompleted(() {});
    /// Configure the callback for timeout of background music download.
    livePusher.setOnBGMDownloadTimeout(() {});
    /// Configure the callback for failed playback of background music.
    livePusher.setOnBGMOpenFailed(() {});
    /// Configure the callback for paused playback of background music.
    livePusher.setOnBGMPaused(() {});
    /// Configure the callback for playback progress.
    livePusher.setOnBGMProgress((progress, duration) {});
    /// Configure the callback for resumed playback of background music.
    livePusher.setOnBGMResumed(() {});
    /// Configure the callback for start of background music playback.
    livePusher.setOnBGMStarted(() {});
    /// Configure the callback for stop of background music playback.
    livePusher.setOnBGMStoped(() {});
  9. Configure stream ingest snapshots.

    /// Configure snapshot settings.
    String dir = "xxxx"; // xxxx is the path in which snapshots are stored.
    if (Platform.isIOS) {
        /// dir: On iOS, the path is a relative path. A custom directory is automatically generated in the system sandbox. If you set this parameter to "", snapshots are stored in the root directory of the system sandbox. 
        /// dirTypeForIOS: optional. If you do not specify this parameter, snapshots are stored in the document directory of the system sandbox. 
        livePusher.snapshot(1, 0, dir, dirTypeForIOS: AlivcLiveSnapshotDirType.document);
    } else {
        livePusher.snapshot(1, 0, dir);
    }
    /// Configure the listener for snapshot capture.
    livePusher.setSnapshotDelegate();
    
    /// Configure callbacks related to snapshot capture.
    livePusher.setOnSnapshot((saveResult, savePath, {dirTypeForIOS}) {
      	// The callback that is fired when a snapshot is stored.
        if (saveResult == true) {
          if (Platform.isIOS) {
            // Construct the full path of the snapshot in the system sandbox. Format: dirTypeForIOS + savePath.
          } else {
            // Obtain the path of the snapshot in SD based on the value of savePath.
          }
        }
      });
  10. Perform camera-related operations.

    /// Switch between the front and rear cameras.
    livePusher.switchCamera();
    /// Enable or disable the flash. You cannot enable the flash for the front camera.
    livePusher.setFlash(false);
    
    /// Adjust the focal length to zoom in or out. If you set the input parameter to a positive number, the system increases the focal length. If you set the input parameter to a negative number, the system decreases the focal length.
    double max = await livePusher.getMaxZoom();
    livePusher.setZoom(min(1.0, max));
    
    /// Configure manual focus.
    /// The autoFocus parameter specifies whether to enable autofocus. This parameter takes effect only for the current focus operation. Whether autofocus is enabled for subsequent operations depends on the configurations of the setAutoFocus method. 
    double pointX = 50.0; // The custom value.
    double pointY = 50.0; // The custom value.
    bool autoFocus = true;
    livePusher.focusCameraAtAdjustedPoint(pointX, pointY, autoFocus);
    
    /// Disable autofocus.
    livePusher.setAutoFocus(false);
    /// Disable the mirroring mode for preview.
    livePusher.setPreviewMirror(false);
    /// Disable the mirroring mode for stream ingest.
    livePusher.setPushMirror(false);
  11. Configure watermarks. Push SDK for Flutter allows you to add one or more watermarks in the PNG format. Sample code:

    String watermarkBundlePath = "xxxx"; // xxxx is the path of the watermark image.
    double coordX = 0.1;
    double coordY = 0.1;
    double width = 0.3;
    /// Add a watermark.
    livePusher.addWatermark(watermarkBundlePath, coordX, coordY, width);
    Note
    • The values of the coordX, coordY, and width parameters are relative. For example, a value of 0.1 for the coordX parameter indicates that the left edge of the watermark is at the 10% position on the x-axis of the stream ingest screen. Therefore, if the stream resolution is 540 × 960, the value of the X coordinate is 54.

    • The height of the watermark is scaled based on the width and height of the source image and the input width value of the watermark.

    • If you want to add a text watermark, you can convert the text into an image and call the addWaterMark method to add the image as a watermark.

    • To ensure the clarity and smoothness of the edges of the watermark, we recommend that you use a source image that has the same size as the output watermark. For example, if the resolution of the output video is 544 × 940 and the width of the watermark is 0.1f, we recommend that you use a source image in the following width: 544 × 0.1f = 54.4.

  12. Configure external audio and video sources. Push SDK for Flutter allows you to import external audio and video sources for stream ingest. For example, you can ingest an external audio or video file.

    1. Configure the input of external audio and video sources in stream ingest settings.

      /// Enable the input of external streams.
      pusherConfig.setExternMainStream(true);
      /// Specify the color format for video data. In this example, the color format is YUVNV21. You can also use other formats based on your business requirements. 
      pusherConfig.setExternVideoFormat(AlivcLivePushVideoFormat.YUVNV21);
      /// Specify the bit depth format for audio data. In this example, the bit depth format is S16. You can also use other formats based on your business requirements.
      pusherConfig.setExternMainStream(AlivcLivePushAudioFormat.S16);
    2. Import external video data.

      /// The sendVideoData method supports only native YUV and RGB buffer data. You can call the sendVideoData method to transmit video data such as the buffer, length, width, height, timestamp, and rotation angle.
      Uint8List bufferData = xxxx; // xxxx indicates the continuous video buffer data in the Uint8List format.
      int width = 720; // The video width.
      int height = 1280; // The video height.
      int dataSize = xxxx; // xxxx indicates the size of the data.
      int pts = xxxx; // xxxx indicates the timestamp in microseconds.
      int rotation = 0; // The rotation angle.
      livePusher.sendVideoData(bufferData, width, height, size, pts, rotation);
    3. Import external audio data.

      /// The sendPCMData method supports only native PCM buffer data. You can call this method to transmit audio data such as the buffer, length, and timestamp.
      Uint8List bufferData = xxxx; // xxxx indicates the continuous audio buffer data in the Uint8List format.
      int dataSize = xxxx; // xxxx indicates the size of the data.
      int sampleRate = xxxx; // xxxx indicates the sampling rate.
      int channel = 0; // The number of sound channels.
      int pts = xxxx; // xxxx indicates the timestamp in microseconds.
      livePusher.sendPCMData(bufferData, size, sampleRate, channel, pts);