This topic describes how to implement features of ApsaraVideo Player SDK for Flutter. This topic also provides sample code that you can use to implement the features.

Playback

This section describes how to use ApsaraVideo Player SDK for Flutter:

  1. Create a player.
    FlutterAliplayer fAliplayer = FlutterAliPlayerFactory.createAliPlayer();

    Create multiple instances of the player.

    You must manage the playerId parameter at the Flutter layer. The value of the playerId parameter is returned during the callback to notify the Flutter layer.
    FlutterAliplayer fAliplayer = FlutterAliPlayerFactory.createAliPlayer(playerId: playerId);
  2. Configure listeners.
    The following code block shows the API operations for specific listeners:
    // The listener for successful preparation.
    fAliplayer.setOnPrepard((playerId) {});
    // The listener for the display of the first frame.
    fAliplayer.setOnRenderingStart((playerId) {});
    // The listener for changes in the width or height of a video.
    fAliplayer.setOnVideoSizeChanged((width, height,playerId) {});
    // The listener for changes of the player status.
    fAliplayer.setOnStateChanged((newState,playerId) {});
    // The listener for the loading status.
    fAliplayer.setOnLoadingStatusListener(
        loadingBegin: (playerId) {},
        loadingProgress: (percent, netSpeed,playerId) {},
        loadingEnd: (playerId) {});
    // The listener for seeking completed.
    fAliplayer.setOnSeekComplete((playerId) {});
    // The listener for event callbacks, such as the buffer callback and the playback progress callback. You can obtain the value of the FlutterAvpdef.infoCode parameter based on the value of the infoCode parameter.
    fAliplayer.setOnInfo((infoCode, extraValue, extraMsg,playerId) {});
    // The listener for playback completed.
    fAliplayer.setOnCompletion((playerId) {});
    // The listener for a stream that is ready.
    fAliplayer.setOnTrackReady((playerId) {});
    // The listener for a snapshot that is taken.
    fAliplayer.setOnSnapShot((path,playerId) {});
    // The listener for an error that occurs.
    fAliplayer.setOnError((errorCode, errorExtra, errorMsg,playerId) {});
    // The listener for stream switching.
    fAliplayer.setOnTrackChanged((value,playerId) {});
  3. Configure the render view.
    @override
    Widget build(BuildContext context) {
      var x = 0.0;
      var y = 0.0;
      Orientation orientation = MediaQuery.of(context).orientation;
      var width = MediaQuery.of(context).size.width;
    
      var height;
      if (orientation == Orientation.portrait) {
        height = width * 9.0 / 16.0;
      } else {
        height = MediaQuery.of(context).size.height;
      }
      AliPlayerView aliPlayerView = AliPlayerView(
          onCreated: onViewPlayerCreated,
          x: x,
          y: y,
          width: width,
          height: height);
      return OrientationBuilder(
        builder: (BuildContext context, Orientation orientation) {
          return Scaffold(
            body: Column(
              children: [
                Container(
                    color: Colors.black,
                    child: aliPlayerView,
                    width: width,
                    height: height),
              ],
            ),
          );
        },
      );
  4. Configure the playback source.
    void onViewPlayerCreated(viewId) async {
      // Specify the render view for the player.
      fAliplayer.setPlayerView(viewId);
      // Configure the playback source.
      switch (_playMode) {
        // Specify the URL playback mode.
        case ModeType.URL:
          this.fAliplayer.setUrl(_dataSourceMap[DataSourceRelated.URL_KEY]);
          break;
        // Specify the STS playback mode.
        case ModeType.STS:
          this.fAliplayer.setVidSts(
              vid: _dataSourceMap[DataSourceRelated.VID_KEY],
              region: _dataSourceMap[DataSourceRelated.REGION_KEY],
              accessKeyId: _dataSourceMap[DataSourceRelated.ACCESSKEYID_KEY],
              accessKeySecret:
                  _dataSourceMap[DataSourceRelated.ACCESSKEYSECRET_KEY],
              securityToken: _dataSourceMap[DataSourceRelated.SECURITYTOKEN_KEY],
              definitionList: _dataSourceMap[DataSourceRelated.DEFINITION_LIST],
              previewTime: _dataSourceMap[DataSourceRelated.PREVIEWTIME_KEY]);
          break;
        // Specify the AUTH playback mode.
        case ModeType.AUTH:
          this.fAliplayer.setVidAuth(
              vid: _dataSourceMap[DataSourceRelated.VID_KEY],
              region: _dataSourceMap[DataSourceRelated.REGION_KEY],
              playAuth: _dataSourceMap[DataSourceRelated.PLAYAUTH_KEY],
              definitionList: _dataSourceMap[DataSourceRelated.DEFINITION_LIST],
              previewTime: _dataSourceMap[DataSourceRelated.PREVIEWTIME_KEY]);
          break;
        // Specify the MPS playback mode.
        case ModeType.MPS:
            this.fAliplayer.setVidMps(_dataSourceMap);
                Map<String, dynamic> authInfo = {
                 "vid": "Enter the VID of the resource.",
                 "region": "Enter the region where the resource resides.",
                 "accessKeyId": "Enter the authentication ID of the resource.",
                 "accessKeySecret": "Enter the authentication key of the resource.",
                 "playDomain": "Enter the domain name that is used to play the resource.",
                 "authInfo": "Enter the authentication information about the resource.",
                 "hlsUriToken": "Enter the HlsUriToken of the resource.",
                 "securityToken": "Enter the security token of the resource."
                    };
        this.fAliplayer.setVidMps(authInfo);
        default:
      }
    }
    Notice
    • The preceding code applies to the latest version of Android.
    • Check the key that you entered in the dictionary. Make sure that the key in the dictionary has the same name as the key that you specified in the preceding code. If the keys do not have the same name, ApsaraVideo Player SDK for Flutter may fail to obtain your data.
  5. Enable autoplay.
    Note If you enable the autoplay feature, videos are automatically played after you call the prepare() method.

    If you do not enable the autoplay feature, you must call the fAliplayer.play() method to start playback when the setOnPrepard() listener is called.

    fAliplayer.setAutoPlay(true);
    fAliplayer.prepare();
  6. Pause the playback.

    After you pause the playback, you can call the play() method to resume the playback.

    fAliplayer.pause();
  7. Stop the playback.

    After you stop the playback, you can call the prepare() method and then the play() method to resume the playback.

    fAliplayer.stop();
  8. Destroy the playback.
    fAliplayer.release();
  9. Specify the seek pointer.
    // Valid values of seekMode: FlutterAvpdef.ACCURATE (accurate seek) and FlutterAvpdef.INACCURATE (inaccurate seek).
    fAliplayer.seek(position,seekMode);
  10. Loop playback.
    fAliplayer.setLoop(true);
  11. Adjust the volume or configure muted playback.
    fAliplayer.setMute(true);
    // Specify the player volume. Value range: 0 to 1.
    fAliPlayer.setVolume(1);
  12. Specify the playback speed.
    // Valid values: 0.5, 1.0, 1.5, and 2.0.
    fAliplayer.setRate(1.0);
  13. Switch between multiple bitrates and enable automatic bitrate switching.
    After you prepare the player, you can call getMediaInfo to obtain the value of the TrackInfo parameter, which indicates the bitrate information.
    fAliplayer.getMediaInfo().then((value) {
       // Valid value: map. You can use value['tracks'] to obtain information about the TrackInfos list. For more information about how to parse TrackInfo, see AVPMediaInfo info = AVPMediaInfo.fromJson(value) in the demo.
    
    };
    // During playback, you can call the selectTrack method to configure the trackIndex parameter in TrackInfo to switch the bitrate. The switching result is returned after you call OnTrackChangedListener.
    
    fAliplayer.selectTrack(index);
    // Enable automatic bitrate switching.
    fAliplayer.selectTrack(-1);
  14. Configure screen rotation, scaling, and mirroring.
    // Specify the mirroring mode: horizontal mirroring, vertical mirroring, or no mirroring.
    fAliplayer.setMirrorMode(FlutterAvpdef.AVP_MIRRORMODE_NONE);
    // Specify the rotation angle: 0°, 90°, 180°, or 270°.
    fAliplayer.setRotateMode(FlutterAvpdef.AVP_ROTATE_0);
    // Specify the scaling mode: aspect ratio-based padding, aspect ratio-based fitting, or stretching.
    fAliplayer.setScalingMode(FlutterAvpdef.AVP_SCALINGMODE_SCALETOFILL);
  15. Enable the play-and-cache feature.

    You must enable this feature before you prepare the player.

    var map = {
      "mMaxSizeMB": _mMaxSizeMBController.text,/// Specify the maximum space that can be occupied by the cache directory.
      "mMaxDurationS": _mMaxDurationSController.text,/// Specify the maximum cache duration of a single file.
      "mDir": _mDirController.text,/// Specify the cache directory.
      "mEnable": mEnableCacheConfig,/// Specify whether to enable the cache feature.
    };
    fAliplayer.setCacheConfig(map);
  16. Configure other settings for the player.

    Before you call the prepare() method, you must configure the following parameters for the player.

    var configMap = {
      'mStartBufferDuration':_mStartBufferDurationController.text,/// Specify the buffer duration before playback.
      'mHighBufferDuration':_mHighBufferDurationController.text,/// Specify the duration of high buffer.
      'mStartBufferDuration':_mStartBufferDurationController.text,/// Specify the maximum buffer duration.
      'mMaxDelayTime': _mMaxDelayTimeController.text,/// Specify the maximum latency. Note: This parameter is valid only for live streaming.
      'mNetworkTimeout': _mNetworkTimeoutController.text,/// Specify the network timeout period.
      'mNetworkRetryCount':_mNetworkRetryCountController.text,/// Specify the number of retries if a network timeout occurs.
      'mMaxProbeSize': _mMaxProbeSizeController.text,/// Specify the maximum probe size.
      'mReferrer': _mReferrerController.text,///referrer
      'mHttpProxy': _mHttpProxyController.text,/// Specify the HTTP proxy.
      'mEnableSEI': mEnableSEI,/// Specify whether to use supplemental enhancement information (SEI).
      'mClearFrameWhenStop': !mShowFrameWhenStop,/// Specify whether to clear the screen when the playback stops.
      'mDisableVideo': mDisableVideo,/// Specify whether to disable video.
      'mDisableAudio': mDisableAudio/// Specify whether to disable audio.
    };
    widget.fAliplayer.setConfig(configMap);

List playback

  1. Create a list player.
    FlutterAliListPlayer fAliListPlayer = FlutterAliPlayerFactory.createAliListPlayer();
  2. Add and remove resources.

    The list player supports only the URL and STS playback modes.

    // The uid parameter specifies the unique ID of a video. You can use the UID to identify videos. Videos that have the same UID are considered the same.
    fAliListPlayer.addUrlSource(url,uid);
    fAliListPlayer.addVidSource(vid,uid);
    fAliListPlayer.removeSource(uid);
  3. Specify the number of videos that you want to preload.
    You can set the parameter to a value based on your business requirements. This way, the startup loading time can be reduced. The following code provides an example:
    // Specify the number of videos that you want to preload. The total number of loaded videos is equal to one plus twice the specified number. 
    fAliListPlayer.setPreloadCount(count);
  4. Play the video source.
    // The uid parameter is required. If you play the video in URL mode, you do not need to configure other parameters. If you play the video in STS mode, you must enter the STS information.
    fAliListPlayer.moveTo();

Video download

ApsaraVideo Player SDK for Flutter allows you to use VidSts and VidAuth to download videos from ApsaraVideo VOD. ApsaraVideo VOD supports the secure download mode and the regular download mode. You can specify a download mode in the ApsaraVideo VOD console.

  1. Create and configure a downloader.
    FlutterAliDownloader donwloader = FlutterAliDownloader.init();
    /// Specify the path in which you want to save downloaded videos.
    donwloader.setSaveDir(path)
    ApsaraVideo Player SDK for Flutter allows you to download videos that are encrypted by using Alibaba Cloud proprietary encryption. For security reasons, you must configure a security file for encryption verification in the SDK.
    FlutterAliPlayerFactory.initService(byteData);
  2. Start the download.
    After you call the method to start the download, listeners are automatically configured and a callback message is returned. The following code provides an example:
    /// 1. prepare
      /// Parameter description: Valid values of type include FlutterAvpdef.DOWNLOADTYPE_STS and FlutterAvpdef.DOWNLOADTYPE_AUTH. If the value of type is DOWNLOADTYPE_STS, the required parameters are {vid,accessKeyId,accessKeySecret,securityToken}. If the value of type is DOWNLOADTYPE_AUTH, the required parameters are {vid,playAuth}.
      downloader.prepare(type, vid).then((value) {
          // Valid value: map. This value corresponds to the custom download class DownloadModel in the demo.
          DownloadModel downloadModel = DownloadModel.fromJson(value);
          // 2. selectItem. This parameter determines the quality of videos that you want to download.
          List<TrackInfoModel> trackInfos = downloadModel.trackInfos;
          downloader.selectItem(vid,trackInfos[0].index);
          // 3. start
          downloader.start(vid, trackInfos[0].index).listen((event) {
            // Note: event may contain various information. You can refer to information in FlutterAvpdef.EventChanneldef. The following code provides the details:
            if (event[EventChanneldef.TYPE_KEY] == EventChanneldef.DOWNLOAD_PROGRESS){
                // event[EventChanneldef.DOWNLOAD_PROGRESS] indicates the download progress in percentage.
            }else if(event[EventChanneldef.TYPE_KEY] == EventChanneldef.DOWNLOAD_PROCESS){
                // event[EventChanneldef.DOWNLOAD_PROCESS] indicates the processing progress in percentage.
            }else if(event[EventChanneldef.TYPE_KEY] == EventChanneldef.DOWNLOAD_COMPLETION){
                // Indicates that the download is complete. You can use event['vid'] and event['index'] to obtain the VID and index. You can determine the video that is downloaded based on the VID and index. You can use event['savePath'] to obtain the on-premises path of downloaded videos.
            }else if(event[EventChanneldef.TYPE_KEY] == EventChanneldef.DOWNLOAD_ERROR){
                // Indicates that the download failed. You can use event['vid'] and event['index'] to obtain the VID and index. You can determine the video that failed to download based on the VID and index. You can use event['errorCode'] and event['errorMsg'] to obtain the error code and error message.
            }
          });
      });
  3. Stop the download.
    downloader.stop(vid, index)
  4. Delete a downloaded file.
    When the deletion process is complete, the downloaded file is deleted. The following code provides an example:
    downloader.delete(vid, index)
  5. Release a downloaded object.
    If you no longer need a downloaded object, you can call the downloader.release method to release the object to prevent memory leaks. The following code provides an example:
    downloader.release(vid, index)