Flutter HLS视频播放插件custom_hls_video的使用

发布于 1周前 作者 htzhanglong 来自 Flutter

Flutter HLS视频播放插件custom_hls_video的使用

Custom HLS视频播放插件是Lecle YoYo视频播放器的改进版,专为Flutter设计,支持HLS(.m3u8)视频流。它基于yoyo_player包,并封装了video_player,为开发者提供了创建自定义UI和功能的基础架构。

该插件已更新了更多可定制属性并修复了来自旧版本的报告问题。

Pub Version (包括预发布版本)

特性

  • 可以选择多个质量并打开
  • 视频点击可以播放/暂停、静音/取消静音或执行其他操作
  • 控制器自动隐藏
  • 支持(.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

项目

  1. 添加依赖项,在项目的pubspec.yaml文件中添加以下代码:
dependencies:
  custom_hls_video: #最新版本
  1. 安装依赖项(如果已自动安装则忽略)
cd 项目目录
flutter pub get
  1. 在页面中引入库
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

1 回复

更多关于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,
        ),
      ),
    );
  }
}

解释

  1. 依赖管理:在pubspec.yaml中添加custom_hls_video依赖。
  2. 主应用MyApp是应用的主入口,它包含一个MaterialApp,并设置VideoPlayerScreen作为主页。
  3. 视频播放器页面VideoPlayerScreen是一个有状态的Widget,它包含一个CustomHlsVideoController来管理视频播放。
  4. 初始化控制器:在initState中初始化CustomHlsVideoController,并设置视频流的URL、自动播放选项和宽高比。
  5. 视频播放器:使用CustomHlsVideoPlayer小部件来显示视频。如果视频未初始化完成,则显示一个加载指示器。
  6. 播放控制:添加一个浮动操作按钮(FAB)来控制视频的播放和暂停。

请确保将https://your-hls-stream-url/playlist.m3u8替换为你实际的HLS视频流URL。这个示例代码展示了如何使用custom_hls_video插件在Flutter应用中播放HLS视频流,并提供了一个简单的播放/暂停控制。

回到顶部