视频播放器抖动

时间:2020-10-24 18:33:39

标签: flutter

这是我的代码,正在其中播放视频。现在,我想在切换页面时停止(暂停)视频。有时代码可以正常工作,但有时会出现视频音频,但视频页面无法打开。我是初学者。我曾尝试在切换之前暂停视频,但是很遗憾,我的逻辑没有起作用。根据我的经验,这种情况是在缓冲视频时发生的,我切换了页面。

final feedViewModel = GetIt.instance<FeedViewModel>();
int currentIndex = -1;

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
  int _pageController = 0;

  List<Widget> _pages = [FeedScreen(), DiscoverPage(), InboxPage(), MePage()];

  counter(int index) {
    if (currentIndex >= 0) {
      try {
        if (feedViewModel.listVideos == null) {
          final feed = _FeedScreenState();
          if (index == 0) {
            feed.load("For you");
          }
        } else {
          feedViewModel.listVideos[currentIndex].controller.pause();
          feedViewModel.listVideos = null;
          feedViewModel.controller.dispose();
          feedViewModel.controller=null;
          super.dispose();
        }
      } catch (e) {
        feedViewModel.listVideos = null;
        final feed = _FeedScreenState();
        if (index == 0) {
          feed.load("For you");
        }
      }
    }
    _pageController = index;
  }

  @override
  Widget build(BuildContext context) {
    // Constants.pref.setBool("loggedIn", true);
    return ResponsiveBuilder(
      builder: (BuildContext context, SizingInformation sizingInformation) {
        return Scaffold(
            bottomNavigationBar: Container(
              padding: EdgeInsets.symmetric(horizontal: 15),
              color: Colors.black,
              height: sizingInformation.localWidgetSize.height * 0.08,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  InkWell(
                    onTap: () {
                      setState(() {
                        counter(0);
                      });
                    },
                    child: _navBarItem(
                      title: "Home",
                      icon: Icons.home,
                    ),
                  ),
                  InkWell(
                    onTap: () {
                      setState(() {
                        counter(1);
                      });
                    },
                    child: _navBarItem(
                      title: "Discover",
                      icon: Icons.search,
                    ),
                  ),
                  InkWell(
                    onTap: () async {
                  if (Constants.pref.getBool("loggedIn") == true) {
                    try {
                      if (currentIndex >= 0) {
                        try {
                          if (feedViewModel.listVideos != null) {
                            if (feedViewModel.listVideos[currentIndex]
                                .controller.value.isPlaying) {
                              feedViewModel
                                  .listVideos[currentIndex].controller
                                  .pause();
                              feedViewModel.listVideos = null;
                              feedViewModel.controller.dispose();
                              feedViewModel.controller=null;
                              super.dispose();
                            }
                          }
                        } catch (e) {}
                      }
                    } catch (e) {
                      print(e.toString());
                    }

                    final videoPath = await Navigator.of(context)
                        .pushNamed(CAMERA_SCREEN);

                    /* Navigator.push(
                        context,
                        MaterialPageRoute(
                            // builder: (_) => Video()
                            builder: (_) => HomeScreen2(null)
                            // builder: (_) => AddVideoPage()
                            ));*/
                  } else {
                    toast("Please login/sign up");
                  }
                },
                child: Container(
                  margin: EdgeInsets.only(top: 10),
                  width: 50,
                  height: sizingInformation.localWidgetSize.height * 0.07,
                  child: Stack(
                    children: <Widget>[
                      Align(
                        alignment: Alignment.topLeft,
                        child: Container(
                          width: 20,
                          height: sizingInformation.localWidgetSize.height *
                              0.05,
                          decoration: BoxDecoration(
                              borderRadius:
                                  BorderRadius.all(Radius.circular(10)),
                              color: Colors.blue),
                        ),
                      ),
                      Align(
                        alignment: Alignment.topRight,
                        child: Container(
                          width: 20,
                          height: sizingInformation.localWidgetSize.height *
                              0.05,
                          decoration: BoxDecoration(
                              borderRadius:
                                  BorderRadius.all(Radius.circular(10)),
                              color: Colors.red),
                        ),
                      ),
                      Align(
                        alignment: Alignment.topCenter,
                        child: Container(
                          width: 40,
                          height: sizingInformation.localWidgetSize.height *
                              0.05,
                          decoration: BoxDecoration(
                              borderRadius:
                                  BorderRadius.all(Radius.circular(10)),
                              color: Colors.white),
                          child: Icon(
                            Icons.add,
                            color: Colors.black,
                          ),
                        ),
                      )
                    ],),),),
              InkWell(
                onTap: () {
                  setState(() {
                    counter(2);
                  });
                },
                child: _navBarItem(
                  title: "Notification",
                  icon: Icons.message,
                ),
              ),
              InkWell(
                onTap: () {
                  setState(() {
                    counter(3);
                  });
                },
                child: _navBarItem(
                  title: "Profile",
                  icon: Icons.person,
                ),
              ),
            ],
          ),
        ),

        // body: Constants.pref.getBool("loggedIn") == true && _pageController==4
        //     ? _pages[_pageController]
        //     : ProfileApp());
        body: _pages[_pageController]);
      },
    );
  }

  Widget _navBarItem({String title, IconData icon}) {
    return Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[Icon(icon), Text(title)],
    );
  }

  toast(String message) {
    Fluttertoast.showToast(
    msg: message,
    toastLength: Toast.LENGTH_SHORT,
    gravity: ToastGravity.CENTER,
    timeInSecForIosWeb: 1);
  }
}

