admin管理员组

文章数量:1122846

Hello Everyone i am trying to implement story function as like instagram in flutter. i am done with display image and video story perfectly. i am getting issue when switching story form user to another user when first user video story start and i switch to another user story by swipe then if next user having video story and try to pause that story and again resume that video story, old user video start playing with same user.

i am following this plugin to display story text

i try to dispose videocontroller but not getting any luck.

Story(
                            sortByVisited: true,
                            shrinkWrap: true,
                            autoplay: true,
                            physics: NeverScrollableScrollPhysics(),
                            controller: controller.storyController,
                            scrollDirection: Axis.horizontal,
                            addAutomaticKeepAlives: true,
                            addRepaintBoundaries: false,
                            children: controller.storyItemDisplayList
                                .map(
                                  (e) => StoryUser(
                                    width: 80.0.w,
                                    height: 80.0.w,
                                    onLongPressed: (value) {},
                                    avatar: Container(
                                      padding: EdgeInsets.all(3.0),
                                      width: 80.0.w,
                                      height: 80.0.w,
                                      decoration: (!e.isAllSeen)
                                          ? const BoxDecoration(
                                              shape: BoxShape.circle,
                                              border: GradientBoxBorder(
                                                gradient: LinearGradient(
                                                    colors: [
                                                      AppTheme.gradientPink,
                                                      AppTheme.blue
                                                    ]),
                                                width: 3,
                                              ),
                                            )
                                          : BoxDecoration(
                                              shape: BoxShape.circle,
                                              border: Border.all(
                                                  color: AppTheme.grey,
                                                  width: 3),
                                            ),
                                      child: RoundImage(
                                        imageUrl: e.profilePicUrl ?? '',
                                      ),
                                    ),
                                    label: Text(
                                      e.displayName ?? '',
                                      textAlign: TextAlign.center,
                                      maxLines: 1,
                                      overflow: TextOverflow.ellipsis,
                                      style: AppUtils.textWhiteSFMedium12,
                                    ),
                                    onPressed: (value) {},
                                    margin: EdgeInsets.symmetric(
                                        horizontal: 7.w),
                                    borderPadding: EdgeInsets.all(3),
                                    children: e.listOfDetails == null
                                        ? []
                                        : e.listOfDetails!
                                            .map(
                                              (story) => StoryCard(
                                                  avatar: RoundImage(
                                                    imageUrl:
                                                        e.profilePicUrl ??
                                                            '',
                                                    height: 40.w,
                                                    width: 40.w,
                                                  ),
                                                  label: Text(
                                                    e.displayName ?? '',
                                                    maxLines: 1,
                                                    overflow: TextOverflow
                                                        .ellipsis,
                                                    style: AppUtils
                                                        .textWhiteSFMedium14,
                                                  ),
                                                  storyTime: Text(
                                                    DateHelper.timeAgoStory(
                                                      value: story
                                                              .createdDate ??
                                                          '',
                                                    ),
                                                    style: AppUtils
                                                        .textWhiteSFMedium14,
                                                  ),
                                                  isLike:
                                                      story.isLike ?? false,
                                                  progressBarHeight: 4.h,
                                                  onPressed: (value) async {
                                                    var friend = Friend();
                                                    friend.userId =
                                                        e.userId ?? '';
                                                    friend.username =
                                                        e.username ?? '';
                                                    friend.displayName =
                                                        e.displayName ?? '';
                                                    friend.profilePicUrl =
                                                        e.profilePicUrl ??
                                                            '';
                                                    await AppRouter
                                                        .otherUserProfile(
                                                            friendItem:
                                                                friend,
                                                            flagClose:
                                                                false);
                                                  },
                                                  onPause: (value) {
                                                    controller
                                                        .storyController
                                                        .pauseStory();
                                                    if (story.type ==
                                                        "video") {
                                                      controller
                                                          .storyVideoPlayer
                                                          .pause();
                                                    }
                                                  },
                                                  onResume: (value) {
                                                    controller
                                                        .storyController
                                                        .playStory();
                                                    if (story.type ==
                                                        "video") {
                                                      controller
                                                          .storyVideoPlayer
                                                          .play();
                                                    }
                                                  },
                                                  onDispose: (value) {},
                                                  onVisited: (cardIndex) {
                                                    // setState(() {
                                                    //   card.visited = true;
                                                    // });
                                                    controller.setStorySeen(
                                                        story);
                                                    controller
                                                        .setActiveIndex(
                                                            story);
                                                  },
                                                  onNext: (value) {
                                                    if (controller
                                                        .isDialogShowing) {
                                                      Navigator.pop(
                                                          context);
                                                      controller
                                                          .storyController
                                                          .playStory();
                                                      // if (story.type == "video") {
                                                      //   controller.storyVideoPlayer
                                                      //       .play();
                                                      // }
                                                      controller
                                                          .showReply(false);
                                                    }
                                                  },
                                                  onPrevious: (value) {
                                                    if (controller
                                                        .isDialogShowing) {
                                                      Navigator.pop(
                                                          context);
                                                      controller
                                                          .storyController
                                                          .playStory();
                                                      // if (story.type == "video") {
                                                      //   controller.storyVideoPlayer
                                                      //       .play();
                                                      // }
                                                      controller
                                                          .showReply(false);
                                                    }
                                                  },
                                                  footer: StoryCardFooter(
                                                    likeButton:
                                                        StoryCardLikeButton(
                                                      onLike: (value) =>
                                                          controller
                                                              .addStoryLike(
                                                                  story),
                                                    ),
                                                    forwardButton:
                                                        StoryCardForwardButton(
                                                      onForward: (value) {
                                                        controller
                                                            .storyController
                                                            .pauseStory();
                                                        if (story.type ==
                                                            "video") {
                                                          controller
                                                              .storyVideoPlayer
                                                              .pause();
                                                        }
                                                        _showReplyDialog(
                                                            context,
                                                            story,
                                                            controller);
                                                      },
                                                    ),
                                                    child: Container(
                                                      padding:
                                                          EdgeInsets.only(
                                                              left: 10.0.w,
                                                              top: 10.h,
                                                              bottom: 10.h),
                                                      child: Container(
                                                        decoration: BoxDecoration(
                                                            border: Border.all(
                                                                width: 1.0,
                                                                color: Colors
                                                                    .white),
                                                            borderRadius:
                                                                const BorderRadius
                                                                    .all(
                                                                    Radius.circular(
                                                                        30))),
                                                        child: TextField(
                                                          readOnly: true,
                                                          onTap: () {
                                                            controller
                                                                .storyController
                                                                .pauseStory();
                                                            if (story
                                                                    .type ==
                                                                "video") {
                                                              controller
                                                                  .storyVideoPlayer
                                                                  .pause();
                                                            }
                                                            _showReplyDialog(
                                                                context,
                                                                story,
                                                                controller);
                                                          },
                                                          decoration:
                                                              InputDecoration(
                                                            fillColor: Colors
                                                                .transparent,
                                                            border:
                                                                InputBorder
                                                                    .none,
                                                            hintText:
                                                                'Send message...',
                                                            hintStyle: AppUtils
                                                                .textWhiteSFMedium14,
                                                            contentPadding:
                                                                EdgeInsets.symmetric(
                                                                    vertical:
                                                                        5.h,
                                                                    horizontal:
                                                                        10.h),
                                                            //Change this value to custom as you like
                                                            isDense: true,
                                                          ),
                                                        ),
                                                      ),
                                                    ),
                                                  ),
                                                  childOverlay: Stack(
                                                    alignment:
                                                        Alignment.center,
                                                    children: [
                                                      for (int i = 0;
                                                          i <
                                                              (story.editableList
                                                                      ?.length ??
                                                                  0);
                                                          i++)
                                                        AppUtils.buildItemWidget(
                                                            story.editableList?[
                                                                    i] ??
                                                                EditableItem(),
                                                            context,
                                                            objs: story,
                                                            storyControllers:
                                                                controller
                                                                    .storyController,
                                                            storyVideoPlayer:
                                                                controller
                                                                    .storyVideoPlayer)
                                                    ],
                                                  ),
                                                  isSeen:
                                                      story.isSeen ?? false,
                                                  cardDuration: Duration(
                                                      seconds:
                                                          (story.duration ??
                                                                  0)
                                                              .toInt()),
                                                  child: StoryChild(
                                                    key: Key(story.cdnUrl ??
                                                        UniqueKey()
                                                            .toString()),
                                                    story: story,
                                                    storyController:
                                                        controller
                                                            .storyController,
                                                    storyVideoPlayer:
                                                        controller
                                                            .storyVideoPlayer,
                                                    videoPlayerController:
                                                        controller
                                                            .videoPlayer,
                                                  )),
                                            )
                                            .toList(),
                                  ),
                                )
                                .toList(),
                          )

