簡體   English   中英

未處理的異常:LateInitializationError:字段“requestPort”尚未初始化。 集市 flutter

[英]Unhandled Exception: LateInitializationError: Field 'requestPort' has not been initialized. Agora flutter

我正在從事一個大型項目並將視頻通話集成到其中。 所以我單獨做了一個項目只是為了練習,並且取得了不錯的效果。 群組通話在 android 和 IOS 上都運行良好。但后來我在我的大型項目中集成了相同的代碼,該項目使用 firebase 作為后端,當我導航到視頻屏幕時,它給我一個錯誤消息“未處理的異常:LateInitializationError:字段 'requestPort' 尚未初始化”。 Agora 控制台目前正在測試中,頻道沒有過期以防萬一你們想知道。 正如我所說,它在一個單獨的項目中完美運行。

import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';

class VideoCallPage extends StatefulWidget {
  const VideoCallPage({Key? key}) : super(key: key);

  @override
  VideoCallPageState createState() => VideoCallPageState();
}

class VideoCallPageState extends State<VideoCallPage> {
  static final _users = <int>[];
  Logger logger = Logger();
  bool muted = false;
  late RtcEngine _engine;
  bool isRigning = true;
  bool isSpeakerOn = true;
  final String channelName = 'video';
  final String appID = 'xxx';
  final String tokenAudio ='xxx';

  @override
  void dispose() {
    _dispose();
    super.dispose();
  }

  Future<void> _dispose() async {
    _users.clear();
    await _engine.leaveChannel();
    await _engine.stopPreview();
    await _engine.release();
  }

  @override
  void initState() {
    super.initState();
    // initialize agora sdk
    initialize();
  }

  Future<void> initialize() async {
    logger.i('Initialize');
    if (appID.isEmpty) {
      setState(() {
        logger.e(
          'APP_ID missing, please provide your APP_ID in settings.dart',
        );
        logger.e('Agora Engine is not starting');
      });
      return;
    }
    await _initAgoraRtcEngine();
    _addAgoraEventHandlers();
    onOffSpeaker();
    await _engine.joinChannel(
        token: tokenAudio,
        channelId: channelName,
        uid: 0,
        options: const ChannelMediaOptions(
            channelProfile: ChannelProfileType.channelProfileCommunication,
            clientRoleType: ClientRoleType.clientRoleBroadcaster));
     
  }

  Future<void> _initAgoraRtcEngine() async {
    logger.i('_initAgoraRtcEngine');
    //create the engine
    _engine = createAgoraRtcEngine();
    logger.i('RtcEngineContext');
    await _engine.initialize(RtcEngineContext(
      appId: appID,
    ));
    logger.i('enablbing video');
    await _engine.enableVideo();
    // await _engine.setVideoEncoderConfiguration(
    //   const VideoEncoderConfiguration(
    //     dimensions: VideoDimensions(width: 640, height: 360),
    //     frameRate: 15,
    //     bitrate: 0,
    //   ),
    // );
    await _engine.startPreview();
  }

