flutter开发实战-video_player视频播放功能及视频缓存

flutter开发实战-video_player视频播放功能及视频缓存

最近开发过程中video_player播放视频,
在这里插入图片描述
在这里插入图片描述

一、引入video_player

在pubspec.yaml引入video_player

  video_player: ^2.7.0

在iOS上,video_player使用的是AVPlayer进行播放。
在Android上,video_player使用的是ExoPlayer。

二、使用前设置

2.1 在iOS中的设置

在iOS工程中info.plist添加一下设置,以便支持Https,HTTP的视频地址

<key>NSAppTransportSecurity</key>
<dict><key>NSAllowsArbitraryLoads</key><true/>
</dict>

2.2 在Android中的设置

需要在/android/app/src/main/AndroidManifest.xml文件中添加网络权限

<uses-permission android:name="android.permission.INTERNET"/>

三、使用前设置video_player

video_player 使用VideoPlayerController来控制播放与暂停

VideoPlayerController的初始化

_controller = VideoPlayerController.networkUrl(Uri.parse('https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4'))..initialize().then((_) {// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.setState(() {});});

显示视频Widget

Center(child: _controller.value.isInitialized? AspectRatio(aspectRatio: _controller.value.aspectRatio,child: VideoPlayer(_controller),): Container(),),

控制播放与暂停

// 播放
_controller.play();
// 暂停
_controller.pause();

完整实例代码

import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';void main() => runApp(const VideoApp());/// Stateful widget to fetch and then display video content.
class VideoApp extends StatefulWidget {const VideoApp({super.key});_VideoAppState createState() => _VideoAppState();
}class _VideoAppState extends State<VideoApp> {late VideoPlayerController _controller;void initState() {super.initState();_controller = VideoPlayerController.networkUrl(Uri.parse('https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4'))..initialize().then((_) {// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.setState(() {});});}Widget build(BuildContext context) {return MaterialApp(title: 'Video Demo',home: Scaffold(body: Center(child: _controller.value.isInitialized? AspectRatio(aspectRatio: _controller.value.aspectRatio,child: VideoPlayer(_controller),): Container(),),floatingActionButton: FloatingActionButton(onPressed: () {setState(() {_controller.value.isPlaying? _controller.pause(): _controller.play();});},child: Icon(_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,),),),);}void dispose() {super.dispose();_controller.dispose();}
}

注意:video_player暂时不支持缓存,如果需要可以使用flutter_cache_manager

四 缓存flutter_cache_manager下载文件

使用flutter_cache_manager代码如下

import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'dart:async';
import 'dart:typed_data';
import 'package:file/file.dart';
import 'package:flutter_suprisebox/utils/string_utils.dart';class CustomCacheManager {static const key = 'customCacheKey';static CacheManager instance = CacheManager(Config(key,stalePeriod: const Duration(days: 7),maxNrOfCacheObjects: 20,repo: JsonCacheInfoRepository(databaseName: key),fileService: HttpFileService(),),);Future<File> getSingleFile(String url, {String? key,Map<String, String>? headers,}) async {return await instance.getSingleFile(url, key: key, headers: headers);}Future<FileInfo?> getFileFromCache(String url,{bool ignoreMemCache = false}) async {String? key = StringUtils.toMD5(url);if (key != null && key.isNotEmpty) {return await instance.getFileFromCache(key, ignoreMemCache: ignoreMemCache);}return null;}Future<FileInfo> downloadFile(String url,{String? key,Map<String, String>? authHeaders,bool force = false}) async {return await instance.downloadFile(url, key: key, authHeaders: authHeaders, force: force);}Stream<FileResponse> getFileStream(String url,{String? key, Map<String, String>? headers, bool withProgress = false}) {return instance.getFileStream(url,key: key, headers: headers, withProgress: withProgress);}Future<void> removeFile(String key) async {return instance.removeFile(key);}/// Removes all files from the cacheFuture<void> emptyCache() {return instance.emptyCache();}
}

添加flutter_cache_manager后,flutter_cache_manager会先判断文件是否存在,如果不存在则下载视频文件。

使用CustomCacheManager后的视频初始化代码如下

Future<void> stuVideoPlay() async {_controller?.dispose();if (Platform.isIOS) {_controller = VideoPlayerController.network(widget.videoUrl);} else {FileInfo? fileInfo =await CustomCacheManager().getFileFromCache(widget.videoUrl);if (fileInfo == null) {fileInfo = await CustomCacheManager().downloadFile(widget.videoUrl);// if (fileInfo != null) {_controller = VideoPlayerController.file(fileInfo.file);// } else {//   _controller = VideoPlayerController.network(widget.videoUrl);// }} else {var file = await CustomCacheManager().getSingleFile(widget.videoUrl);_controller = VideoPlayerController.file(file);}}await _controller?.initialize().then((_) {// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.setState(() {});});await _controller!.setLooping(true);if (widget.autoPlay) {await _controller?.play();} else {await _controller?.pause();}}

特别注意:我使用的时候,flutter_cache_manager好像暂时不支持iOS。这点可能还需要其他方案来做缓存处理。如果支持了请留言哦,也可能我记错了。

四、小结

flutter开发实战-video_player视频播放功能及视频缓存。video_player播放视频,flutter_cache_manager处理视频缓存。

学习记录,每天不停进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/29058.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python-docx常用方法总结

由于最近有任务需要自动生成word报告&#xff0c;因此学习了一些python-docx的使用方法&#xff0c;在此总结。 目前网上相关的资料不算太多&#xff0c;且大多数都很简单。有一些稍微复杂的需求往往找不到答案&#xff0c;很多想要的方法这个库似乎并没有直接提供。在git上看…

Dockerfile定制Tomcat镜像

Dockerfile中的打包命令 FROM &#xff1a; 以某个基础镜像作为此镜像的基础 RUN &#xff1a; RUN后面跟着linux常用命令&#xff0c;如RUN echo xxx >> xxx,注意&#xff0c;RUN 不能用于执行命令&#xff0c;因为每个RUN都是独立运行的&#xff0c;RUN 的cd对镜像中的…

PHP8的循环控制语句-PHP8知识详解

我们在上一节讲的是条件控制语句&#xff0c;本节课程我们讲解循环控制语句。循环控制语句中&#xff0c;主要有for循环、while循环、do...while循环和foreach循环。 在编写代码时&#xff0c;经常需要反复运行同一代码块。我们可以使用循环来执行这样的任务&#xff0c;而不是…

利用MMPose进行姿态估计(训练、测试全流程)

前言 MMPose是一款基于PyTorch的姿态分析开源工具箱&#xff0c;是OpenMMLab项目成员之一&#xff0c;主要特性&#xff1a; 支持多种人体姿态分析相关任务&#xff1a;2D多人姿态估计、2D手部姿态估计、动物关键点检测等等更高的精度和更快的速度&#xff1a;包括“自顶向下”…

力扣初级算法(二分查找)

力扣初级算法(二分法)&#xff1a; 每日一算法&#xff1a;二分法查找 学习内容&#xff1a; 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 2.二分查找流程&…

Mageia 9 RC1 正式发布,Mandriva Linux 发行版的社区分支

导读Mageia 9 首个 RC 已发布。公告写道&#xff0c;自 2023 年 5 月发布 beta 2 以来&#xff0c;Mageia 团队一直致力于解决许多顽固问题并提供安全修复和新特性。 新版本的控制中心添加了用于删除旧内核的新功能&#xff0c;该功能在 Mageia 9 中默认自动启用&#xff0c;用…

探秘手机隐藏的望远镜功能:开启后,观察任何你想看的地方

当今的智能手机不仅仅是通信工具&#xff0c;它们蕴藏着各种隐藏的功能&#xff0c;其中之一就是让你拥有望远镜般的观察能力。是的&#xff0c;你没有听错&#xff01;今天我们将探秘手机中隐藏的望远镜功能&#xff0c;这项神奇的功能可以让你打开后&#xff0c;轻松观察任何…

Spring Boot读取yml或者properties配置信息

文章目录 Spring Boot读取yml或者properties配置信息方法一&#xff1a;Value获取基本信息&#xff0c;适用于少量信息方法二&#xff1a;通过注解ConfigurationProperties(prefix "spring.datasource")方法三&#xff1a;通过api Environment Spring Boot读取yml或…

小兔鲜项目 uniapp (1)

目录 项目架构 uni-app小兔鲜儿电商项目架构 小兔鲜儿电商课程安排 创建uni-app项目 1.通过HBuilderX创建 2.通过命令行创建 pages.json和tabBar案例 uni-app和原生小程序开发区别 用VS Code开发uni-app项目 拉取小兔鲜儿项目模板代码 基础架构–引入uni-ui组件库 操…

SSM个人博客项目

文章目录 SSM个人博客系统实现项目介绍 一、准备工作0. 创建项目添加对应依赖1. 数据库设计2. 定时实体类 二、功能实现1.统一功能处理统一返回格式统一异常处理定义登录拦截器 2. 注册登录实现生成获取验证码密码加盐实现注册功能登录功能注销功能 3.登录用户博客列表获取登录…

机器学习笔记之优化算法(十)梯度下降法铺垫:总体介绍

机器学习笔记之优化算法——梯度下降法铺垫&#xff1a;总体介绍 引言回顾&#xff1a;线搜索方法线搜索方法的方向 P k \mathcal P_k Pk​线搜索方法的步长 α k \alpha_k αk​ 梯度下降方法整体介绍 引言 从本节开始&#xff0c;将介绍梯度下降法 ( Gradient Descent,GD ) …

SpringCloud Gateway获取请求响应body大小

前提 本文获取请求、响应body大小方法的前提 : 网关只做转发逻辑&#xff0c;不修改请求、相应的body内容。 SpringCloud Gateway内部的机制类似下图&#xff0c;HttpServer&#xff08;也就是NettyServer&#xff09;接收外部的请求&#xff0c;在Gateway内部请求将会通过Htt…

RISC-V基础之函数调用(四)非叶函数调用(包含实例)

叶函数是指不调用其他函数&#xff0c;也不改变任何非易失性寄存器的函数2。叶函数通常是一些简单的操作&#xff0c;如数学运算或逻辑判断。叶函数的特点是可以通过模拟返回来展开&#xff0c;即不需要保存或恢复寄存器的状态。 非叶函数是指调用其他函数或改变非易失性寄存器…

电力巡检无人机助力迎峰度夏,保障夏季电力供应

夏季是电力需求量较高的时期&#xff0c;随着高温天气的来临&#xff0c;风扇、空调和冰箱等电器的使用量也大大增加&#xff0c;从而迎来夏季用电高峰期&#xff0c;电网用电负荷不断攀升。为了保障夏季电网供电稳定&#xff0c;供电公司会加强对电力设施设备的巡检&#xff0…

opencv基础-34 图像平滑处理-2D 卷积 cv2.filter2D()

2D卷积是一种图像处理和计算机视觉中常用的操作&#xff0c;用于在图像上应用滤波器或卷积核&#xff0c;从而对图像进行特征提取、平滑处理或边缘检测等操作。 在2D卷积中&#xff0c;图像和卷积核都是二维的矩阵或数组。卷积操作将卷积核在图像上滑动&#xff0c;对每个局部区…

瑞数系列及顶像二次验证LOGS

瑞数商标局药监局专利局及顶像二次验证 日期&#xff1a;20230808 瑞数信息安全是一个专注于信息安全领域的公司&#xff0c;致力于为企业和个人提供全面的信息安全解决方案。他们的主要业务包括网络安全、数据安全、应用安全、云安全等方面的服务和产品。瑞数信息安全拥有一支…

现在转行搞嵌入式找工作难不难啊?

对于应届生来说&#xff0c;嵌入式开发的经验不会有太多&#xff0c;所以要求也不会太高。 嵌入式开发常用的是C语言&#xff0c;所以需要你有扎实的功底&#xff0c;这一点很重要&#xff0c;数据结构算法&#xff0c;指针&#xff0c;函数&#xff0c;网络编程 有了上面的基…

web题型

0X01 命令执行 漏洞原理 没有对用户输入的内容进行一定过滤直接传给shell_exec、system一类函数执行 看一个具体例子 cmd1|cmd2:无论cmd1是否执行成功&#xff0c;cmd2将被执行 cmd1;cmd2:无论cmd1是否执行成功&#xff0c;cmd2将被执行 cmd1&cmd2:无论cmd1是否执行成…

源码分析——ConcurrentHashMap源码+底层数据结构分析

文章目录 1. ConcurrentHashMap 1.71. 存储结构2. 初始化3. put4. 扩容 rehash5. get 2. ConcurrentHashMap 1.81. 存储结构2. 初始化 initTable3. put4. get 3. 总结 1. ConcurrentHashMap 1.7 1. 存储结构 Java 7 中 ConcurrentHashMap 的存储结构如上图&#xff0c;Concurr…

winform控件 datagridview分页功能

主要实现页面跳转、动态改变每页显示行数、返回首末页、上下页功能&#xff0c;效果图如下&#xff1a; 主代码如下&#xff1a; namespace Paging {public partial class Form1 : Form{public Form1(){InitializeComponent();}private int currentPageCount;//记录当前页行数…