我正在视频滚动应用程序上创建,我有多个视频。所以我遇到的问题是,当我滚动视频时,它需要加载然后播放视频,如果滚动回到同一个视频,那么它会再次加载然后播放。如果我快速滚动,那么视频控制器就会崩溃并且无法正常工作。
我使用页面浏览生成器垂直滚动,但我不知道最好的解决方案是什么。我在 onPageChanged 中写了一些代码 即使这就是为什么我猜它加载很多所以我正在寻找最好的解决方案
这是我的代码
设计形象
onPageChange 事件
onPageChanged(index) async {
videoPlayerController!.value.dispose();
videoPlayerController!.value =
VideoPlayerController.network(widget.videosList[index]["video_link"]);
videoPlayerController!.value.setLooping(true);
videoPlayerController!.value.initialize().then(
(_) {
if (isAutoplay.value == true) {
videoPlayerGetXController.isPlaying.value = true;
videoPlayerController!.value.play();
log(videoPlayerController!.value.value.size.toString());
} else {
videoPlayerGetXController.isPlaying.value = false;
}
videoPlayerGetXController.update();
},
);
PipFlutterPlayerDataSource dataSource = PipFlutterPlayerDataSource(
PipFlutterPlayerDataSourceType.network,
widget.videosList[index]["video_link"],
);
videoPlayerGetXController.pipFlutterPlayerController.value =
PipFlutterPlayerController(
PipFlutterPlayerConfiguration(
eventListener: (PipFlutterPlayerEvent value) {
if (PipFlutterPlayerEventType.pipStart ==
value.pipFlutterPlayerEventType) {
videoPlayerGetXController.pipFlutterPlayerController.value.play();
}
if (PipFlutterPlayerEventType.pipStop ==
value.pipFlutterPlayerEventType) {
videoPlayerGetXController.pipFlutterPlayerController.value.pause();
}
},
aspectRatio: 9 / 16,
fit: BoxFit.contain,
controlsConfiguration: const PipFlutterPlayerControlsConfiguration(
enablePlayPause: false,
),
// autoPlay: true,
deviceOrientationsAfterFullScreen: [DeviceOrientation.portraitUp],
deviceOrientationsOnFullScreen: [DeviceOrientation.portraitUp],
),
);
videoPlayerGetXController.pipFlutterPlayerController.value
.setupDataSource(dataSource);
videoPlayerGetXController.pipFlutterPlayerController.value
.setPipFlutterPlayerGlobalKey(
videoPlayerGetXController.pipFlutterPlayerKey);
// videoController.pipFlutterPlayerController.value.pause();
videoPlayerGetXController.update();
}
页面视图生成器代码
PageView.builder(
controller: widget.pageController.value,
onPageChanged: (index) async {
onPageChanged(index);
},
scrollDirection: Axis.vertical,
itemCount: widget.videosList.length,
itemBuilder: (context, i) {
pageindex = i;
// Future.delayed(const Duration(seconds: 1));
return videoPlayerGetXController
.pipFlutterPlayerController.value.isFullScreen
? Stack(
children: [
Container(
height: 1,
width: 1,
color: purpleColor,
child: PipFlutterPlayer(
controller: videoPlayerGetXController
.pipFlutterPlayerController.value,
key: videoPlayerGetXController
.pipFlutterPlayerKey,
),
),
VideoPlayer(videoPlayerController!.value)
],
)
: InkWell(
onTap: () {
if (videoPlayerController!
.value.value.isPlaying) {
videoPlayerGetXController.isPlaying.value =
false;
videoPlayerController!.value.pause();
} else {
videoPlayerGetXController.isPlaying.value =
true;
videoPlayerController!.value.play();
}
// videoPlayerGetXController.update();
},
child: Stack(
children: [
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
color: primaryBlack,
child: Stack(
alignment: Alignment.center,
children: [
if (videoPlayerController!
.value.value.isInitialized)
SizedBox(
height: 0,
width: 0,
child: PipFlutterPlayer(
controller:
videoPlayerGetXController
.pipFlutterPlayerController
.value,
key: videoPlayerGetXController
.pipFlutterPlayerKey,
),
),
videoPlayerController!
.value.value.isInitialized
? VideoPlayer(
videoPlayerController!.value)
: Container(),
Positioned(
bottom: widget.fromHomePage == true
? Get.height * 0.1
: 20,
child: SizedBox(
height: 8,
width: Get.width,
child: VideoProgressIndicator(
videoPlayerController!.value,
allowScrubbing: true,
colors: const VideoProgressColors(
bufferedColor: primaryWhite,
backgroundColor: primaryWhite,
playedColor: purpleColor,
),
),
),
),
if (widget.fromHomePage != true)
Positioned(
top: 10,
left: 10,
child: GestureDetector(
onTap: () {
Get.back();
},
child: Container(
margin:
const EdgeInsets.symmetric(
horizontal: 20,
vertical: 40),
height: 50,
width: 50,
decoration: BoxDecoration(
color: whiteColor
.withOpacity(.2),
borderRadius:
BorderRadius.circular(12),
),
child: const Icon(
Icons
.arrow_back_ios_new_outlined,
size: 16,
color: primaryWhite,
),
),
),
),
],
),
),
// if (!videoPlayerGetXController
// .isPlaying.value)
// const Center(
// child: Icon(
// Icons.play_arrow,
// color: primaryWhite,
// size: 50,
// ),
// ),
],
),
);
},
),
当您不使用应用程序时,TikTok、Instagram 等会在后台加载内容。所以当你打开它时,你总是有一些已经加载的东西,可以立即显示, 访问 https://stackoverflow.com/a/55891860/21947028
您可以使用此小部件来播放视频。只需传递视频的 URL 即可正常工作。
在 pubspec 中添加这两个插件
https://pub.dev/packages/chewie 和 https://pub.dev/packages/video_player
import 'package:chewie/chewie.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class VideoWidget extends StatefulWidget {
final String url;
const VideoWidget({required this.url});
@override
_VideoWidgetState createState() => _VideoWidgetState();
}
class _VideoWidgetState extends State<VideoWidget> {
late VideoPlayerController videoPlayerController;
late Future<void> _initializeVideoPlayerFuture;
@override
void initState() {
super.initState();
videoPlayerController =
new VideoPlayerController.networkUrl(Uri.parse(widget.url));
_initializeVideoPlayerFuture = videoPlayerController.initialize().then((_) {
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
setState(() {});
});
}
@override
void dispose() {
videoPlayerController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
return (snapshot.connectionState == ConnectionState.done)
? SizedBox(
height: 200,
child: Chewie(
key: new PageStorageKey(widget.url),
controller: ChewieController(
videoPlayerController: videoPlayerController,
autoInitialize: true,
looping: true,
showOptions: false,
allowFullScreen: false,
errorBuilder: (context, errorMessage) {
return Center(
child: Text(
errorMessage,
style: TextStyle(color: Colors.white),
),
);
},
),
),
)
: SizedBox(
height: 200,
child: Center(
child: (snapshot.connectionState != ConnectionState.none)
? CircularProgressIndicator()
: SizedBox(),
),
);
},
);
}
}