class FeedScreen extends StatefulWidget {
  // FeedScreen({Key key}) : super(key: key);

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

class _FeedScreenState extends State<FeedScreen>with SingleTickerProviderStateMixin {
  AnimationController _animationController;
  int _followingForYouController = 1;
  FullScreenDialog _myDialog;

  @override
  void initState() {
    _animationController =
        AnimationController(vsync: this, duration: Duration(seconds: 8));
    _animationController.repeat();
    load("For you");
    super.initState();
  }

  Future<bool> _onWillPop() async {
    if (currentIndex >= 0) {
      if (feedViewModel.listVideos != null) {
    feedViewModel.listVideos[currentIndex].controller.pause();
    feedViewModel.listVideos = null;
    feedViewModel.controller.dispose();
    feedViewModel.controller=null;
    super.dispose();
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return ViewModelBuilder<FeedViewModel>.reactive(
    disposeViewModel: false,
    builder: (context, model, child) => videoScreen(),
    viewModelBuilder: () => feedViewModel);
  }

  Widget videoScreen() {
    return WillPopScope(
      onWillPop: _onWillPop,
      child: ResponsiveBuilder(
      builder: (BuildContext context, SizingInformation sizingInformation) {
    return Padding(
        padding: const EdgeInsets.all(1),
        child: Scaffold(
          backgroundColor: GetIt.instance<FeedViewModel>().actualScreen == 0
              ? Colors.black
              : Colors.white,
          body: Stack(
            children: [
              PageView.builder(
                  itemCount: 1,
                  onPageChanged: (value) {
                    print(value);
                    if (value == 1)
                      SystemChrome.setSystemUIOverlayStyle(
                          SystemUiOverlayStyle.dark);
                    else
                      SystemChrome.setSystemUIOverlayStyle(
                          SystemUiOverlayStyle.light);
                  },
                  itemBuilder: (context, index) {
                    return scrollFeed(sizingInformation);
                  })
            ],
          ),
        ));
      }),
    );
  }

  Widget scrollFeed(SizingInformation sizingInformation) {
    return Column(
  mainAxisAlignment: MainAxisAlignment.end,
  children: [
    Expanded(child: feedVideos(sizingInformation)),
  ],
    );
  }

  Widget feedVideos(SizingInformation sizingInformation) {
    return feedViewModel.listVideos != null
    ? Scaffold(body: videoPage(sizingInformation))
    : Center(child: CircularProgressIndicator());
  }

  Widget videoPage(SizingInformation sizingInformation) {
    return Stack(
  children: [
    PageView.builder(
      controller: PageController(
        initialPage: 0,
        viewportFraction: 1,
      ),
      itemCount: feedViewModel.listVideos.length,
      onPageChanged: (index) {
        index = index % (feedViewModel.listVideos.length);
        feedViewModel.changeVideo(index);
      },
      scrollDirection: Axis.vertical,
      itemBuilder: (context, index) {
        currentIndex = index;
        index = index % (feedViewModel.listVideos.length);
        return videoCard(
            feedViewModel.listVideos[index], index, sizingInformation);
      },
    ),
    followingForYou(),
      ],
    );
  }

  Widget videoCard(
  Video video, int index, SizingInformation sizingInformation) {
    return Stack(
  children: [
    video.controller != null
        ? GestureDetector(
            onTap: () {
              if (video.controller.value.isPlaying) {
                video.controller.pause();
              } else {
                video.controller.play();
              }
            },
            child: SizedBox.expand(
                child: FittedBox(
              fit: BoxFit.cover,
              child: SizedBox(
                width: video.controller.value.size?.width ?? 0,
                height: video.controller.value.size?.height ?? 0,
                child: VideoPlayer(video.controller),
              ),
            )),
          )
        : Container(
            color: Colors.black,
            child: Center(
              child: Text("Loading..."),
            ),
          ),
    Column(
      mainAxisAlignment: MainAxisAlignment.end,
      children: <Widget>[
        Row(
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.end,
          children: <Widget>[
            VideoDescription(
                video.id, video.user, video.videoTitle, video.songName),
            _rightWidget(video, index),
            // _rightSideButtonsWidgets(index),
            // _textDataWidgetBottom(sizingInformation, index)
          ],
        ),
        SizedBox(height: 20)
      ],
    ),
      ],
    );
  }

  @override
  void dispose() {
    try {
  feedViewModel.controller.dispose();
  feedViewModel.controller=null;
  super.dispose();
    } catch (e) {
      print(e.toString());
    }
      }

  load(String type) async {
    feedViewModel.listVideos = await getVideoList(type);
    setState(() {
      feedViewModel.loadVideo(0);
  // feedViewModel.loadVideo(1);
    });
  }

  Future<List<Video>> getVideoList(String type) async {
var videoList = <Video>[];

final body = {
  "username": Constants.pref.getString("profileId"),
  "Type": type,
};
var jsonObj = json.encode(body);
var response = await http.post('https://ssca-api.appspot.com/act/video/',
    headers: {"api-Key": "NkHb13BxRBiZ0JSyxLbAU"}, body: jsonObj);
print("${response.request}"); //200 if successful
print("http status: ${response.statusCode}"); //200 if successful
print("http Request: ${jsonObj}"); //200 if successful
print("http Response: ${response.body}");
var data = json.decode(response.body);

// data = jsonDecode(response.body);

for (int i = 0; i < data["video"].length; i++) {
  Video video = new Video();
  video.id = data["video"][i]["id"];
  video.user = data["video"][i]["profileId"];
  video.userPic = data["video"][i]["image"];
  video.videoTitle = data["video"][i]["description"];
  video.songName = "Music name is here";
  video.likes = data["video"][i]["liked"];
  video.comments = data["video"][i]["comment"];
  video.url = data["video"][data["video"].length-1]["video"];
  // video.url = data["video"][i]["video"];
  video.isLiked = data["video"][i]["isLiked"];
  if (data["video"][i]["followstatus"] == 0) {
    video.following = false;
  } else {
    video.following = true;
  }
  video.isLiked = data["video"][i]["isLiked"];
  videoList.add(video);
}

return videoList;
  }

  toast(String message) {
Fluttertoast.showToast(
    msg: message,
    toastLength: Toast.LENGTH_SHORT,
    gravity: ToastGravity.CENTER,
    timeInSecForIosWeb: 1);
  }

  // Full dimensions of an action
  static const double ActionWidgetSize = 60.0;

// The size of the icon showen for Social Actions
  static const double ActionIconSize = 35.0;

// The size of the share social icon
  static const double ShareActionIconSize = 25.0;

// The size of the profile image in the follow Action
  static const double ProfileImageSize = 50.0;

// The size of the plus icon under the profile image in follow action
  static const double PlusIconSize = 20.0;

  LinearGradient get musicGradient => LinearGradient(colors: [
        Colors.grey[800],
    Colors.grey[900],
    Colors.grey[900],
    Colors.grey[800]
  ], stops: [
    0.0,
    0.4,
    0.6,
    1.0
  ], begin: Alignment.bottomLeft, end: Alignment.topRight);

  Widget _rightWidget(Video video, int index) {
return Container(
  width: 100.0,
  child: Column(mainAxisSize: MainAxisSize.min, children: [
    _getFollowAction(index),
    _likeWidget(index),
    GestureDetector(
      onTap: () {
        if (Constants.pref.getBool("loggedIn") == true) {
          Navigator.push(
              context,
              MaterialPageRoute(
                  builder: (context) =>
                      CommentList(feedViewModel.listVideos[index].id)));
        } else {
          toast("Please login/sign up");
        }
      },
      child: Container(
          margin: EdgeInsets.only(top: 15.0),
          width: 60.0,
          height: 60.0,
          child: Column(children: [
            Icon(FontAwesomeIcons.comment,
                size: 35.0, color: Colors.grey[300]),
            Padding(
              padding: EdgeInsets.only(top: 8.0),
              child: Text(video.comments,
                  style: TextStyle(
                      color: Colors.white,
                      fontWeight: FontWeight.w500,
                      fontSize: 12.0)),
            )
          ])),
    ),
    GestureDetector(
      onTap: () {
        // _shareImageAndText(video);
        Share.share('check out my video ' + video.url);
      },
      child: Container(
          margin: EdgeInsets.only(top: 15.0),
          width: 60.0,
          height: 60.0,
          child: Column(children: [
            Icon(FontAwesomeIcons.share,
                size: 25.0, color: Colors.grey[300]),
            Padding(
              padding: EdgeInsets.only(top: 8.0),
              child: Text('Share',
                  style: TextStyle(
                      color: Colors.white,
                      fontWeight: FontWeight.w500,
                      fontSize: 12.0)),
            )
          ])),
    ),
    GestureDetector(
      onTap: () {
        Navigator.push(
            context,
            new MaterialPageRoute(
              builder: (BuildContext context) => _myDialog =
                  new FullScreenDialog(feedViewModel.listVideos[index].id),
              fullscreenDialog: true,
            ));
      },
      child: Container(
          margin: EdgeInsets.only(top: 15.0),
          width: 60.0,
          height: 60.0,
          child: Column(children: [
            Icon(FontAwesomeIcons.angry,
                size: 25.0, color: Colors.grey[300]),
            Padding(
              padding: EdgeInsets.only(top: 8.0),
              child: Text('Report',
                  style: TextStyle(
                      color: Colors.white,
                      fontWeight: FontWeight.w500,
                      fontSize: 12.0)),
            )
          ])),
    ),
    CircleImageAnimation(
      child: _getMusicPlayerAction(video.userPic),
    )
  ]),
    );
  }

  Widget _likeWidget(int index) {
return GestureDetector(
  onTap: () {
    if (Constants.pref.getBool("loggedIn") == true) {
      setState(() {
        if (feedViewModel.listVideos[index].isLiked) {
          feedViewModel.listVideos[index].isLiked = false;
        } else {
          feedViewModel.listVideos[index].isLiked = true;
        }

        final body = {
          "username": Constants.pref.getString("profileId"),
          "videoId": feedViewModel.listVideos[index].id,
          "like": feedViewModel.listVideos[index].isLiked,
        };
        ApiService.like(body).then((success) {
          if (success.statusCode == 200) {
            var response = json.decode(success.body);
            if (response["response"]["confirmation"] != 0) {
              feedViewModel.listVideos[index].likes =
                  response["response"]["TotalLiked"];
            } else {
              ShowAlertDialog(context, response["success"]["message"]);
            }
          } else {
            ShowAlertDialog(context, ParameterConstant.STATUS);
          }
        });
      });
    } else {
      toast("Please login/sign up");
    }
  },
  child: Container(
      margin: EdgeInsets.only(top: 15.0),
      width: 60.0,
      height: 60.0,
      child: Column(children: [
        Icon(
          FontAwesomeIcons.solidHeart,
          size: 35.0,
          color:
              feedViewModel.listVideos[index].isLiked ? Colors.red : null,
        ),
        Padding(
          padding: EdgeInsets.only(top: 8.0),
          child: Text(feedViewModel.listVideos[index].likes,
              style: TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.w500,
                  fontSize: 12.0)),
        )
      ])),
    );
  }

  Widget _getFollowAction(int index) {
    return GestureDetector(
  onTap: () {
    if (Constants.pref.getBool("loggedIn") == true) {
      setState(() {
        if (feedViewModel.listVideos[index].following) {
          feedViewModel.listVideos[index].following = false;
        } else {
          feedViewModel.listVideos[index].following = true;
        }

        final body = {
          "profileId": Constants.pref.getString("profileId"),
          "followupId": feedViewModel.listVideos[index].user,
        };
        ApiService.follow(body).then((success) {
          if (success.statusCode == 200) {
            var response = json.decode(success.body);
            // if (response["confirmation"] != 0) {
            /* if (feedViewModel.listVideos[index].following) {
              feedViewModel.listVideos[index].following = false;
            } else {
              feedViewModel.listVideos[index].following = true;
            }*/
            // } else {
            //   ShowAlertDialog(context, response["message"]);
            // }
          } else {
            ShowAlertDialog(context, ParameterConstant.STATUS);
          }
        });
      });
    } else {
      toast("Please login/sign up");
    }
  },
  child: Container(
      margin: EdgeInsets.symmetric(vertical: 10.0),
      width: 60.0,
      height: 60.0,
      child: Stack(children: [
        _getProfilePicture(feedViewModel.listVideos[index].userPic),
        _getPlusIcon(index)
      ])),
    );
  }

  Widget _getProfilePicture(userPic) {
return Positioned(
    left: (ActionWidgetSize / 2) - (ProfileImageSize / 2),
    child: Container(
        padding: EdgeInsets.all(1.0),
        // Add 1.0 point padding to create border
        height: ProfileImageSize,
        // ProfileImageSize = 50.0;
        width: ProfileImageSize,
        // ProfileImageSize = 50.0;
        decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.circular(ProfileImageSize / 2)),
        // import 'package:cached_network_image/cached_network_image.dart'; at the top to use CachedNetworkImage
        child: ClipRRect(
            borderRadius: BorderRadius.circular(10000.0),
            child: CachedNetworkImage(
              imageUrl: userPic,
              placeholder: (context, url) =>
                  new CircularProgressIndicator(),
              errorWidget: (context, url, error) => new Icon(Icons.error),
            ))));
  }

