您现已看到很多包括视频内容的运用程序,比如带有视频教程的食谱运用程序、电影运用程序和体育相关的运用程序。您是否想知道怎么将视频内容增加到您的下一个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),
))
],
)
定论
运用视频播映器插件而不是从头开端完成一个视频播映器,能够节约大量的开发时刻,并供给一切开箱即用的功用。
假如您想逾越这些定制,完成一个具有Material-和Cupertino灵感的漂亮的视频播映器,您能够挑选chewie Flutter插件。
The postHandling videos in Flutter using a video player pluginappeared first onLogRocket Blog.