Flutter视频缩略图滑动插件video_thumbnail_slider的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter视频缩略图滑动插件video_thumbnail_slider的使用

video_thumbnail_slider 是一个用于Flutter的插件,它提供了一个可定制的视频缩略图滑动组件。这个组件允许你通过生成的视频缩略图来显示一个滑动条,方便用户导航和预览视频的不同部分。

Features

  • 显示带有自定义设置的视频缩略图滑动条。
  • 支持为滑动条中的每个帧自定义构建器。
  • 通过与滑动条交互,可以跳转到视频的不同部分。

Preview

Getting Started

步骤1: 添加依赖

在你的 pubspec.yaml 文件中添加以下依赖:

dependencies:
  video_thumbnail_slider: ^1.0.0

步骤2: 导入包

在你的 Dart 代码中导入该包:

import 'package:video_thumbnail_slider/video_thumbnail_slider.dart';

步骤3: 创建视频控制器

创建一个 VideoPlayerController 实例来控制视频播放:

VideoPlayerController _controller = VideoPlayerController.network('http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4');

步骤4: 使用 VideoThumbnailSlider 组件

在你的 Flutter UI 中使用 VideoThumbnailSlider 组件:

VideoThumbnailSlider(
  controller: _controller,
  height: 50,
  width: 350,
  splitImage: 7,
  backgroundColor: Colors.black,
  customCurrentFrameBuilder: (controller) => VideoPlayer(controller),
)

Usage

下面是一个基本的例子,展示如何使用 VideoThumbnailSlider 组件:

import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:video_thumbnail_slider/video_thumbnail_slider.dart';

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

class MyApp extends StatelessWidget {
  final VideoPlayerController _controller = VideoPlayerController.network('https://example.com/sample_video.mp4');

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Video Thumbnail Slider Example'),
        ),
        body: Center(
          child: VideoThumbnailSlider(
            controller: _controller,
            height: 50,
            width: 350,
            splitImage: 7,
            backgroundColor: Colors.black,
            customCurrentFrameBuilder: (controller) => VideoPlayer(controller),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            if (_controller.value.isPlaying) {
              _controller.pause();
            } else {
              _controller.play();
            }
          },
          child: Icon(
            _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
          ),
        ),
      ),
    );
  }
}

示例代码

以下是更详细的示例代码,展示了如何在应用中集成和使用 video_thumbnail_slider 插件:

import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:video_thumbnail_slider/video_thumbnail_slider.dart';

class SeltectThumbnailPage extends StatefulWidget {
  const SeltectThumbnailPage({required this.media, Key? key}) : super(key: key);
  final File media;

  @override
  State<SeltectThumbnailPage> createState() => _SeltectThumbnailPageState();
}

class _SeltectThumbnailPageState extends State<SeltectThumbnailPage> {
  late VideoPlayerController videoController = VideoPlayerController.file(widget.media);