  Widget _getPlusIcon(int index) {
return Positioned(
  bottom: 0,
  left: ((ActionWidgetSize / 2) - (PlusIconSize / 2)),
  child: Container(
      width: PlusIconSize, // PlusIconSize = 20.0;
      height: PlusIconSize, // PlusIconSize = 20.0;
      decoration: BoxDecoration(
          color: Color.fromARGB(255, 255, 43, 84),
          borderRadius: BorderRadius.circular(15.0)),
      child: Icon(
        feedViewModel.listVideos[index].following
            ? Icons.remove
            : Icons.add,
        color: Colors.white,
        size: 20.0,
      )),
);
// import_contacts, clear,forward,gesture
  }

  Widget _getMusicPlayerAction(userPic) {
    return Container(
    margin: EdgeInsets.only(top: 10.0),
    width: ActionWidgetSize,
    height: ActionWidgetSize,
    child: Column(children: [
      Container(
          padding: EdgeInsets.all(11.0),
          height: ProfileImageSize,
          width: ProfileImageSize,
          decoration: BoxDecoration(
              gradient: musicGradient,
              borderRadius: BorderRadius.circular(ProfileImageSize / 2)),
          child: ClipRRect(
              borderRadius: BorderRadius.circular(10000.0),
              child: CachedNetworkImage(
                imageUrl: userPic,
                placeholder: (context, url) =>
                    new CircularProgressIndicator(),
                errorWidget: (context, url, error) => new Icon(Icons.error),
              ))),
    ]));
  }

