Flutter自定义视频播放插件custom_video_player的使用

Flutter自定义视频播放插件custom_video_player的使用

本视频播放插件专为Flutter应用程序设计的自定义视频播放器。该插件封装了video_player插件,并添加了一些关键功能和设计,以帮助开发者轻松完成他们喜欢的视频播放器。

特性

  • 执行任何操作,包括播放、暂停、重播和菜单。
  • 可选菜单显示,包含两个主要功能:更改播放速度和静音/取消静音。
  • 平滑的滑块,可以自定义其UI。
  • 双击左侧以倒退,双击右侧以快进。倒退和快进的时长可以修改。
  • 可选择将视频播放器设置为全屏。
  • 可选择设置覆盖层显示的时间长度。

自定义视频播放器展示

如何使用此插件

确保在将控制器传递给插件之前初始化视频播放控制器,否则视频播放器将无法加载。

CustomVideoPlayer(
  playerController: playerController,
  skipDuration: 30000, // 您希望跳过的毫秒数
  rewindDuration: 30000, // 您希望倒退的毫秒数
  videoSourceType: VideoSourceType.network, // 视频源类型:assets, file, network
  durationEndDisplay: DurationEndDisplay.totalDuration, // 显示总时长还是剩余时长
  displayMenu: true, // 是否显示菜单
  thumbColor: Colors.red, // 滑块的拇指颜色
  activeTrackColor: Colors.pink, // 活动轨道的颜色
  inactiveTrackColor: Colors.green, // 非活动轨道的颜色
  overlayBackgroundColor: Colors.grey.withOpacity(0.5), // 覆盖层背景颜色
  pressablesBackgroundColor: Colors.teal, // 可按压图标的背景颜色(如播放、暂停、重播和菜单)
  overlayDisplayDuration: 3000, // 覆盖层显示的时间长度(毫秒)
)

示例代码

以下是一个完整的示例,展示了如何使用custom_video_player插件:

import 'dart:io';
import 'package:permission_handler/permission_handler.dart' as ph;
import 'package:device_info_plus/device_info_plus.dart';
import 'package:custom_video_player/CustomVideoPlayer.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:video_player/video_player.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom Video Player',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Custom Video Player Examples'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  String videoUrl = 'https://www.shutterstock.com/shutterstock/videos/1103928479/preview/stock-footage-one-hour-neon-digital-negative-countdown-timer-hour-digital-negative-countdown-neon-one-hour.webm';
  String videoLocation = 'assets/videos/video1.mov';

  late VideoPlayerController networkVideoController;
  late VideoPlayerController assetVideoController;

  String videoLink = '';
  Widget videoPlayerComponent = Container();
  VideoPlayerController fileVideoController = VideoPlayerController.file(File(''));
  ImagePicker _picker = ImagePicker();
  ValueNotifier<double> width = ValueNotifier(200);
  ValueNotifier<double> height = ValueNotifier(350);

  [@override](/user/override) void initState(){
    super.initState();
    networkVideoController = VideoPlayerController.networkUrl(Uri.parse(videoUrl));
    assetVideoController = VideoPlayerController.asset(videoLocation);
    initializeVideoController();
  }

  Future<void> initializeVideoController() async{
    setState(() async{
      await networkVideoController.initialize();
      await assetVideoController.initialize();
    });
  }

  Future<void> pickVideo() async {
    try {
      bool permissionIsGranted = false;
      ph.Permission? permission;
      if(Platform.isAndroid){
        final androidInfo = await DeviceInfoPlugin().androidInfo;
        if(androidInfo.version.sdkInt <= 32){
          permission = ph.Permission.storage;
        }else{
          permission = ph.Permission.videos;
        }
      }
      permissionIsGranted = await permission!.isGranted;
      if(!permissionIsGranted){
        await permission.request();
        permissionIsGranted = await permission.isGranted;
      }
      if(permissionIsGranted){
        if(videoLink.isEmpty){
          final XFile? pickedFile = await _picker.pickVideo(
            source: ImageSource.gallery,
          );
          if(pickedFile != null ){
            String videoLUri = pickedFile.path;
            VideoPlayerController getController = VideoPlayerController.file(File(videoLUri));
            await getController.initialize().then((value){
              setState(() {
                videoLink = videoLUri;
                videoPlayerComponent = CustomVideoPlayer(
                  playerController: getController,
                  skipDuration: 10000, 
                  rewindDuration: 10000, 
                  videoSourceType: VideoSourceType.file, 
                  durationEndDisplay: DurationEndDisplay.remainingDuration, 
                  displayMenu: false, 
                  thumbColor: Colors.red, 
                  activeTrackColor: Colors.black, 
                  inactiveTrackColor: Colors.grey, 
                  overlayBackgroundColor: Colors.transparent, 
                  pressablesBackgroundColor: Colors.amber,
                  overlayDisplayDuration: 5000
                );
                fileVideoController = getController;
              });
            });
          }
        }
      }
    } catch (e) {
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: ListView(
          children: [
            CustomVideoPlayer(
              playerController: networkVideoController,
              skipDuration: 30000, // 您希望跳过的毫秒数
              rewindDuration: 30000, // 您希望倒退的毫秒数
              videoSourceType: VideoSourceType.network, // 视频源类型:assets, file, network
              durationEndDisplay: DurationEndDisplay.totalDuration, // 显示总时长还是剩余时长
              displayMenu: true, // 是否显示菜单
              thumbColor: Colors.red, // 滑块的拇指颜色
              activeTrackColor: Colors.pink, // 活动轨道的颜色
              inactiveTrackColor: Colors.green, // 非活动轨道的颜色
              overlayBackgroundColor: Colors.grey.withOpacity(0.5), // 覆盖层背景颜色
              pressablesBackgroundColor: Colors.teal, // 可按压图标的背景颜色(如播放、暂停、重播和菜单)
              overlayDisplayDuration: 3000, // 覆盖层显示的时间长度(毫秒)
            ),
            const SizedBox(
              height: 50
            ),
            CustomVideoPlayer(
              skipDuration: 10000, // 您希望跳过的毫秒数
              rewindDuration: 10000, // 您希望倒退的毫秒数
              videoSourceType: VideoSourceType.asset, // 视频源类型:assets, file, network
              playerController: assetVideoController,
              durationEndDisplay: DurationEndDisplay.totalDuration, // 显示总时长还是剩余时长
              displayMenu: false, // 是否显示菜单
              thumbColor: Colors.grey, // 滑块的拇指颜色
              activeTrackColor: Colors.black, // 活动轨道的颜色
              inactiveTrackColor: Colors.cyan, // 非活动轨道的颜色
              overlayBackgroundColor: Colors.grey.withOpacity(0.5), // 覆盖层背景颜色
              pressablesBackgroundColor: Colors.transparent, // 可按压图标的背景颜色(如播放、暂停、重播和菜单)
              overlayDisplayDuration: 3000, // 覆盖层显示的时间长度(毫秒)
            ),
            videoLink.isEmpty ?
              ElevatedButton(
                onPressed: () => pickVideo(),
                child: Text('Pick Video')
              )
            :
              Stack(
                children: [
                  ValueListenableBuilder<double>(
                    valueListenable: width,
                    builder: (BuildContext context, double width, Widget? child){
                      return ValueListenableBuilder<double>(
                        valueListenable: height,
                        builder: (BuildContext context, double height, Widget? child){
                          return videoPlayerComponent;
                        }
                      );
                    }
                  ),
                  Positioned(
                    top: 5, right: 0.03 * getScreenWidth(),
                    child: Container(
                      width: 0.075 * getScreenWidth(),
                      height: 0.075 * getScreenWidth(),
                      decoration: BoxDecoration(
                        color: Colors.black,
                        shape: BoxShape.circle,
                      ),
                      child: GestureDetector(
                        onTap: (){
                          setState((){
                            videoLink = '';
                            videoPlayerComponent = Container();
                            width.value = 200;
                            height.value = 350;
                            fileVideoController.pause();
                            fileVideoController.dispose();
                          });
                        },
                        child: Icon(Icons.delete, size: 25, color: Colors.white)
                      )
                    )
                  ),
                ],
              )
          ],
        ),
      ),
    );
  }
}

