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();

完整实例代码

扫描二维码关注公众号,回复: 16989979 查看本文章
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处理视频缓存。

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

猜你喜欢

转载自blog.csdn.net/gloryFlow/article/details/132124837