  Future<bool?> initVideoController() async {
    await videoController.initialize();
    return true;
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: [CupertinoButton(child: const Text('Save'), onPressed: () {})],
      ),
      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16),
        child: Column(
          children: [
            SizedBox(
              child: FutureBuilder(
                  future: initVideoController(),
                  builder: (context, snapshot) {
                    if (snapshot.data != null) {
                      return FittedVideoPlayer(
                        controller: videoController,
                        height: 400,
                      );
                    }
                    return const SizedBox();
                  }),
            ),
            const SizedBox(height: 16),
            VideoThumbnailSlider(
              controller: videoController,
              splitImage: 11,
              width: MediaQuery.of(context).size.width - 32,
              backgroundColor: const Color(0xff474545),
              frameBuilder: (imgData) => Container(
                decoration: BoxDecoration(
                    border: Border.all(color: Colors.black.withOpacity(0.1), width: 0.5)),
                child: Image.memory(imgData, fit: BoxFit.cover),
              ),
              customCurrentFrameBuilder: (videoController) => Container(
                decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(4),
                    border: Border.all(color: const Color(0xFFFF5858), width: 4)),
                child: VideoPlayer(videoController),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class FittedVideoPlayer extends StatefulWidget {
  const FittedVideoPlayer({required this.controller, this.height = 300, Key? key})
      : super(key: key);
  final VideoPlayerController controller;
  final double height;

  @override
  State<FittedVideoPlayer> createState() => _FittedVideoPlayerState();
}

class _FittedVideoPlayerState extends State<FittedVideoPlayer> {
  late double width = MediaQuery.of(context).size.width;
  late double height = widget.height;

  @override
  void initState() {
    super.initState();
  }

  void getVideoRatio() {
    if (widget.controller.value.isInitialized) {
      updateWidthHeight();
    }
  }

  void updateWidthHeight() {
    final ratio = widget.controller.value.aspectRatio;
    if (height * ratio <= width) {
      width = height * ratio;
    } else {
      height = width / ratio;
    }
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    updateWidthHeight();
    return Center(
      child: SizedBox(
        width: width,
        height: height,
        child: VideoPlayerView(
          videoController: widget.controller,
        ),
      ),
    );
  }
}

class VideoPlayerView extends StatefulWidget {
  const VideoPlayerView({
    this.videoController,
    this.media,
    this.autoPlay = true,
    Key? key,
  }) : super(key: key);
  final VideoPlayerController? videoController;
  final File? media;
  final bool autoPlay;

  @override
  State<VideoPlayerView> createState() => _VideoPlayerViewState();
}

class _VideoPlayerViewState extends State<VideoPlayerView> {
  late final VideoPlayerController _videoController =
      widget.videoController ?? VideoPlayerController.file(widget.media!);

  @override
  void initState() {
    initVideoController();
    super.initState();
  }

  void initVideoController() async {
    if (!_videoController.value.isInitialized) {
      await _videoController.initialize();
    }
    setState(() {});
    if (widget.autoPlay) {
      _videoController.play();
    }
  }

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

  void onVideoTap() {
    if (_videoController.value.isPlaying) {
      _videoController.pause();
    } else {
      _videoController.play();
    }
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onVideoTap,
      child: VideoPlayer(_videoController),
    );
  }
}

Additional Information

欢迎在 GitHub 上贡献、报告问题或请求功能。我们欢迎您的反馈和贡献!


更多关于Flutter视频缩略图滑动插件video_thumbnail_slider的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter视频缩略图滑动插件video_thumbnail_slider的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用Flutter中的video_thumbnail_slider插件来实现视频缩略图滑动的示例代码。这个插件允许你生成视频帧的缩略图,并在滑动视图中展示它们。

首先,确保你的pubspec.yaml文件中已经添加了video_thumbnail_slider依赖:

dependencies:
  flutter:
    sdk: flutter
  video_thumbnail_slider: ^最新版本号  # 请替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

接下来,你可以创建一个Flutter页面来使用video_thumbnail_slider。以下是一个完整的示例代码:

import 'package:flutter/material.dart';
import 'package:video_thumbnail_slider/video_thumbnail_slider.dart';
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';

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

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

class VideoThumbnailSliderPage extends StatefulWidget {
  @override
  _VideoThumbnailSliderPageState createState() => _VideoThumbnailSliderPageState();
}

class _VideoThumbnailSliderPageState extends State<VideoThumbnailSliderPage> {
  VideoPlayerController _controller;
  ChewieController _chewieController;

  @override
  void initState() {
    super.initState();
    // 初始化视频控制器
    _controller = VideoPlayerController.network(
      'https://www.example.com/path/to/your/video.mp4', // 替换为你的视频URL
    )
      ..initialize().then((_) {
        // 当视频初始化完成后,设置Chewie控制器
        setState(() {
          _chewieController = ChewieController(
            videoPlayerController: _controller,
            aspectRatio: _controller.value.aspectRatio,
            autoPlay: false,
            looping: false,
          );
        });
      });
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Video Thumbnail Slider Demo'),
      ),
      body: _controller.value.isInitialized
          ? Column(
              children: [
                Expanded(
                  child: VideoThumbnailSlider(
                    videoPlayerController: _controller,
                    thumbnailHeight: 100,
                    thumbnailWidth: 150,
                    maxDuration: 30, // 设置生成缩略图的最大时长(秒)
                    maxThumbnailCount: 50, // 设置最大缩略图数量
                    onVideoTap: () {
                      // 点击缩略图时播放视频
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) => ChewiePage(
                            controller: _chewieController,
                          ),
                        ),
                      );
                    },
                  ),
                ),
              ],
            )
          : Center(child: CircularProgressIndicator()),
    );
  }
}

class ChewiePage extends StatelessWidget {
  final ChewieController controller;

  ChewiePage({required this.controller});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Chewie(
          controller: controller,
        ),
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. 使用VideoPlayerController来加载视频。
  2. 当视频初始化完成后,创建ChewieController以便播放视频。
  3. 使用VideoThumbnailSlider生成视频的缩略图,并设置缩略图的高度、宽度、最大时长和最大缩略图数量。
  4. 当用户点击缩略图时,使用Chewie播放器播放视频。

请确保你替换了示例中的视频URL为你自己的视频路径,并根据需要调整缩略图的高度、宽度和其他参数。

回到顶部