StoryChild is item of itembuilder.

class StoryChild extends StatefulWidget {
  final StoryItems? story;
  final StoryController? storyController;
  final VideoStoryController? storyVideoPlayer;
  final VideoPlayerController? videoPlayerController;

  const StoryChild(
      {super.key,
      this.story,
      this.storyController,
      this.storyVideoPlayer,
      this.videoPlayerController});

  @override
  State<StoryChild> createState() => _StoryChildState();
}

class _StoryChildState extends State<StoryChild> {
  StreamSubscription? _streamSubscription;
  bool _isInitialized = false;
  VideoPlayerController? videoPlayer;

  @override
  void initState() {
    super.initState();
    if (widget.story?.type == "video") {
      videoPlayer = widget.videoPlayerController;
      _initializeVideo();
    } else {
      _disposeVideo();
    }
  }

  // @override
  // void didUpdateWidget(StoryChild oldWidget) {
  //   super.didUpdateWidget(oldWidget);
  //   if (widget.story != oldWidget.story) {
  //     _disposeVideo();
  //     _initializeVideo();
  //   }
  // }

  Future<void> _initializeVideo() async {
    final file =
        await VideoCacheManager.getVideoFile(widget.story?.cdnUrl ?? '');
    videoPlayer = VideoPlayerController.file(file);
    await videoPlayer?.initialize().then(
      (value) {
        if (mounted) {
          setState(() {
            _isInitialized = true;
          });
        }
        _streamSubscription =
            widget.storyVideoPlayer!.playbackNotify.listen((playbackState) {
          if (playbackState == PlaybackState.pause) {
            // if (widget.isActive ?? false) {
            videoPlayer?.pause();
            widget.storyController?.pauseStory();
            // }
          } else {
            videoPlayer?.play();
            widget.storyController?.playStory();
          }
        });
      },
    );
  }

