这篇文章主要讲解了“Flutter中视频播放器插件如何使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Flutter中视频播放器插件如何使用”吧!
创建一个新的视频播放器
在使用视频播放器插件之前,你应该把它添加到你的pubspec.yaml
文件中。当你打开pubspec.yaml
文件时,你可以看到运行你的应用程序所需的一些配置和依赖性。我们的视频播放器插件应该被添加到dependencies
块下。
dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.2 video_player: 2.1.15 //video player
该插件的当前版本是2.1.15
,但你可以通过查看插件页面在这里添加最新版本。如果你保存文件时是在VS Code中,它会自动下载该插件。如果不是,打开终端,写flutter pub get
来下载该插件。
进入你想添加该插件的文件,并导入video_player.dart
文件。
import 'package:video_player/video_player.dart';
现在你可以在你的项目中使用视频播放器插件了。
有几种方法来加载视频。让我们从资产中加载我们的例子。在项目的根层创建一个assets/video文件夹,在该文件夹内添加一个视频。然后在pubspec.yaml
,在assets
部分,指定文件路径,如下所示。
assets: - assets/video/video.mp4
让我们创建一个单独的有状态的部件,称为VideoPlayerWidget
,以插入我们的视频播放器相关的实现。
你可以在initState
方法中初始化视频播放器,如下所示。另外,别忘了dispose
,让视频播放器做清理工作。
class _VideoPlayerState extends State<VideoPlayerWidget> { late VideoPlayerController _videoPlayerController; @override void initState() { super.initState(); _videoPlayerController = VideoPlayerController.asset( 'assets/video/video.mp4') ..initialize().then((_) { setState(() {}); _videoPlayerController.play(); }); } @override void dispose() { _videoPlayerController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Center( child: VideoPlayer(_videoPlayerController), ); }}
VideoPlayerController
必须用late
关键字来指定,因为我们在这一行中仍然没有定义视频播放器控制器,我们将在后面做这个。在initState
里面,videoPlayerController
已经和资产的路径一起被初始化。
当初始化完成后,它改变了状态并重建了小部件。你可以在初始化后开始播放视频。
取代assets
,你可以使用视频的URL。为了访问网络,你应该给Android和iOS添加互联网权限配置。
从根目录下,进入ios/Runner
,打开info.plist
文件。然后,在该文件中添加以下配置。
<key>NSAppTransportSecurity</key><dict> <key>NSAllowsArbitraryLoads</key> <true/></dict>
接下来,去android/app/src/main
,并打开AndroidManifest.xml
。然后,向其添加以下代码。
<uses-permission android:name="android.permission.INTERNET"/>
现在你可以把asset
改为network
,并在那里添加视频URL。
@override void initState() { super.initState(); _videoPlayerController = VideoPlayerController.network('video_url_here') ..initialize().then((_) { setState(() {}); _videoPlayerController.play(); }); }
即使初始化已经完成,也应该有办法在用户界面中显示播放器。VideoPlayer
widget可以用来做到这一点。为了使它工作,你应该把控制器作为第一个参数传递给VideoPlayer
widget。
在显示VideoPlayer
widget之前,最好先检查初始化是否成功。
@override Widget build(BuildContext context) { return Center( child: _videoPlayerController.value.isInitialized ? VideoPlayer(_videoPlayerController) : Container(), ); }
现在你可以看到屏幕上的视频了。但是有一个小问题:它的长宽比不合适。这可以通过使用AspectRatio
widget来解决。视频播放器提供了一个适当的视频长宽比,你可以使用这个值来设置为AspectRatio
widget。
@override Widget build(BuildContext context) { return Center( child: _videoPlayerController.value.isInitialized ? AspectRatio(aspectRatio: _videoPlayerController.value.aspectRatio, child: VideoPlayer(_videoPlayerController) ) : Container(), ); }
现在你可以看到具有适当长宽比的视频。
添加播放和暂停按钮
首先,让我们把视频播放器小部件包在一个列小部件里面,因为我们应该把播放和暂停按钮放在播放器下面。在播放器小组件之后的列内,让我们在一个Row
小组件内添加两个ElevatedButton
小组件,在这些按钮之间让我们添加一个Padding
小组件以保持一些呼吸空间。
对每个ElevatedButton
,添加相关的Icons
,作为子部件。然后在播放按钮onPressed
的回调里面,你可以参考_videoPlayerController
,并调用play
方法来开始播放视频。在暂停按钮里面,使用pause
方法而不是播放。
现在你可以删除之前在initState
方法里面添加的播放。
@override Widget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ _videoPlayerController.value.isInitialized ? AspectRatio(aspectRatio: _videoPlayerController.value.aspectRatio, child: VideoPlayer(_videoPlayerController) ) : Container(), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton(onPressed: (){ _videoPlayerController.pause(); }, child: Icon(Icons.pause)), Padding(padding: EdgeInsets.all(2)), ElevatedButton(onPressed: (){ _videoPlayerController.play(); }, child: Icon(Icons.play_arrow)) ], ) ], ); }
另外,你可以给按钮添加样式,得到一个看起来很圆的按钮,这通常是在视频播放器中。
@override Widget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ _videoPlayerController.value.isInitialized ? AspectRatio( aspectRatio: _videoPlayerController.value.aspectRatio, child: VideoPlayer(_videoPlayerController)) : Container(), Padding( padding: EdgeInsets.all(20), ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all<Color>(Colors.blue), fixedSize: MaterialStateProperty.all(Size(70, 70)), shape: MaterialStateProperty.all(RoundedRectangleBorder( borderRadius: BorderRadius.circular(100)))), onPressed: () { _videoPlayerController.pause(); }, child: Icon(Icons.pause)), Padding(padding: EdgeInsets.all(2)), ElevatedButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all<Color>(Colors.redAccent), fixedSize: MaterialStateProperty.all<Size>(Size(80, 80)), shape: MaterialStateProperty.all(RoundedRectangleBorder( borderRadius: BorderRadius.circular(100)))), onPressed: () { _videoPlayerController.play(); }, child: Icon(Icons.play_arrow)) ], ) ], ); }
创建一个快进
在实现快进之前,让我们思考一下我们需要什么。首先,应该有一个访问当前视频位置/时间的方法和一个设置新值的方法。控制器的seekTo
方法允许我们为视频设置持续时间。
你可以通过视频播放器value
属性访问当前的视频位置,就像下面这样。
ElevatedButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all<Color>(Colors.blue), fixedSize: MaterialStateProperty.all(Size(70, 70)), shape: MaterialStateProperty.all(RoundedRectangleBorder( borderRadius: BorderRadius.circular(100)))), onPressed: () { _videoPlayerController.seekTo(Duration( seconds: _videoPlayerController.value.position.inSeconds + 10)); }, child: Icon(Icons.fast_forward))
像这样,当用户点击按钮时,你也可以通过减少10
秒来实现向后倒转。
添加一个视频进度指示器
视频播放器插件提供了内置的功能来添加一个进度条以及一些控件。你可以使用VideoProgressIndicator
widget来实现这个功能。
作为第一个参数,你必须传递控制器并设置allowScrubbing
属性。allowScrubbing
属性将允许用户通过触摸小组件来滑动进度。通过启用这个,用户可以跳到视频的不同时间戳。此外,你还可以单独控制寻求栏的背景颜色、缓冲区颜色和播放区颜色。
VideoProgressIndicator( _videoPlayerController, allowScrubbing: true, colors: VideoProgressColors( backgroundColor: Colors.red, bufferedColor: Colors.black, playedColor: Colors.blueAccent), )
应用视频的字幕
字幕对你的应用程序来说需要两样东西。第一个是不同时期的段落/单词列表,第二个是在视频播放时显示这些的方法。为此,应该有一种方法来为时间变化添加一个监听器。
视频播放器包含一个addListener
方法,每秒钟执行一次。你可以使用这个监听器,根据不同的时间段为视频播放器提供字幕。
首先,让我们创建一个Map
,其中包含时间作为一个键,字幕文本作为一个值。在Map
,时间的单位将是秒。
Map<int,String> captions = { 5:"First subtitle", 20:"Second subtitle" };
接下来,在初始化视频播放器时注册一个Listener
。在回调里面,你可以检查视频是否正在播放,如果视频正在播放,则获得当前的时间为秒。然后,如果当前值包含在captions
地图中,我们可以像下面这样将该值设置为选定的。
void initState() { super.initState(); _videoPlayerController = VideoPlayerController.asset('assets/video/video.mp4') ..addListener(() { if(_videoPlayerController.value.isPlaying){ setState(() { if(captions.containsKey(_videoPlayerController.value.position.inSeconds)){ selectedCaption = captions[_videoPlayerController.value.position.inSeconds]; } }); } }) ..initialize().then((_) { setState(() {}); _videoPlayerController.play(); }); }
现在你可以使用ClosedCaption
来设置那个选定的。你可以给文本添加一些样式,以获得更好的可见性。
ClosedCaption( text: selectedCaption,textStyle: TextStyle(fontSize: 15,color: Colors.white),)
但是,每次改变时,建立主部件并不是好的做法。因此,我们应该把逻辑提取到一个单独的小部件。
要注册一个监听器,你应该把视频控制器传递给一个新创建的子部件。
从那里,你可以在子部件内注册监听器。
class VCaption extends StatefulWidget { const VCaption( this.videoPlayerController, ); final VideoPlayerController videoPlayerController; @override _VCaptionState createState() => _VCaptionState();}class _VCaptionState extends State<VCaption> { String? selectedCaption = ""; Map<int,String> captions = { 5:"First subtitle", 20:"Second subtitle" }; @override void initState() { widget.videoPlayerController.addListener(() { if(widget.videoPlayerController.value.isPlaying){ print("Time ${widget.videoPlayerController.value.position.inSeconds}"); setState(() { if(captions.containsKey(widget.videoPlayerController.value.position.inSeconds)){ selectedCaption = captions[widget.videoPlayerController.value.position.inSeconds]; } }); } }); super.initState(); } @override Widget build(BuildContext context) { return ClosedCaption( text: selectedCaption,textStyle: TextStyle(fontSize: 15,color: Colors.white),); }}
现在我们可以在之前创建的栏目内添加这个小部件,并将_videoPlayerController
作为参数传递。你可以在把小部件添加到树上之前检查视频播放器是否已经被初始化,就像下面这样。
_videoPlayerController.value.isInitialized ? VCaption(_videoPlayerController) : Container(),
你可以使用Stack
widget在视频顶部显示这些字幕,而不是在视频下面显示那些字幕。字幕以及进度指示器已经被移到了Stack
widget里面,以便在视频的顶部显示。
Stack( children: [ _videoPlayerController.value.isInitialized ? AspectRatio( aspectRatio: _videoPlayerController.value.aspectRatio, child: VideoPlayer(_videoPlayerController)) : Container(), Positioned( bottom: 2, width: MediaQuery.of(context).size.width, child: _videoPlayerController.value.isInitialized ? VCaption(_videoPlayerController) : Container(), ), Positioned( bottom: 0, width: MediaQuery.of(context).size.width, child: VideoProgressIndicator( _videoPlayerController, allowScrubbing: false, colors: VideoProgressColors( backgroundColor: Colors.blueGrey, bufferedColor: Colors.blueGrey, playedColor: Colors.blueAccent), )) ], )
感谢各位的阅读,以上就是“Flutter中视频播放器插件如何使用”的内容了,经过本文的学习后,相信大家对Flutter中视频播放器插件如何使用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!