  void _addAgoraEventHandlers() {
    _engine.registerEventHandler(RtcEngineEventHandler(
      onError: (ErrorCodeType errorCodeType, String value) {
        if (mounted) {
          setState(() {
            final info = 'onError: ${errorCodeType.name}';
            logger.e(info);
          });
        }
      },
      onJoinChannelSuccess: (RtcConnection connection, int elapsed) {
        setState(() {
          final info =
              'onJoinChannel: ${connection.channelId}, uid: ${connection.localUid}';
          logger.i(info);
        });
      },
      onLeaveChannel: (RtcConnection rtcConnection, RtcStats rtcStats) {
        setState(() {
          logger.i('onLeaveChannel');
          _users.clear();
        });
      },
      onUserJoined: (RtcConnection connection, int remoteUid, int elapsed) {
        setState(() {
          isRigning = false;
          final info = 'remoteUserJoined: $remoteUid';
          logger.i(info);
          _users.add(remoteUid);
        });
      },
      onUserOffline: (RtcConnection connection, int remoteUid,
          UserOfflineReasonType reason) {
        setState(() {
          final info =
              'remoteUserOffline: $remoteUid , reason: ${reason.index}';
          logger.i(info);
          _users.remove(remoteUid);
        });
      },
      onFirstRemoteVideoFrame: (connection, uid, width, height, elapsed) {
        setState(() {
          final info = 'firstRemoteVideoFrame: $uid';
          logger.i(info);
        });
      },
    ));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Agora Group Video Calling'),
      ),
      backgroundColor: Colors.black,
      body: Center(
        child: Stack(
          children: <Widget>[
            Opacity(
              opacity: isRigning ? 0.2 : 1,
              child: _viewRows(),
            ),
            _toolbar(),
            if (isRigning)
              Positioned(
                  top: 100,
                  left: MediaQuery.of(context).size.width * 0.3,
                  right: MediaQuery.of(context).size.width * 0.3,
                  child: Center(
                    child: Text(
                      'Ringing...',
                      style: TextStyle(color: Colors.white, fontSize: 30),
                    ),
                  ))
          ],
        ),
      ),
    );
  }

  /// Helper function to get list of native views
  List<Widget> _getRenderViews() {
    final List<StatefulWidget> list = [];
    list.add(AgoraVideoView(
        controller: VideoViewController(
      rtcEngine: _engine,
      canvas: const VideoCanvas(uid: 0),
    )));
    _users.forEach((int uid) => list.add(AgoraVideoView(
          controller: VideoViewController.remote(
            rtcEngine: _engine,
            canvas: VideoCanvas(uid: uid),
            connection: RtcConnection(channelId: channelName),
          ),
        )));
    return list;
  }

  /// Video view wrapper
  Widget _videoView(view) {
    return Expanded(child: Container(child: view));
  }

  /// Video view row wrapper
  Widget _expandedVideoRow(List<Widget> views) {
    final wrappedViews = views.map<Widget>(_videoView).toList();
    return Expanded(
      child: Row(
        children: wrappedViews,
      ),
    );
  }

  Widget _viewRows() {
    final views = _getRenderViews();
    switch (views.length) {
      case 1:
        return Container(
            child: Column(
          children: <Widget>[_videoView(views[0])],
        ));
      case 2:
        return Container(
            child: Column(
          children: <Widget>[
            _expandedVideoRow([views[0]]),
            _expandedVideoRow([views[1]])
          ],
        ));
      case 3:
        return Container(
            child: Column(
          children: <Widget>[
            _expandedVideoRow(views.sublist(0, 2)),
            _expandedVideoRow(views.sublist(2, 3))
          ],
        ));
      case 4:
        return Container(
            child: Column(
          children: <Widget>[
            _expandedVideoRow(views.sublist(0, 2)),
            _expandedVideoRow(views.sublist(2, 4))
          ],
        ));
      default:
    }
    return Container();
  }

  Widget _toolbar() {
    return Container(
      alignment: Alignment.bottomCenter,
      padding: const EdgeInsets.symmetric(vertical: 48),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          RawMaterialButton(
            onPressed: onOffSpeaker,
            child: Icon(
              isSpeakerOn ? Icons.volume_up_sharp : Icons.volume_off,
              color: isSpeakerOn ? Colors.white : Colors.blueAccent,
              size: 20.0,
            ),
            shape: CircleBorder(),
            elevation: 2.0,
            fillColor: isSpeakerOn ? Colors.blueAccent : Colors.white,
            padding: const EdgeInsets.all(12.0),
          ),
          RawMaterialButton(
            onPressed: _onToggleMute,
            child: Icon(
              muted ? Icons.mic_off : Icons.mic,
              color: muted ? Colors.white : Colors.blueAccent,
              size: 20.0,
            ),
            shape: CircleBorder(),
            elevation: 2.0,
            fillColor: muted ? Colors.blueAccent : Colors.white,
            padding: const EdgeInsets.all(12.0),
          ),
          RawMaterialButton(
            onPressed: () => _onCallEnd(context),
            child: Icon(
              Icons.call_end,
              color: Colors.white,
              size: 35.0,
            ),
            shape: CircleBorder(),
            elevation: 2.0,
            fillColor: Colors.redAccent,
            padding: const EdgeInsets.all(15.0),
          ),
          RawMaterialButton(
            onPressed: _onSwitchCamera,
            child: Icon(
              Icons.switch_camera,
              color: Colors.blueAccent,
              size: 20.0,
            ),
            shape: CircleBorder(),
            elevation: 2.0,
            fillColor: Colors.white,
            padding: const EdgeInsets.all(12.0),
          )
        ],
      ),
    );
  }

  void _onToggleMute() {
    setState(() {
      muted = !muted;
    });
    _engine.muteLocalAudioStream(muted);
  }

  void _onCallEnd(BuildContext context) {
    Navigator.pop(context);
  }

  void _onSwitchCamera() {
    _engine.switchCamera();
  }

  Future onOffSpeaker() async {
    setState(() {
      isSpeakerOn = !isSpeakerOn;
    });
    await _engine.setEnableSpeakerphone(isSpeakerOn);
  }
}

我使用Logger package查看日志,發現錯誤出現在這段代碼中

await _engine.initialize(RtcEngineContext(
      appId: appID,
    ));

The app uses agora_rtc_engine: ^6.1.0 and defined in pubspec.yaml file

在 Agora SDK 中,必須有一個late字段requestPort在初始化之前訪問。

似乎已經在 Agora SDK github 回購中提出了類似的問題 但是它關閉了。 您可以打開一個新問題或重新打開現有問題,並按照步驟重現該問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM