在 Flutter 里官方提供了一個(gè) video_player
插件可以播放視頻柠掂。
先安裝依賴:
dependencies:
video_player: ^0.6.4
基本使用
class _VideoAppState extends State<VideoApp> {
VideoPlayerController _controller;
bool _isPlaying = false;
String url = 'http://vd3.bdstatic.com/mda-ifvq' +
'u9yp3eaqueep/mda-ifvqu9yp3eaqueep.mp4';
@override
void initState() {
super.initState();
_controller = VideoPlayerController.network(this.url)
// 播放狀態(tài)
..addListener(() {
final bool isPlaying = _controller.value.isPlaying;
if (isPlaying != _isPlaying) {
setState(() { _isPlaying = isPlaying; });
}
})
// 在初始化完成后必須更新界面
..initialize().then((_) {
setState(() {});
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Video Demo',
home: new Scaffold(
body: new Center(
child: _controller.value.initialized
// 加載成功
? new AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
) : new Container(),
),
floatingActionButton: new FloatingActionButton(
onPressed: _controller.value.isPlaying
? _controller.pause
: _controller.play,
child: new Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
),
),
);
}
}
下面是在模擬器下看到的效果(略卡)。
video_player 的 controller 有以下方法可用:
- initialize() - 初始化播放器忍捡。
- dispose() - 釋放播放器資源。
- notifyListeners() - 監(jiān)聽(tīng)播放消息澎粟。
- addListener(listener) - 添加監(jiān)聽(tīng)器奇昙。
- removeListener(listener) - 移除監(jiān)聽(tīng)器。
- pause() - 暫停播放群叶。
- play() - 開(kāi)始播放漠嵌。
- position - 播放位置。
- seekTo(moment) - 指定到某個(gè)位置播放盖呼。
- setLooping(looping) - 是否循環(huán)播放儒鹿。
- setVolume(volume) - 設(shè)置音量大小。
使用 chewie
chewie
几晤,是一個(gè)非官方的第三方視頻播放組件约炎,看起來(lái)好像是基于 HTML5 播放的組件。chewie 相對(duì) video_player 來(lái)說(shuō)蟹瘾,有控制欄和全屏的功能圾浅。Chewie 使用 video_player 引擎并將其包裹在友好的 Material 或 Cupertino UI 中!
安裝依賴:
dependencies
chewie: ^0.6.1
基本使用:
import 'package:chewie/chewie.dart';
new Center(
child: new Chewie(
new VideoPlayerController.network(this.url),
aspectRatio: 16 / 9,
autoPlay: !true,
looping: true,
showControls: true,
// 占位圖
placeholder: new Container(
color: Colors.grey,
),
// 是否在 UI 構(gòu)建的時(shí)候就加載視頻
autoInitialize: !true,
// 拖動(dòng)條樣式顏色
materialProgressColors: new ChewieProgressColors(
playedColor: Colors.red,
handleColor: Colors.blue,
backgroundColor: Colors.grey,
bufferedColor: Colors.lightGreen,
),
),
),
chewie
實(shí)際上就是為 video_player
做了一個(gè) UI 上的封裝憾朴,因?yàn)?UI 實(shí)在長(zhǎng)得太像狸捕。
控制欄樣式?
chewie
并不能自定義控制欄樣式众雷,那只能自己修改源碼了(修改的版本是 v0.6.1)灸拍。
首先打開(kāi)文件:chewie/lib/src/material_controls.dart
做祝,在里面定義兩個(gè)變量。
const lightColor = Color.fromRGBO(255, 255, 255, 0.85);
const darkColor = Color.fromRGBO(1, 1, 1, 0.35);
接著添加顏色值鸡岗。
// 在 _buildExpandButton 下混槐,大約 127 行
child: new Icon(
widget.fullScreen ? Icons.fullscreen_exit : Icons.fullscreen,
color: lightColor,
),
// 在 _buildHitArea 下,大約 157 行
decoration: new BoxDecoration(
color: Colors.black54,
borderRadius: new BorderRadius.circular(48.0),
),
// 167 行
child: new Icon(
Icons.play_arrow,
size: 32.0,
color: lightColor,
),
// 在 _buildMuteButton 下轩性,大約 206 行
child: new Icon(
color: lightColor,
),
// 在 _buildPlayPause 下声登,大約 228 行
child: new Icon(
controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
color: lightColor,
),
// 在 _buildPosition 下,大約 244 行
style: new TextStyle(
fontSize: 14.0,
color: lightColor,
),
// 在 _buildProgressBar 下揣苏,尾行
new ChewieProgressColors(
playedColor: lightColor,
handleColor: lightColor,
bufferedColor: Colors.white30,
backgroundColor: darkColor,
),
此外 chewie 在全屏?xí)r沒(méi)有一個(gè)退出全屏的返回按鈕和標(biāo)題顯示悯嗓,接著改。
// 在 build 里加一個(gè) _buildHeader()卸察,這個(gè) header 需要自己定義绅作。
@override
Widget build(BuildContext context) {
return new Column(
children: <Widget>[
// 在全屏?xí)r才顯示
widget.fullScreen ? _buildHeader(context, _title) : new Container(),
_buildHitArea(),
_buildBottomBar(context, widget.controller),
],
);
}
AnimatedOpacity _buildHeader(BuildContext context, String title) {
return new AnimatedOpacity(
opacity: _hideStuff ? 0.0 : 1.0,
duration: new Duration(milliseconds: 300),
child: new Container(
color: darkColor,
height: barHeight,
child: new Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new IconButton(
onPressed: _onExpandCollapse,
color: lightColor,
icon: new Icon(Icons.chevron_left),
),
new Text(
'$title',
style: new TextStyle(
color: lightColor,
fontSize: 18.0,
),
),
],
),
),
);
}
標(biāo)題是從上下文獲取的,因此要一級(jí)一級(jí)的傳遞下去蛾派。
// chewie/lib/src/chewie_player.dart 文件
// 標(biāo)題
final String title;
// 在構(gòu)造函數(shù)處
this.title = '',
// 在 92 行左右俄认,PlayerWithControls 構(gòu)造的時(shí)候(有兩個(gè)位置,兩個(gè)都要加)
title: widget.title,
// chewie/lib/src/player_with_controls.dart 文件
// 標(biāo)題
final String title;
// 在構(gòu)造函數(shù)處
this.title = '',
// 在 92 行左右洪乍,MaterialControls 構(gòu)造的時(shí)候
title: widget.title,
// chewie/lib/src/material_controls.dart
final String title;
@required this.title,