Flutter HLS视频播放插件custom_hls_video的使用
Flutter HLS视频播放插件custom_hls_video的使用
Custom HLS视频播放插件是Lecle YoYo视频播放器的改进版,专为Flutter设计,支持HLS(.m3u8)视频流。它基于yoyo_player
包,并封装了video_player
,为开发者提供了创建自定义UI和功能的基础架构。
该插件已更新了更多可定制属性并修复了来自旧版本的报告问题。
特性
- 可以选择多个质量并打开
- 视频点击可以播放/暂停、静音/取消静音或执行其他操作
- 控制器自动隐藏
- 支持(.m3u8) HLS视频流
安装与设置
Android
在<项目根目录>/android/app/src/main/AndroidManifest.xml
文件中添加以下权限:
<uses-permission android:name="android.permission.INTERNET"/>
iOS
如果需要通过http
(而不是https
)URL访问视频,则必须在应用程序的<项目根目录>/ios/Runner/Info.plist
文件中添加适当的NSAppTransportSecurity
权限。
在Xcode中,将项目的部署目标更改为11
。
项目
- 添加依赖项,在项目的
pubspec.yaml
文件中添加以下代码:
dependencies:
custom_hls_video: #最新版本
- 安装依赖项(如果已自动安装则忽略)
cd 项目目录
flutter pub get
- 在页面中引入库
import 'package:custom_hls_video/lecle_yoyo_player.dart';
使用
一个简单的使用示例:
YoYoPlayer(
aspectRatio: 16 / 9,
url: "视频URL",
videoStyle: VideoStyle(),
videoLoadingStyle: VideoLoadingStyle(),
),
更改图标
videoStyle: VideoStyle(
playIcon: Icon(Icons.play_arrow),
pauseIcon: Icon(Icons.pause),
fullscreenIcon: Icon(Icons.fullscreen),
forwardIcon: Icon(Icons.skip_next),
backwardIcon: Icon(Icons.skip_previous),
)
更改视频加载样式
videoLoadingStyle: VideoLoadingStyle(
loading: Center(
child: Text("正在加载视频..."),
),
)
播放带字幕的视频
body: YoYoPlayer(
aspectRatio: 16 / 9,
url: "https://sfux-ext.sfux.info/hls/chapter/105/1588724110/1588724110.m3u8",
videoStyle: VideoStyle(
qualityStyle: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w500,
color: Colors.white,
),
forwardAndBackwardBtSize: 30.0,
playButtonIconSize: 40.0,
playIcon: Icon(
Icons.add_circle_outline_outlined,
size: 40.0,
color: Colors.white,
),
pauseIcon: Icon(
Icons.remove_circle_outline_outlined,
size: 40.0,
color: Colors.white,
),
videoQualityPadding: EdgeInsets.all(5.0),
),
videoLoadingStyle: VideoLoadingStyle(
loading: Center(
child: Text("正在加载视频"),
),
),
allowCacheFile: true,
onCacheFileCompleted: (files) {
print('缓存文件长度 ::: ${files?.length}');
if (files != null && files.isNotEmpty) {
for (var file in files) {
print('文件路径 ::: ${file.path}');
}
}
},
onCacheFileFailed: (error) {
print('缓存文件错误 ::: $error');
},
onFullScreen: (value) {
setState(() {
if (fullscreen != value) {
fullscreen = value;
}
});
}
),
直播视频
videoStyle: VideoStyle(
showLiveDirectButton: true,
)
播放器选项
播放器
属性名称 | 类型 | 描述 |
---|---|---|
url | String | 视频源 (.m3u8 & 文件) |
videoStyle | VideoStyle | 视频播放器样式 |
videoLoadingStyle | VideoLoadingStyle | 视频加载样式 |
aspectRatio | double | 视频宽高比 [宽高比 : 16 / 9] |
onFullScreen | VideoCallback | 视频全屏状态 |
onPlayingVideo | VideoCallback | 视频类型 (如:mkv, mp4, hls) |
onPlayButtonTap | VideoCallback | 视频播放状态 |
onFastForward | VideoCallback<VideoPlayerValue?> | 视频快进后的新值 |
onRewind | VideoCallback<VideoPlayerValue?> | 视频倒退后的新值 |
onShowMenu | VideoCallback<bool, bool> | 视频控制按钮状态和视频质量选择器状态 |
onVideoInitCompleted | VideoCallback | 视频初始化完成后暴露视频控制器 |
headers | Map<String, String> | 视频URL请求的附加头信息 |
autoPlayVideoAfterInit | bool | 允许视频在初始化后自动播放 |
displayFullScreenAfterInit | bool | 允许视频在初始化后全屏显示 |
onCacheFileCompleted | VideoCallback<List> | 缓存文件列表 |
onCacheFileFailed | VideoCallback | 缓存文件错误 |
allowCacheFile | bool | 允许缓存文件到设备存储 |
closedCaptionFile | VideoCallback<ClosedCaptionFile?> | 字幕文件 |
videoPlayerOptions | VideoPlayerOptions | 提供额外的配置选项 |
onLiveDirectTap | VideoCallback<VideoPlayerValue?> | 直播视频当前值 |
播放器自定义样式 (VideoStyle)
属性名称 | 类型 | 描述 |
---|---|---|
playIcon | Widget | 自定义播放按钮图标 |
pauseIcon | Widget | 自定义暂停按钮图标 |
fullscreenIcon | Widget | 自定义全屏按钮图标 |
forwardIcon | Widget | 自定义快进按钮图标 |
backwardIcon | Widget | 自定义倒退按钮图标 |
qualityStyle | TextStyle | 当前视频质量文本样式 |
qualityOptionStyle | TextStyle | 视频质量选项样式 |
videoSeekStyle | TextStyle | 视频当前位置文本样式 |
videoDurationStyle | TextStyle | 视频时长文本样式 |
allowScrubbing | bool | 检测触摸输入并相应地尝试定位视频 |
progressIndicatorColors | VideoProgressColors | 指示器使用的默认颜色 |
progressIndicatorPadding | EdgeInsetsGeometry | 进度指示器周围的视觉填充 |
playButtonIconColor | Color | 播放按钮图标的自定义颜色 |
playButtonIconSize | double | 播放按钮图标的自定义大小 |
spaceBetweenBottomBarButtons | double | 播放、快进和倒退按钮之间的间距 |
actionBarBgColor | Color | 操作栏的自定义背景色 |
actionBarPadding | EdgeInsetsGeometry | 操作栏的自定义填充 |
qualityOptionsBgColor | Color | 质量选项弹出框的自定义背景色 |
qualityOptionsMargin | EdgeInsetsGeometry | 质量选项弹出框的自定义边距 |
qualityOptionsPadding | EdgeInsetsGeometry | 质量选项弹出框内视频质量选项文本的自定义填充 |
qualityOptionsRadius | BorderRadius | 质量选项弹出框的自定义圆角 |
qualityButtonAndFullScrIcoSpace | double | 全屏按钮和视频质量按钮之间的间距 |
forwardAndBackwardBtSize | double | 快进和倒退按钮的自定义大小 |
forwardIconColor | Color | 快进按钮的自定义颜色 |
backwardIconColor | Color | 倒退按钮的自定义颜色 |
bottomBarPadding | EdgeInsetsGeometry | 底部栏周围的填充 |
videoQualityBgColor | Color | 选定视频质量控件的自定义背景色 |
videoQualityRadius | BorderRadiusGeometry | 选定视频质量控件的自定义圆角 |
videoQualityPadding | EdgeInsetsGeometry | 选定视频质量文本周围的填充 |
qualityOptionWidth | double | 视频选项弹出框内每个项目的宽度 |
fullScreenIconSize | double | 全屏按钮图标的大小 |
fullScreenIconColor | Color | 全屏按钮的自定义颜色 |
showLiveDirectButton | bool | 启用或禁用直播直接按钮(用于直播视频) |
liveDirectButtonText | String | 直播直接按钮的自定义文本 |
liveDirectButtonTextStyle | TextStyle | 直播直接按钮文本的自定义样式 |
liveDirectButtonColor | Color | 直播直接按钮圆圈的自定义颜色 |
liveDirectButtonDisableColor | Color | 直播直接按钮圆圈的自定义禁用颜色 |
liveDirectButtonSize | double | 直播直接按钮圆圈的自定义大小 |
enableSystemOrientationsOverride | bool | 启用或禁用系统的方向覆盖 |
orientation | List | 应用程序界面可以显示的一组方向 |
播放器加载自定义样式 (VideoLoadingStyle)
属性名称 | 类型 | 描述 |
---|---|---|
loading | Widget | 自定义加载小部件以替换默认加载小部件 |
loadingBackgroundColor | Color | 加载小部件的自定义背景色 |
loadingIndicatorValueColor | Color | 加载指示器的自定义颜色 |
loadingText | String | 加载小部件的自定义加载文本 |
loadingTextStyle | TextStyle | 加载文本的自定义样式 |
loadingIndicatorBgColor | Color | 进度指示器的背景色 |
loadingIndicatorColor | Color | 进度指示器的颜色 |
loadingIndicatorWidth | double | 绘制圆圈所用线的宽度 |
indicatorSemanticsLabel | String | 进度指示器的 SemanticsProperties.label |
indicatorSemanticsValue | String | 进度指示器的 SemanticsProperties.value |
indicatorInitValue | double | 进度指示器的初始值 |
spaceBetweenIndicatorAndText | double | 加载文本和加载指示器之间的间距 |
showLoadingText | bool | 允许加载小部件显示加载文本 |
如何创建?
- 源URL(m3u8)中的数据通过正则表达式检查,并根据各自的规则创建并保存子m3u8文件。
- 一旦视频开始播放,就开始创建子m3u8文件。
- 每次视频完成或主URL发生变化时,都会检查并删除子m3u8文件。
子m3u8文件的创建方式如下:
- 如果视频质量为
yoyo_[文件名]_[视频质量].m3u8
- 如果视频质量和音频质量为
yoyo_[视频质量]_[音频质量].m3u8
支持M3U8
#EXT-X-MEDIA
#EXT-X-STREAM-INF
(不适用于iOS)
播放器截图
示例代码
import 'package:flutter/material.dart';
import 'package:lecle_yoyo_player/lecle_yoyo_player.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool fullscreen = false;
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Material App',
home: Scaffold(
appBar: fullscreen == false
? AppBar(
backgroundColor: Colors.blue,
title: const Image(
image: AssetImage('image/yoyo_logo.png'),
fit: BoxFit.fitHeight,
height: 50,
),
centerTitle: true,
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context);
},
),
)
: null,
body: Padding(
padding:
fullscreen ? EdgeInsets.zero : const EdgeInsets.only(top: 32.0),
child: YoYoPlayer(
aspectRatio: 16 / 9,
url:
"https://sfux-ext.sfux.info/hls/chapter/105/1588724110/1588724110.m3u8",
allowCacheFile: true,
onCacheFileCompleted: (files) {
print('缓存文件长度 ::: ${files?.length}');
if (files != null && files.isNotEmpty) {
for (var file in files) {
print('文件路径 ::: ${file.path}');
}
}
},
onCacheFileFailed: (error) {
print('缓存文件错误 ::: $error');
},
videoStyle: const VideoStyle(
qualityStyle: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.w500,
color: Colors.white,
),
forwardAndBackwardBtSize: 30.0,
playButtonIconSize: 40.0,
playIcon: Icon(
Icons.add_circle_outline_outlined,
size: 40.0,
color: Colors.white,
),
pauseIcon: Icon(
Icons.remove_circle_outline_outlined,
size: 40.0,
color: Colors.white,
),
videoQualityPadding: EdgeInsets.all(5.0),
// showLiveDirectButton: true,
// enableSystemOrientationsOverride: false,
),
videoLoadingStyle: const VideoLoadingStyle(
loading: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image(
image: AssetImage('image/yoyo_logo.png'),
fit: BoxFit.fitHeight,
height: 50,
),
SizedBox(height: 16.0),
Text("正在加载视频..."),
],
),
),
),
onFullScreen: (value) {
setState(() {
if (fullscreen != value) {
fullscreen = value;
}
});
},
),
),
),
);
}
}
更多关于Flutter HLS视频播放插件custom_hls_video的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter HLS视频播放插件custom_hls_video的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用custom_hls_video
插件来播放HLS视频流的示例代码。这个插件允许你直接在Flutter应用中嵌入和播放HLS视频流。
首先,确保你已经在pubspec.yaml
文件中添加了custom_hls_video
依赖:
dependencies:
flutter:
sdk: flutter
custom_hls_video: ^最新版本号 # 请替换为实际最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,你可以在你的Flutter项目中创建一个页面来播放HLS视频。以下是一个完整的示例:
import 'package:flutter/material.dart';
import 'package:custom_hls_video/custom_hls_video.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter HLS Video Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: VideoPlayerScreen(),
);
}
}
class VideoPlayerScreen extends StatefulWidget {
@override
_VideoPlayerScreenState createState() => _VideoPlayerScreenState();
}
class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
CustomHlsVideoController? _controller;
@override
void initState() {
super.initState();
// 初始化视频控制器
_controller = CustomHlsVideoController(
dataSource: 'https://your-hls-stream-url/playlist.m3u8', // 替换为你的HLS视频流URL
autoPlay: true,
aspectRatio: 16 / 9,
)..initialize().then((_) {
// 初始化完成后可以执行一些操作,比如设置监听器等
setState(() {});
});
}
@override
void dispose() {
_controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('HLS Video Player'),
),
body: Center(
child: _controller?.value.isInitialized == true
? CustomHlsVideoPlayer(_controller!)
: CircularProgressIndicator(),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// 根据需要添加控制,比如播放/暂停
if (_controller!.value.isPlaying) {
_controller!.pause();
} else {
_controller!.play();
}
},
tooltip: 'Play/Pause',
child: Icon(
_controller!.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
),
);
}
}
解释
- 依赖管理:在
pubspec.yaml
中添加custom_hls_video
依赖。 - 主应用:
MyApp
是应用的主入口,它包含一个MaterialApp
,并设置VideoPlayerScreen
作为主页。 - 视频播放器页面:
VideoPlayerScreen
是一个有状态的Widget,它包含一个CustomHlsVideoController
来管理视频播放。 - 初始化控制器:在
initState
中初始化CustomHlsVideoController
,并设置视频流的URL、自动播放选项和宽高比。 - 视频播放器:使用
CustomHlsVideoPlayer
小部件来显示视频。如果视频未初始化完成,则显示一个加载指示器。 - 播放控制:添加一个浮动操作按钮(FAB)来控制视频的播放和暂停。
请确保将https://your-hls-stream-url/playlist.m3u8
替换为你实际的HLS视频流URL。这个示例代码展示了如何使用custom_hls_video
插件在Flutter应用中播放HLS视频流,并提供了一个简单的播放/暂停控制。