更多关于Flutter自定义视频播放插件custom_video_player的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter自定义视频播放插件custom_video_player的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中集成和使用自定义视频播放插件 custom_video_player 的示例代码。请注意,这个示例假设 custom_video_player 插件已经存在且功能正常,但实际中,你可能需要替换为真实存在的插件或自己实现的插件,因为 custom_video_player 并不是Flutter官方或广泛认可的插件名称。

首先,确保你已经在 pubspec.yaml 文件中添加了该插件的依赖(这里假设插件名为 custom_video_player,实际上你需要替换为正确的插件名):

dependencies:
  flutter:
    sdk: flutter
  custom_video_player: ^x.y.z  # 替换为实际版本号

然后运行 flutter pub get 来获取依赖。

接下来,在你的 Flutter 项目中创建一个页面来使用这个自定义的视频播放插件。下面是一个简单的示例:

import 'package:flutter/material.dart';
import 'package:custom_video_player/custom_video_player.dart';  // 替换为实际导入路径

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom Video Player Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: VideoPlayerScreen(),
    );
  }
}

class VideoPlayerScreen extends StatefulWidget {
  @override
  _VideoPlayerScreenState createState() => _VideoPlayerScreenState();
}

class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
  CustomVideoPlayerController? _controller;

  @override
  void initState() {
    super.initState();
    // 初始化视频控制器,这里假设视频URL是一个有效的网络视频地址
    _controller = CustomVideoPlayerController.network(
      'https://www.example.com/path/to/your/video.mp4',
    )..initialize().then((_) {
      // 确保在UI更新之前视频已经加载完成
      setState(() {});
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Custom Video Player Demo'),
      ),
      body: Center(
        child: _controller?.value.isInitialized == true
            ? AspectRatio(
                aspectRatio: _controller!.value.aspectRatio,
                child: CustomVideoPlayer(_controller!),
              )
            : Container(
                child: CircularProgressIndicator(),
              ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _controller?.value.isPlaying
                ? _controller!.pause()
                : _controller!.play();
          });
        },
        child: Icon(
          _controller?.value.isPlaying == true
              ? Icons.pause
              : Icons.play_arrow,
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的 Flutter 应用,其中包含一个自定义的视频播放器。我们假设 CustomVideoPlayerControllerCustomVideoPlayercustom_video_player 插件提供的类,用于控制视频播放和显示视频内容。

  • CustomVideoPlayerController.network 用于从网络加载视频。
  • initialize() 方法用于初始化视频控制器。
  • isInitialized 属性用于检查视频是否已经加载完成。
  • aspectRatio 属性用于获取视频的宽高比,以确保视频播放器正确显示。
  • play()pause() 方法用于控制视频的播放和暂停。

请注意,这个示例代码是基于假设的 custom_video_player 插件的API。在实际使用中,你需要根据具体的插件文档来调整代码。如果 custom_video_player 实际上并不存在,你可能需要寻找一个现有的Flutter视频播放插件(如 chewievideo_player)或者自己实现一个自定义的视频播放插件。

回到顶部