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

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

最近开发过程中video_player播放视频,

一、引入video_player

在pubspec.yaml引入video_player

dart 复制代码
  video_player: ^2.7.0

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

在Android上,video_player使用的是ExoPlayer。

二、使用前设置

2.1 在iOS中的设置

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

dart 复制代码
<key>NSAppTransportSecurity</key>
<dict>
	<key>NSAllowsArbitraryLoads</key>
	<true/>
</dict>

2.2 在Android中的设置

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

dart 复制代码
<uses-permission android:name="android.permission.INTERNET"/>

三、使用前设置video_player

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

VideoPlayerController的初始化

dart 复制代码
_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

dart 复制代码
Center(
          child: _controller.value.isInitialized
              ? AspectRatio(
                  aspectRatio: _controller.value.aspectRatio,
                  child: VideoPlayer(_controller),
                )
              : Container(),
        ),

控制播放与暂停

dart 复制代码
// 播放
_controller.play();
dart 复制代码
// 暂停
_controller.pause();

完整实例代码

dart 复制代码
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});

  @override
  _VideoAppState createState() => _VideoAppState();
}

class _VideoAppState extends State<VideoApp> {
  late VideoPlayerController _controller;

  @override
  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(() {});
      });
  }

  @override
  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,
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }
}

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

四 缓存flutter_cache_manager下载文件

使用flutter_cache_manager代码如下

dart 复制代码
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后的视频初始化代码如下

dart 复制代码
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处理视频缓存。

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

相关推荐
量子-Alex8 分钟前
【多模态聚类】用于无标记视频自监督学习的多模态聚类网络
学习·音视频·聚类
mo47764 小时前
Webrtc音频模块(四) 音频采集
音视频·webrtc
icy、泡芙4 小时前
T527-----音频调试
linux·驱动开发·音视频
易我数据恢复大师4 小时前
怎么提取音频保存到本地?电脑音频提取方法
音视频·软件·音频提取
野蛮的大西瓜4 小时前
开源呼叫中心中,如何将ASR与IVR菜单结合,实现动态的IVR交互
人工智能·机器人·自动化·音视频·信息与通信
海海不掉头发5 小时前
苍穹外卖-day05redis 缓存的学习
学习·缓存
川石教育6 小时前
Vue前端开发-缓存优化
前端·javascript·vue.js·缓存·前端框架·vue·数据缓存
嘟嘟实验室6 小时前
微信小程序xr-frame透明视频实现
微信小程序·ffmpeg·音视频·xr
DT辰白7 小时前
基于Redis的网关鉴权方案与性能优化
数据库·redis·缓存
红米饭配南瓜汤7 小时前
WebRTC服务质量(09)- Pacer机制(01) 流程概述
网络·音视频·webrtc