Flutter跨平台视频播放库video_full_screen鸿蒙化使用指南
OpenHarmony视频播放插件video_full_screen是基于Flutter开发的定制化解决方案,整合了video_player和chewie核心功能。该插件支持本地/网络视频播放、全屏切换、播放控制等特性,并针对OpenHarmony平台进行了深度优化。使用前需配置Flutter环境(3.0+)和OpenHarmony API 9+,通过Git方式引入依赖后即可实现流畅的视频播放体验

一、插件介绍
video_full_screen是一个专为OpenHarmony平台适配的Flutter视频播放插件,基于video_player和chewie进行定制开发,提供了完整的视频播放功能和流畅的全屏体验。该插件支持本地视频播放、在线视频流播放、播放控制、进度条拖动、全屏切换等核心功能,并针对OpenHarmony平台进行了深度优化。
核心特性:
- 🎬 支持本地视频和网络视频播放
- 🎛️ 完整的播放控制(播放/暂停、进度拖动、音量调节)
- 📺 流畅的全屏切换体验
- 📱 自动适配屏幕方向(横屏/竖屏)
- 🎨 优雅的UI设计和交互体验
- 🔧 针对OpenHarmony平台深度优化
二、环境要求
- OpenHarmony:API 9 及以上版本
- Flutter:3.0.0 及以上版本
- 开发工具:DevEco Studio 3.0+ 或 VS Code + Flutter插件
三、插件引入与配置
由于video_full_screen是针对OpenHarmony平台的定制版本,需要通过Git方式引入依赖。请按照以下步骤进行配置:
1. 添加依赖配置
在项目的pubspec.yaml文件中,添加以下依赖配置:
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
chewie: 1.7.5
orientation: ^1.3.0
dependency_overrides:
video_player:
git:
url: "https://atomgit.com/openharmony-tpc/flutter_packages"
path: "packages/video_player/video_player"
2. 配置资源文件
如果需要播放本地视频,请在pubspec.yaml中添加资源文件配置:
flutter:
uses-material-design: true
assets:
- assets/video1.mp4
然后在项目根目录下创建assets文件夹,并将视频文件放入其中。
3. 安装依赖
执行以下命令安装依赖:
flutter pub get
四、API使用示例
1. 基本用法
以下是video_full_screen的基本使用示例:
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';
import 'package:flutter/services.dart';
class VideoPlayerScreen extends StatefulWidget {
const VideoPlayerScreen({super.key});
State<VideoPlayerScreen> createState() => _VideoPlayerScreenState();
}
class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
late VideoPlayerController _controller;
late ChewieController _chewieController;
void initState() {
super.initState();
// 初始化视频控制器
_controller = VideoPlayerController.asset("assets/video1.mp4");
// 初始化Chewie控制器
_chewieController = ChewieController(
videoPlayerController: _controller,
autoPlay: true,
looping: true,
deviceOrientationsAfterFullScreen: [
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown
],
);
// 初始化视频
_controller.initialize();
}
void dispose() {
super.dispose();
_controller.dispose();
_chewieController.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('视频播放器'),
),
body: Center(
child: Chewie(
controller: _chewieController,
),
),
);
}
}
2. 完整功能示例
以下是一个包含完整功能的视频播放器示例,包括自定义控制UI:
import 'dart:async';
import 'package:chewie/chewie.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:video_player/video_player.dart';
class MyVideoPlayer extends StatefulWidget {
const MyVideoPlayer({super.key});
State<MyVideoPlayer> createState() => _MyVideoPlayerState();
}
class _MyVideoPlayerState extends State<MyVideoPlayer> {
bool _videoInit = false;
VideoPlayerController? _controller;
Duration _position = const Duration(seconds: 0);
Timer? _timer;
bool _hidePlayControl = true;
double _playControlOpacity = 0;
bool get _isFullScreen =>
MediaQuery.of(context).orientation == Orientation.landscape;
ChewieController? _chewieController;
void initState() {
_loadVideo();
super.initState();
}
void dispose() {
if (_controller != null) {
_controller?.removeListener(_videoListener);
_controller?.dispose();
_chewieController?.dispose();
}
super.dispose();
}
void _loadVideo() {
if (_controller != null) {
_controller?.removeListener(_videoListener);
_controller?.dispose();
}
setState(() {
_hidePlayControl = true;
_videoInit = false;
_position = const Duration(seconds: 0);
});
// 加载本地视频
_controller = VideoPlayerController.asset("assets/video1.mp4");
// 加载网络视频示例
// _controller = VideoPlayerController.networkUrl(
// Uri.parse('https://example.com/video.mp4'),
// );
_controller?.initialize().then((_) {
setState(() {
_videoInit = true;
});
});
_controller?.addListener(_videoListener);
_chewieController = ChewieController(
videoPlayerController: _controller!,
autoPlay: true,
looping: true,
deviceOrientationsAfterFullScreen: [
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown
]);
}
void _videoListener() async {
Duration res = await _controller!.position ?? const Duration();
if (res >= _controller!.value.duration) {
_controller!.pause();
_controller!.seekTo(const Duration(seconds: 0));
}
setState(() {
_position = res;
});
}
void _togglePlayControl() {
setState(() {
if (_hidePlayControl) {
_hidePlayControl = false;
_playControlOpacity = 1;
_startPlayControlTimer();
} else {
if (_timer != null) _timer!.cancel();
_playControlOpacity = 0;
Future.delayed(const Duration(milliseconds: 300)).whenComplete(() {
_hidePlayControl = true;
});
}
});
}
void _startPlayControlTimer() {
if (_timer != null) _timer!.cancel();
_timer = Timer(const Duration(seconds: 3), () {
setState(() {
_playControlOpacity = 0;
Future.delayed(const Duration(milliseconds: 300)).whenComplete(() {
_hidePlayControl = true;
});
});
});
}
void _toggleFullScreen() {
setState(() async {
var currentOrientation = MediaQuery.of(context).orientation;
if (currentOrientation == Orientation.portrait) {
await SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight
]);
} else {
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown
]);
}
_startPlayControlTimer();
});
}
String durationToTime(Duration duration) {
String hours = duration.inHours.toString().padLeft(2, '0');
String minutes =
duration.inMinutes.remainder(60).toString().padLeft(2, '0');
String seconds =
duration.inSeconds.remainder(60).toString().padLeft(2, '0');
return "$hours:$minutes:$seconds";
}
Widget build(BuildContext context) {
return Container(
width: _isFullScreen
? MediaQuery.of(context).size.height
: MediaQuery.of(context).size.width,
height: _isFullScreen
? MediaQuery.of(context).size.width
: MediaQuery.of(context).size.width / 16 * 9,
color: Colors.black,
child: Stack(
children: <Widget>[
GestureDetector(
onTap: () {
_togglePlayControl();
},
child: _videoInit
? Center(
child: Chewie(
controller: _chewieController!,
),
)
: const Center(
child: SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(),
),
),
),
Positioned(
left: 0,
bottom: 0,
child: Offstage(
offstage: _hidePlayControl,
child: AnimatedOpacity(
opacity: _playControlOpacity,
duration: const Duration(milliseconds: 300),
child: Container(
width: _isFullScreen
? MediaQuery.of(context).size.height
: MediaQuery.of(context).size.width,
height: 40,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
Color.fromRGBO(0, 0, 0, .7),
Color.fromRGBO(0, 0, 0, .1)
],
),
),
child: _videoInit
? Row(
children: <Widget>[
IconButton(
padding: EdgeInsets.zero,
iconSize: 26,
icon: Icon(
_controller!.value.isPlaying
? Icons.pause
: Icons.play_arrow,
color: Colors.white,
),
onPressed: () {
setState(() {
_controller!.value.isPlaying
? _controller!.pause()
: _controller!.play();
_startPlayControlTimer();
});
},
),
Flexible(
child: VideoProgressIndicator(
_controller!,
allowScrubbing: true,
padding: const EdgeInsets.all(0),
colors: VideoProgressColors(
playedColor: Theme.of(context).primaryColor,
bufferedColor: const Color.fromRGBO(
255, 255, 255, .5),
backgroundColor: const Color.fromRGBO(
255, 255, 255, .2),
),
),
),
Container(
margin: const EdgeInsets.only(left: 10),
child: Text(
durationToTime(_position) +
'/' +
durationToTime(_controller!.value.duration),
style: const TextStyle(color: Colors.white),
),
),
IconButton(
padding: EdgeInsets.zero,
iconSize: 26,
icon: Icon(
_isFullScreen
? Icons.fullscreen_exit
: Icons.fullscreen,
color: Colors.white,
),
onPressed: () {
_toggleFullScreen();
},
),
],
)
: Container(),
),
),
),
),
],
),
);
}
}
3. 主页面集成
在主页面中集成视频播放器:
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';
import 'my_video_player.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'VideoPlayer Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'VideoPlayer Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
void initState() {
super.initState();
}
void dispose() {
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('视频播放示例'),
),
body: const MyVideoPlayer(),
);
}
}
四、API说明
1. VideoPlayerController
-
构造方法:
VideoPlayerController.asset(String assetPath)- 加载本地视频VideoPlayerController.networkUrl(Uri url)- 加载网络视频
-
常用方法:
initialize()- 初始化控制器play()- 播放视频pause()- 暂停视频seekTo(Duration position)- 跳转到指定位置setVolume(double volume)- 设置音量dispose()- 释放资源
2. ChewieController
- 构造参数:
videoPlayerController- 视频控制器autoPlay- 是否自动播放looping- 是否循环播放deviceOrientationsAfterFullScreen- 退出全屏后的屏幕方向aspectRatio- 视频宽高比showControls- 是否显示控制UIcustomControls- 自定义控制UI
五、常见问题与解决方案
1. 视频无法播放
问题:视频加载后无法播放,显示黑屏或报错。
解决方案:
- 检查视频文件路径是否正确
- 确保视频格式受支持(建议使用MP4格式)
- 检查网络连接(网络视频)
- 确认权限配置是否正确
2. 全屏切换异常
问题:全屏切换时方向不正确或布局混乱。
解决方案:
- 确保在
ChewieController中正确配置deviceOrientationsAfterFullScreen - 检查OpenHarmony项目的权限配置
- 更新Flutter和插件版本到最新
3. 性能问题
问题:视频播放卡顿或内存占用过高。
解决方案:
- 降低视频分辨率
- 优化视频编码格式
- 确保及时释放资源(调用
dispose()) - 关闭不必要的后台应用
六、总结
video_full_screen插件为Flutter开发者在OpenHarmony平台上提供了强大而易用的视频播放解决方案。通过本文的介绍,您可以轻松掌握该插件的使用方法,包括插件引入、配置、API调用和常见问题解决。
该插件不仅提供了完整的视频播放功能,还针对OpenHarmony平台进行了深度优化,确保在各种设备上都能提供流畅的播放体验。无论是开发教育类应用、娱乐类应用还是企业级应用,video_full_screen都是您的理想选择。
如果您在使用过程中遇到问题或有任何建议,欢迎加入开源鸿蒙跨平台社区与我们交流讨论!
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐



所有评论(0)