Flutter Video Player On Click 传递 URL 动态并加载要播放的视频
Posted
技术标签:
【中文标题】Flutter Video Player On Click 传递 URL 动态并加载要播放的视频【英文标题】:Flutter Video Player On Click Pass URL dynamic and Load Video to play 【发布时间】:2020-05-12 15:53:04 【问题描述】:sample screen of video player attached below 我怎样才能让视频播放器动态播放,同时通过传递视频URL点击列表播放视频?
点击时我通过了 URL 并尝试重新初始化并开始播放它不工作,状态没有改变
这是我的代码,
videoplayerscreen.dart,
class VideoPlayerScreen extends StatefulWidget
int playBackTime;
int playBackTotalTime;
String setPlayTime;
String setPlayDuration;
double aspectRatio;
String videoUrl;
bool isForward;
bool isFullScreen;
bool allowFullScreen;
bool showControls;
bool isAutoPlay;
int startWithinSeconds;
VideoPlayerScreen(
Key key,
this.playBackTime = 0,
this.playBackTotalTime = 0,
this.setPlayTime = "00:00",
this.setPlayDuration = "00:00",
this.aspectRatio = 16 / 9,
this.videoUrl =
"",
this.isForward = true,
this.isFullScreen = false,
this.allowFullScreen = false,
this.showControls = true,
this.isAutoPlay = false,
this.startWithinSeconds = 0,
) : super(key: key);
@override
_VideoPlayerScreenState createState() => _VideoPlayerScreenState();
class _VideoPlayerScreenState extends State<VideoPlayerScreen>
VideoPlayerController _controller;
void initPlayer() async
_controller = VideoPlayerController.network(widget.videoUrl);
await _controller.initialize();
_controller.setLooping(true);
_controller.seekTo(Duration(seconds: widget.startWithinSeconds));
if (widget.isAutoPlay)
_controller.play();
_controller.addListener(()
setState(()
widget.playBackTime = _controller.value.position.inSeconds;
widget.setPlayTime = timeFormatter(widget.playBackTime);
);
);
@override
void initState()
initPlayer();
super.initState();
@override
void dispose()
_controller.dispose();
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
super.dispose();
在配置中,
video_player: ^0.10.5
调用其他类 CourseDetails.dart ,
Container(
padding: EdgeInsets.only(left: 20.0, right: 20.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: _playUrl != null
? VideoPlayerScreen(videoUrl: _playUrl)
: Image.asset(
'assets/images/test_video_player_screen.png'),
),
)
GestureDetector(
**here i am changing the state **
onTap: ()
setState(()
_playUrl = videoLists['course_video_url'];
);
,
child: Padding(
padding:
EdgeInsets.only(left: 10.0, right: 20.0, top: 2.0, bottom: 5.0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
"$videoLists['sn_no']",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.black45,
fontFamily: 'Oswald-SemiBold'),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 10.0),
child: Text(
"$videoLists['course_video_title']",
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.black45,
fontFamily: 'Oswald-SemiBold'),
),
),
Row(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 10.0),
child: Text(
"Video - $videoLists['course_video_duration']",
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.grey,
fontFamily: 'Oswald-SemiBold'),
),
),
Padding(
padding: EdgeInsets.only(left: 5.0),
child: videoLists['course_watched']
? Image.asset(
'assets/images/green_tick_icon.png',
width: 12.0,
height: 12.0,
)
: null),
],
),
],
),
],
),
),
)
【问题讨论】:
您能解释一下您在setState
上的onTap
上的这个类初始化做什么吗?这段代码中很少有令人困惑的地方,使我们难以帮助您调试。
你当然会解释,实际上我已经创建了两个类, 1.VideoPlayerScreen 2.CourseDetails 在 CourseDetails.dart 中,我正在调用其余的 api 来获取 VideoURL 的列表并显示在列表视图中, onTap 在用户单击特定列表项时被调用。那时我将 URL 传递给 VideoPlayerScreen.dart 来播放视频,因此在第一次播放时,在下一次点击时,视频 url 正在传递但视频没有播放,帮我解决它如何在传递 URL @JoãoSoares 时动态播放视频播放器
【参考方案1】:
感谢所有回复。我得到了解决方案:
在Build
函数中,我检查了是否发生了任何 url 更改。如果发生变化,我处理旧控制器并重新初始化视频控制器。然后,它对我来说很好。
@override
Widget build(BuildContext context)
if (currentObjectVideoUrl != widget.videoUrl)
_controller.dispose();
initPlayer();
【讨论】:
如何找到 currentObjectVideoUrl ?【参考方案2】:您可以通过创建一个传递 URL 的有状态小部件来实现此目的。然后在init方法里面,就可以这样做了
class ViewVideo extends StatefulWidget
final link;
ViewVideo(this.link);
@override
_ViewVideoState createState() => _ViewVideoState(this.link);
class _ViewVideoState extends State<ViewVideo>
final link;
_ViewVideoState(this.link);
@override
void initState()
super.initState();
//Write your video player code here
@override
Widget build(BuildContext context)
return Scaffold(
body: Container(),
);
@override
void dispose()
//Here you can close the video player
super.dispose();
【讨论】:
我尝试过同样的事情但仍然无法正常工作,它不会破坏旧视频,也不会播放新视频@K K 我已经修改了问题并简单地添加了我的代码@K K 您必须添加 dispose 方法并关闭现有控制器。检查我更新的代码。 是的,我已经添加了`@override void dispose() _controller.dispose(); SystemChrome.setPreferredOrientations([ DeviceOrientation.landscapeRight, DeviceOrientation.landscapeLeft, DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); super.dispose(); ` @KK,我也试过你的方法。它不工作。【参考方案3】:我已根据您的 cmets 修改了我的回复。您只需要将视频网址放在您使用 setState 更改的类变量上。然后在您的小部件上检查变量是否存在并决定显示VideoPlayerScreen
小部件或空框。
String videoUrl = '';
@override
Widget build(BuildContext context)
return Column(
children: <Widget>[
videoUrl == '' ? SizedBox() : VideoPlayerScreen(videoUrl: videoUrl),
RaisedButton(
onPressed: ()
setState(()
videoUrl == videoLists['course_video_url'];
);
),
],
);
【讨论】:
嗨,但我在一个屏幕上做,这里我附上设计的图像,(i.stack.imgur.com/PoeyX.png)在这个 URL 的图像列表中点击我在顶部播放视频@若昂·苏亚雷斯 @Jai 我已经修改了我的回复以符合您的评论。 @Jai 你的 VideoPlayerScreen 类中显示视频的 build 方法在哪里,你能分享一下吗? VideoPlayerScreen 构建方法,` @override Widget build(BuildContext context) if (_controller.value.initialized) AspectRatio( aspectRatio: widget.aspectRatio, child: VideoPlayer(_controller), ) ` @Joao Soares【参考方案4】:你可以使用didUpdateWidget
方法。
我们可以比较 Widget 类的任何属性,并据此重置播放器。
对于重置,一般步骤是
-
停止播放器
关闭会话
再次初始化播放器(使用新的 URL 和其他参数)
下面是逻辑的代码sn-p。
class _VideoPlayerScreenState extends State<VideoPlayerScreen>
VideoPlayerController _controller;
void initPlayer() async
/// initialise player
void disposePlayer()
/// dispose player
void resetPlayer()
disposePlayer();
initPlayer();
@override
void initState()
initPlayer();
super.initState();
@override
void didUpdateWidget(VideoPlayerScreen oldWidget)
super.didUpdateWidget(oldWidget);
if (oldWidget.videoUrl != widget.videoUrl)
resetPlayer();
@override
void dispose()
disposePlayer();
super.dispose();
didUpdateWidget 方法的参考。
【讨论】:
以上是关于Flutter Video Player On Click 传递 URL 动态并加载要播放的视频的主要内容,如果未能解决你的问题,请参考以下文章
Qt/C++ Multimedia Player Video Clips,多个视频小部件