1. video_player 视频播放
插件地址:https://pub.dev/packages/video_player
- 添加插件
- 导入头文件
import 'package:video_player/video_player.dart';
- Android配置(iOS不用配置)
修改这个文件:
/android/app/src/main/AndroidManifest.xml
;
添加下面的配置:
<uses-permission android:name="android.permission.INTERNET"/>
- 添加核心代码
初始化播放器:
Uri url = Uri.parse("https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4");
_videoPlayerController = VideoPlayerController.networkUrl(url);
_videoPlayerController.initialize().then((_){
print("播放器初始化完成");
// 添加播放器的监听
_videoPlayerController.addListener(_onVideoChange);
// 设置自动播放
_videoPlayerController.play();
_isPlaying = true;
setState(() {
print("111111");
});
});
添加播放器的视图:
return VideoPlayer(_videoPlayerController);
退出页面时,需要销毁播放器:
void dispose() {
_videoPlayerController.dispose();
super.dispose();
}
- 完整代码
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class VideoPlayerDemo extends StatefulWidget {
const VideoPlayerDemo({super.key});
State<VideoPlayerDemo> createState() => _VideoPlayerDemoState();
}
class _VideoPlayerDemoState extends State<VideoPlayerDemo> {
late VideoPlayerController _videoPlayerController;
bool _isPlaying = false;
double _progress = 0.0;
// 添加播放状态的订阅,避免每次调用setState 重刷页面
late StreamController _isPlayingController;
// 添加播放进度的订阅,避免每次调用setState 重刷页面
late StreamController _progressController;
void initState() {
super.initState();
_isPlayingController = StreamController.broadcast();
_progressController = StreamController.broadcast();
Uri url = Uri.parse("https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4");
_videoPlayerController = VideoPlayerController.networkUrl(url);
_videoPlayerController.initialize().then((_){
print("播放器初始化完成");
// 添加播放器的监听
_videoPlayerController.addListener(_onVideoChange);
// 设置自动播放
_videoPlayerController.play();
_isPlaying = true;
setState(() {
});
});
}
void dispose() {
_videoPlayerController.dispose();
_isPlayingController.close();
_progressController.close();
super.dispose();
}
// 自定义播放器的监听回调的方法
void _onVideoChange() {
print("播放器的监听回调");
if (_videoPlayerController.value.isInitialized) {
final isPlaying = _videoPlayerController.value.isPlaying;
if (isPlaying != _isPlaying) {
_isPlaying = isPlaying;
_isPlayingController.sink.add(_isPlaying);
}
// 更新播放进度
final position = _videoPlayerController.value.position;
final duration = _videoPlayerController.value.duration;
if (duration != null) {
_progress = position.inMilliseconds / duration.inMilliseconds;
print("进度 = $_progress");
_progressController.sink.add(_progress);
}
// 检查视频是否播放完毕
if (position >= duration) {
print('Video has completed playing.');
_videoPlayerController.seekTo(Duration.zero); // 重置到开始位置
_videoPlayerController.pause(); // 暂停播放
_isPlaying = false;
_isPlayingController.add(_isPlaying);
}
}
}
// 播放器的视图
Widget _palyerViewWidget() {
if (_videoPlayerController.value.isInitialized) {
// 初始化成功
return AspectRatio(
aspectRatio: _videoPlayerController.value.aspectRatio,
child: Stack(
children: [
// 播放器
VideoPlayer(_videoPlayerController),
// 添加进度条
Align(
alignment: Alignment.bottomCenter,
child: _progressWidget(),
)
],
)
);
} else {
// loading视图
return CircularProgressIndicator();
}
}
// 进度条
Widget _progressWidget() {
// 进度条变化比较频繁:用 StreamBuilder 减少内存的消耗
return StreamBuilder(
stream: _progressController.stream,
builder: (context, snapshot) {
print("更新进度条");
return SizedBox(
height: 35,
child: Slider(
value: _progress,
onChanged: (value) {
print("onChanged");
setState(() {
_videoPlayerController.seekTo(
Duration(
milliseconds: (value * _videoPlayerController.value.duration.inMilliseconds).round()
)
);
});
},
),
);
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Video_Player_demo"),
),
body: Center(
child: _palyerViewWidget(),
),
floatingActionButton: FloatingActionButton(
onPressed: (){
if (_isPlaying) {
// 正在播放
_videoPlayerController.pause();
_isPlaying = false;
} else {
_videoPlayerController.play();
_isPlaying = true;
}
_isPlayingController.add(_isPlaying);
},
// 这个按钮变化比较频繁:用 StreamBuilder 减少内存的消耗
child: StreamBuilder(
stream: _isPlayingController.stream,
builder: (context, snapshot) {
return Icon(
_isPlaying ? Icons.pause : Icons.play_arrow
);
}),
),
);
}
}
- 效果图如下:
2. chewie 播放视频
在 Flutter 里官方提供了一个
video_player插件
可以播放视频,但video_player
有一些局限性:没法控制底部播放进度等。
所以可以用另外一个三方的视频播放库chewie
。
chewie
是一个非官方的第三方视频播放组件,看起来好像是基于 HTML5 播放的组件。
chewie 相对 video_player 来说,有控制栏和全屏的功能
。
Chewie
使用video_player
引擎并将其包裹在友好的 Material 或 Cupertino UI中!
插件地址:https://pub.dev/packages/chewie
- 引入插件
chewie基于video_player,所以要使用chewie必须配置video_player
- 导入头文件
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';
- Android配置(iOS不用配置)
修改这个文件:
/android/app/src/main/AndroidManifest.xml
;
添加下面的配置:
<uses-permission android:name="android.permission.INTERNET"/>
- 核心代码
import 'package:chewie/chewie.dart';
import 'package:video_player/video_player.dart';
final videoPlayerController = VideoPlayerController.networkUrl(Uri.parse(
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4'));
await videoPlayerController.initialize();
final chewieController = ChewieController(
videoPlayerController: videoPlayerController,
autoPlay: true,
looping: true,
);
final playerWidget = Chewie(
controller: chewieController,
);
退出页面时,需要销毁播放器:
void dispose() {
_videoPlayerController.dispose();
_chewieController.dispose();
super.dispose();
}
- 完整代码
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';
class ChewieDemo extends StatefulWidget {
const ChewieDemo({super.key});
State<ChewieDemo> createState() => _ChewieDemoState();
}
class _ChewieDemoState extends State<ChewieDemo> {
late VideoPlayerController _videoPlayerController;
late ChewieController _chewieController;
void initState() {
super.initState();
// 初始化播放器
_initVideo();
}
void dispose() {
_videoPlayerController.dispose();
_chewieController.dispose();
super.dispose();
}
// 初始化播放器
void _initVideo() async {
Uri url = Uri.parse(
"https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4"
);
_videoPlayerController = VideoPlayerController.networkUrl(url);
await _videoPlayerController.initialize();
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController,
aspectRatio: _videoPlayerController.value.aspectRatio,
autoPlay: true,
looping: false
);
setState(() {});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Chewie demo-在线播放视频"),
),
body: Center(
child: _videoPlayerController.value.isInitialized ? AspectRatio(
aspectRatio: _videoPlayerController.value.aspectRatio,
child: Chewie(controller: _chewieController),
) : CircularProgressIndicator(),
),
);
}
}
- 效果图: