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处理视频缓存。

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

相关推荐
安步当歌2 分钟前
【WebRTC】视频编码链路中各个类的简单分析——VideoStreamEncoder
音视频·webrtc·视频编解码·video-codec
顾北川_野3 分钟前
Android CALL关于电话音频和紧急电话设置和获取
android·音视频
顶呱呱程序6 分钟前
2-143 基于matlab-GUI的脉冲响应不变法实现音频滤波功能
算法·matlab·音视频·matlab-gui·音频滤波·脉冲响应不变法
EasyCVR1 小时前
萤石设备视频接入平台EasyCVR多品牌摄像机视频平台海康ehome平台(ISUP)接入EasyCVR不在线如何排查?
运维·服务器·网络·人工智能·ffmpeg·音视频
runing_an_min1 小时前
ffmpeg 视频滤镜:屏蔽边框杂色- fillborders
ffmpeg·音视频·fillborders
problc3 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
想要打 Acm 的小周同学呀3 小时前
LRU缓存算法
java·算法·缓存
hlsd#3 小时前
go 集成go-redis 缓存操作
redis·缓存·golang
镰刀出海3 小时前
Recyclerview缓存原理
java·开发语言·缓存·recyclerview·android面试
奶糖趣多多5 小时前
Redis知识点
数据库·redis·缓存