Flutter视频缩略图滑动插件video_thumbnail_slider的使用
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
更多关于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,
),
),
);
}
}
在这个示例中,我们做了以下几件事:
- 使用
VideoPlayerController
来加载视频。 - 当视频初始化完成后,创建
ChewieController
以便播放视频。 - 使用
VideoThumbnailSlider
生成视频的缩略图,并设置缩略图的高度、宽度、最大时长和最大缩略图数量。 - 当用户点击缩略图时,使用
Chewie
播放器播放视频。
请确保你替换了示例中的视频URL为你自己的视频路径,并根据需要调整缩略图的高度、宽度和其他参数。