  void _disposeVideo() {
    videoPlayer?.dispose();
    videoPlayer = null;
    _streamSubscription?.cancel();
    _isInitialized = false;
  }

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

  @override
  Widget build(BuildContext context) {
    return widget.story?.type == "image"
        ? Stack(
            alignment: Alignment.center,
            fit: StackFit.expand,
            children: [
              Positioned.fill(
                child: Container(color: Colors.transparent),
              ),
              CachedNetworkImage(
                imageUrl: widget.story?.cdnUrl ?? '',
                fit: BoxFit.contain,
                alignment: Alignment.center,
                cacheKey: widget.story?.cdnUrl ?? '',
                cacheManager: CustomCacheManager().getCacheManager(
                  widget.story?.cdnUrl ?? '',
                ),
                progressIndicatorBuilder: (context, url, progress) => Center(
                  child: CircularProgressIndicator(
                    color: Colors.white,
                  ),
                ),
              ),
            ],
          )
        : widget.story?.type == "video"
            ? getContentView()
            : Container(
                decoration: BoxDecoration(
                  color: Color(
                    int.parse(widget.story?.backgroundColor ?? ''),
                  ),
                ),
                padding: const EdgeInsets.symmetric(
                  horizontal: 24,
                  vertical: 16,
                ),
              );
  }

  Widget getContentView() {
    // if (widget.videoLoader.state == LoadState.success && _videoPlayerController!.value.isInitialized) {
    if (_isInitialized) {
      return VisibilityDetector(
        key: Key(widget.story?.cdnUrl ?? ''),
        onVisibilityChanged: (info) {
          if (info.visibleFraction == 1) {
            widget.storyVideoPlayer?.play();
          } else if (info.visibleFraction == 0) {
            widget.storyVideoPlayer?.pause();
          }
        },
        child: Center(
          child: ClipRRect(
            borderRadius: BorderRadius.all(Radius.circular(10)),
            child: AspectRatio(
                aspectRatio: videoPlayer!.value.aspectRatio,
                child: VideoPlayer(videoPlayer!)),
          ),
        ),
      );
    } else {
      return Center(
        child: SizedBox(
          width: 70,
          height: 70,
          child: CircularProgressIndicator(
            valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
            strokeWidth: 3,
          ),
        ),
      );
    }
  }
}

本文标签: flutterVideo story as like instagram dispose issueStack Overflow