Flutter视频播放插件fplayer的使用
Flutter视频播放插件fplayer的使用
fplayer
是一个基于 fplayer-core
的 Flutter 媒体播放器插件,适用于 iOS 和 Android 平台。
您的支持是我们开发的动力。 欢迎 Star,欢迎 PR~。 反馈欢迎并 Pull Requests 最受欢迎!
文档
开发文档 包含首页、入门指南、基础、内核、fplayer 中的概念理解:
安装
在 pubspec.yaml
文件中添加 fplayer
作为依赖项:
dependencies:
fplayer: ^{{latest version}}
替换 {{latest version}}
为上面 badge 中显示的版本号。
如果需要使用未发布的 git 分支:
dependencies:
fplayer:
git:
url: https://github.com/FlutterPlayer/fplayer.git
ref: develop # 可以替换为分支或标签名称
示例
下面是一个完整的示例代码,展示了如何使用 fplayer
插件来播放视频:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:fplayer/fplayer.dart';
import 'package:screen_brightness/screen_brightness.dart';
import 'app_bar.dart';
class VideoScreen extends StatefulWidget {
final String url;
const VideoScreen({super.key, required this.url});
[@override](/user/override)
VideoScreenState createState() => VideoScreenState();
}
class VideoScreenState extends State<VideoScreen> {
final FPlayer player = FPlayer();
// 视频列表
List<VideoItem> videoList = [
VideoItem(
title: '第一集',
subTitle: '视频1副标题',
url: 'http://player.alicdn.com/video/aliyunmedia.mp4',
),
VideoItem(
title: '第二集',
subTitle: '视频2副标题',
url: 'https://www.runoob.com/try/demo_source/mov_bbb.mp4',
),
VideoItem(
title: '第三集',
subTitle: '视频3副标题',
url: 'http://player.alicdn.com/video/aliyunmedia.mp4',
),
];
// 倍速列表
Map<String, double> speedList = {
"2.0": 2.0,
"1.5": 1.5,
"1.0": 1.0,
"0.5": 0.5,
};
// 清晰度列表
Map<String, ResolutionItem> resolutionList = {
"480P": ResolutionItem(
value: 480,
url: 'https://www.runoob.com/try/demo_source/mov_bbb.mp4',
),
"270P": ResolutionItem(
value: 270,
url: 'http://player.alicdn.com/video/aliyunmedia.mp4',
),
};
// 视频索引, 单个视频可不传
int videoIndex = 0;
// 模拟播放记录视频初始化完需要跳转的进度
int seekTime = 100000;
VideoScreenState();
[@override](/user/override)
void initState() {
super.initState();
startPlay();
}
void startPlay() async {
// 视频播放相关配置
await player.setOption(FOption.hostCategory, "enable-snapshot", 1);
await player.setOption(FOption.hostCategory, "request-screen-on", 1);
await player.setOption(FOption.hostCategory, "request-audio-focus", 1);
await player.setOption(FOption.playerCategory, "reconnect", 20);
await player.setOption(FOption.playerCategory, "framedrop", 20);
await player.setOption(FOption.playerCategory, "enable-accurate-seek", 1);
await player.setOption(FOption.playerCategory, "mediacodec", 1);
await player.setOption(FOption.playerCategory, "packet-buffering", 0);
await player.setOption(FOption.playerCategory, "soundtouch", 1);
// 播放传入的视频
setVideoUrl(widget.url);
// 播放视频列表的第一个视频
// setVideoUrl(videoList[videoIndex].url);
}
Future<void> setVideoUrl(String url) async {
try {
await player.setDataSource(url, autoPlay: true, showCover: true);
} catch (error) {
print("播放-异常: $error");
return;
}
}
[@override](/user/override)
Widget build(BuildContext context) {
MediaQueryData mediaQueryData = MediaQuery.of(context);
Size size = mediaQueryData.size;
double videoHeight = size.width * 9 / 16;
return Scaffold(
appBar: const FAppBar.defaultSetting(title: "Video"),
body: Column(
children: [
FView(
player: player,
width: double.infinity,
height: videoHeight,
color: Colors.black,
fsFit: FFit.contain, // 全屏模式下的填充
fit: FFit.fill, // 正常模式下的填充
panelBuilder: fPanelBuilder(
// 单视频配置
title: '视频标题',
subTitle: '视频副标题',
// 右下方截屏按钮
isSnapShot: true,
// 右上方按钮组开关
isRightButton: true,
// 右上方按钮组
rightButtonList: [
InkWell(
onTap: () {},
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Theme.of(context).primaryColorLight,
borderRadius: const BorderRadius.vertical(
top: Radius.circular(5),
),
),
child: Icon(
Icons.favorite,
color: Theme.of(context).primaryColor,
),
),
),
InkWell(
onTap: () {},
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Theme.of(context).primaryColorLight,
borderRadius: const BorderRadius.vertical(
bottom: Radius.circular(5),
),
),
child: Icon(
Icons.thumb_up,
color: Theme.of(context).primaryColor,
),
),
)
],
// 字幕功能:待内核提供api
// caption: true,
// 视频列表开关
isVideos: true,
// 视频列表列表
videoList: videoList,
// 当前视频索引
videoIndex: videoIndex,
// 全屏模式下点击播放下一集视频按钮
playNextVideoFun: () {
setState(() {
videoIndex += 1;
});
},
settingFun: () {
print('设置按钮点击事件');
},
// 自定义倍速列表
speedList: speedList,
// 清晰度开关
isResolution: true,
// 自定义清晰度列表
resolutionList: resolutionList,
// 视频播放错误点击刷新回调
onError: () async {
await player.reset();
setVideoUrl(videoList[videoIndex].url);
},
// 视频播放完成回调
onVideoEnd: () async {
var index = videoIndex + 1;
if (index < videoList.length) {
await player.reset();
setState(() {
videoIndex = index;
});
setVideoUrl(videoList[index].url);
}
},
onVideoTimeChange: () {
// 视频时间变动则触发一次,可以保存视频播放历史
},
onVideoPrepared: () async {
// 视频初始化完毕,如有历史记录时间段则可以触发快进
try {
if (seekTime >= 1) {
/// seekTo必须在FState.prepared
print('seekTo');
await player.seekTo(seekTime);
// print("视频快进-$seekTime");
seekTime = 0;
}
} catch (error) {
print("视频初始化完快进-异常: $error");
}
},
),
),
// 自定义小屏列表
Container(
width: double.infinity,
height: 30,
margin: const EdgeInsets.all(20),
child: ListView.builder(
scrollDirection: Axis.horizontal,
padding: EdgeInsets.zero,
itemCount: videoList.length,
itemBuilder: (context, index) {
bool isCurrent = videoIndex == index;
Color textColor = Theme.of(context).primaryColor;
Color bgColor = Theme.of(context).primaryColorDark;
Color borderColor = Theme.of(context).primaryColor;
if (isCurrent) {
textColor = Theme.of(context).primaryColorDark;
bgColor = Theme.of(context).primaryColor;
borderColor = Theme.of(context).primaryColor;
}
return GestureDetector(
onTap: () async {
await player.reset();
setState(() {
videoIndex = index;
});
setVideoUrl(videoList[index].url);
},
child: Container(
margin: EdgeInsets.only(left: index == 0 ? 0 : 10),
padding: const EdgeInsets.symmetric(horizontal: 5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: bgColor,
border: Border.all(
width: 1.5,
color: borderColor,
),
),
alignment: Alignment.center,
child: Text(
videoList[index].title,
style: TextStyle(
fontSize: 15,
color: textColor,
),
),
),
);
},
),
),
],
),
);
}
[@override](/user/override)
void dispose() async {
super.dispose();
try {
await ScreenBrightness().resetScreenBrightness();
} catch (e) {
print(e);
throw 'Failed to reset brightness';
}
player.release();
}
}
更多关于Flutter视频播放插件fplayer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter视频播放插件fplayer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用fplayer
插件来播放视频的示例代码。fplayer
是一个流行的Flutter视频播放器插件,它提供了丰富的功能和自定义选项。
首先,你需要在你的pubspec.yaml
文件中添加fplayer
依赖:
dependencies:
flutter:
sdk: flutter
fplayer: ^latest_version_here # 请替换为实际的最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,你可以在你的Flutter应用中使用fplayer
来播放视频。以下是一个简单的示例:
import 'package:flutter/material.dart';
import 'package:fplayer/fplayer.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Video Player Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: VideoPlayerScreen(),
);
}
}
class VideoPlayerScreen extends StatefulWidget {
@override
_VideoPlayerScreenState createState() => _VideoPlayerScreenState();
}
class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
late FPlayerController _controller;
@override
void initState() {
super.initState();
// 初始化视频控制器
_controller = FPlayerController.network(
'https://www.example.com/your-video-file.mp4', // 替换为你的视频URL
)..initialize().then((_) {
// 可以在这里设置初始状态,比如自动播放等
setState(() {});
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Video Player Demo'),
),
body: Center(
child: _controller.value.isInitialized
? AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: FPlayer(controller: _controller),
)
: Container(
child: CircularProgressIndicator(),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
if (_controller.value.isPlaying) {
_controller.pause();
} else {
_controller.play();
}
});
},
tooltip: 'Play/Pause',
child: Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
),
);
}
}
在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个视频播放器。以下是代码的主要部分:
- 依赖导入:首先,我们导入了
fplayer
包。 - 视频控制器初始化:在
_VideoPlayerScreenState
的initState
方法中,我们创建了一个FPlayerController
对象,并通过调用initialize()
方法来初始化它。这里我们使用的是网络视频URL,但你也可以使用本地视频文件。 - 视频播放器构建:在
build
方法中,我们使用AspectRatio
和FPlayer
小部件来显示视频。如果视频尚未初始化,则显示一个加载指示器。 - 播放/暂停控制:我们添加了一个浮动操作按钮(FAB),用于控制视频的播放和暂停。
请注意,你需要将示例中的视频URL替换为你自己的视频文件的URL或路径。此外,确保你已经按照fplayer
插件的文档正确配置了项目(例如,在iOS和Android项目中添加必要的权限和配置)。
这个示例代码提供了一个基本的框架,你可以根据需要进行扩展和自定义,比如添加全屏支持、音量控制、进度条等。