상세 컨텐츠

본문 제목

[Flutter] VlcPlayer 무한 영상 재생

IT/응용

by SINAFLA 2021. 7. 13. 10:57

본문

반응형

class VlcView extends StatefulWidget {
  final String url;
  VlcView({this.url});

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

class _VlcViewState extends State<VlcView> {
  VlcPlayerController _videoPlayerController;
  String videoUrl = '';
  Future<void> initializePlayer() async {}
  PlayingState state;
  Widget refreshVideoView;
  bool _isEnded = false;
  bool _isPlaying = false;

  @override
  void initState() {
    videoUrl = widget.url;
    super.initState();
    try {
      _videoPlayerController = initController();
    } catch(e) {
      print('>> error: $e');
    }
  }

  @override
  void dispose() {
    super.dispose();
    if(_videoPlayerController != null) {
      _videoPlayerController.stopRendererScanning();
      _videoPlayerController.dispose();
    }
  }

  VlcPlayerController initController(){
    return VlcPlayerController.network(
      '$videoUrl',
      hwAcc: HwAcc.FULL,
      autoPlay: true,
      options: VlcPlayerOptions(),
    );
  }

  void initializedListener(value) {
    setState(() {
      state = value;
      if(_isEnded) {
        _isEnded = false;
      }
    });
  }

  void playingListener(value){
    setState(() {
      if(!_isPlaying) _isPlaying = value;
    });
  }

  void stoppingListener() {
    setState(() {
      if(_isPlaying) _isPlaying = false;
    });
  }

  void endedListener({value}) async {
    setState(() {
      _videoPlayerController = initController();
      if(!_isEnded) _isEnded = true;
    });

    if(value != PlayingState.initialized) {
      showToast('실시간 영상 연결이 끊겼습니다.');
      refreshVideoView = CircularProgressIndicator();
      await delayRefreshVideoView();
    }
  }

  Future<void> delayRefreshVideoView() async {
    Future.delayed(Duration(seconds: 10),()  {
      setState(() {
        refreshVideoView = videoView(_videoPlayerController);

        Future.delayed(Duration(seconds: 5), () {
          if(!_isEnded && !_isPlaying) {
            this.setState(() {
              refreshVideoView = CircularProgressIndicator();
              _videoPlayerController = initController();
            });
            delayRefreshVideoView();
          }
        });
      });
    });
  }

  Widget videoView(controller) {
    return VlcMain(
      controller: _videoPlayerController,
      endedListener: endedListener,
      initializedListener: initializedListener,
      playingListener: playingListener,
      stoppingListener: stoppingListener,
    );
  }

  @override
  Widget build(BuildContext context) {
    if(refreshVideoView == null) {
      refreshVideoView = videoView(_videoPlayerController);
    }
    return Container(
        child: Center(
        child: refreshVideoView,
      ),
    );
  }

}

class VlcMain extends StatefulWidget {
  final VlcPlayerController controller;
  final Function endedListener;
  final Function initializedListener;
  final Function playingListener;
  final Function stoppingListener;

  VlcMain({this.controller, this.endedListener, this.initializedListener, this.playingListener, this.stoppingListener});

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

class _VlcMainState extends State<VlcMain> {
  PlayingState _state;

  @override
  void initState() {
    super.initState();
    widget.controller.addListener(() async {
      final PlayingState state = widget.controller.value.playingState;
      setState(() {
        _state = state;
      });

      switch(_state) {
        case PlayingState.initialized:
          widget.initializedListener(widget.controller.value.playingState);
          widget.controller.play();
          break;
        case PlayingState.playing:
          widget.playingListener(await widget.controller.isPlaying());
          break;
        case PlayingState.stopped:
          widget.stoppingListener();
          break;
        case PlayingState.ended:
          widget.endedListener(value: state);
          break;
        case PlayingState.error:
          break;
      }
    });
  }

  @override
  void dispose() {
    if(widget.controller != null) {
      widget.controller.stopRendererScanning();
      widget.controller.dispose();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return VlcPlayer(controller: widget.controller, aspectRatio:16 / 9,);
  }
}

 

반응형

관련글 더보기

댓글 영역