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/class="lazy" data-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 cache Future<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处理视频缓存。
学习记录,每天不停进步。
来源地址:https://blog.csdn.net/gloryFlow/article/details/132124837
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341