簡體   English   中英

StateError(錯誤狀態:調用關閉后無法添加新事件)

[英]StateError (Bad state: Cannot add new events after calling close)

我正在使用這個包: https ://pub.dev/packages/dart_vlc 在我的 Flutter App 頁面上流式傳輸多個攝像頭。 但是我遇到了一個問題,當我更改頁面並轉到另一個頁面時,我會收到以下錯誤:

未處理的異常:StateError(錯誤狀態:調用關閉后無法添加新事件)

下面是我的流媒體頁面的代碼:

class CameraScreen extends StatefulWidget {
  CameraScreen(
      {required Key key,
      required this.onPageChange,
      required this.onLogout,
      required this.id})
      : super(key: key);
  final Function(String, String) onPageChange;
  final VoidCallback onLogout;
  final String id;
  @override
  CameraScreenState createState() => CameraScreenState();
}

class CameraScreenState extends State<CameraScreen>
    with TickerProviderStateMixin {
  PageConfig pageConfig = PageConfig();
  String project = '';
  List<ResponsiveGridCol> children = [];
  List<Player> players = [];
  List<dynamic> items = [];
  double initialSliderValue = 0;
  Player playerOfTheExpandedImg =
      Player(id: 1000, videoWidth: 1200, videoHeight: 800);

  @override
  void initState() {
    project = Project.getCurrentProject();
    pageConfig = Project.getProjectPageDetails(widget.id);
    getData();
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    return CustomScaffold(
      text: pageConfig.name!,
      onPageChange: widget.onPageChange,
      onLogout: widget.onLogout,
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: SingleChildScrollView(
          child: ResponsiveGridRow(
            children: children,
          ),
        ),
      ),
    );
  }

  getData() async {
    File cameraFile = File(AppStrings.CONFIG_DIRECTORY_PATH +
        project +
        AppStrings.CAMERA_CONFIG_FILE_NAME);
    items = jsonDecode(cameraFile.readAsStringSync());
    int i = 0;
    List<ResponsiveGridCol> widgets = [];
    for (var item in items) {
      var cameraConfig = Camera.fromJson(item);
      Player player = Player(id: i, videoWidth: 400, videoHeight: 300);
      var media = await Media.network(cameraConfig.url,
          parse: true, timeout: Duration(seconds: 2));
      await player.open(media);
      await player.play();
      players.add(player);
      widgets.add(
        ResponsiveGridCol(
          lg: 6,
          child: Card(
            key: Key('$i'),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Text(cameraConfig.title, style: AppStyles.BOLD),
                Text('Telecamere'),
                Video(
                  playerId: i,
                  width: 500,
                  height: 375,
                  showControls: false,
                ),
                Divider(),
                IconButton(
                  icon: Icon(Icons.open_in_browser),
                  onPressed: () async {
                    var stream = await createStreamForExpandedImg(item);
                    showDialog(
                      context: context,
                      builder: (BuildContext context) {
                        return ExpandedCamImg(
                            player: playerOfTheExpandedImg,
                            stream: stream,
                            cameraConfig: cameraConfig);
                      },
                    ).whenComplete(() async {
                      await playerOfTheExpandedImg.stop();
                      await playerOfTheExpandedImg.dispose();
                    });
                  },
                )
              ],
            ),
          ),
        ),
      );
      i++;
    }
    if (mounted) {
      setState(() {
        children = widgets;
      });
    } else
      return;
  }

  Future<Video> createStreamForExpandedImg(dynamic item) async {
    playerOfTheExpandedImg =
        Player(id: 1000, videoWidth: 1200, videoHeight: 800);
    var stream = Video(
      playerId: 1000,
      width: 1200,
      height: 800,
      showControls: false,
    );
    var cameraConfig = Camera.fromJson(item);
    var media = await Media.network(cameraConfig.url,
        parse: true, timeout: Duration(seconds: 2));
    await playerOfTheExpandedImg.open(media);
    await playerOfTheExpandedImg.play();
    return stream;
  }

  stopAndDisposePlayers() async {
    for (var player in players) {
      await player.stop();
      await player.dispose();
    }
  }
}

我想這是一個問題,當調用dispose()時,所有players器都沒有正確關閉和銷毀。

此問題的原因是流控制器在關閉后被訪問。 可能是由於player.dispose() 您可以在此處添加一個檢查器以確保在調用dispose()后不會添加新事件。

bool _isDisposed = false;

stopAndDisposePlayers() async {
  _isDisposed = true;
  
  ...
}

然后,您可以在啟動 Stream 之前使用_isDisposed進行檢查。

暫無
暫無

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

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