  TextStyle _textStyleFollowingForYou(Color color) {
    return TextStyle(fontSize: 18, color: color, fontWeight: FontWeight.w500);
  }

  Widget followingForYou() {
    return SafeArea(
  child: Container(
    padding: EdgeInsets.only(top: 20),
    child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              GestureDetector(
                  onTap: () {
                    setState(() {
                      if (Constants.pref.getBool("loggedIn") == true) {
                        _followingForYouController = 0;
                        setState(() {
                          feedViewModel.listVideos[currentIndex].controller
                              .pause();
                          feedViewModel.listVideos = null;
                          load("Following");
                        });
                      } else {
                        toast("Please login/sign up");
                      }
                    });
                  },
                  child: Text("Following",
                      style: _textStyleFollowingForYou(
                          _followingForYouController == 0
                              ? Colors.white
                              : Colors.white60))),
              SizedBox(
                width: 15,
              ),
              GestureDetector(
                  onTap: () {
                    setState(() {
                      try {
                        feedViewModel.listVideos[currentIndex].controller
                            .pause();
                      } catch (e) {
                        print(e.toString());
                      }
                      _followingForYouController = 1;
                      feedViewModel.listVideos = null;
                      load("For you");
                    });
                  },
                  child: Text("For you",
                      style: _textStyleFollowingForYou(
                          _followingForYouController == 1
                              ? Colors.white
                              : Colors.white60)))
            ],
          ),
        ]),
  ),
    );
  }
}

0 个答案:

没有答案