1. video_player 視頻播放
插件地址:https://pub.dev/packages/video_player
- 添加插件
- 導入頭文件
import 'package:video_player/video_player.dart';
- Android配置(iOS不用配置)
修改這個文件:
/android/app/src/main/AndroidManifest.xml
;
添加下面的配置:
<uses-permission android:name="android.permission.INTERNET"/>
- 添加核心代碼
初始化播放器:
Uri url = Uri.parse("https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4");_videoPlayerController = VideoPlayerController.networkUrl(url);_videoPlayerController.initialize().then((_){print("播放器初始化完成");// 添加播放器的監聽_videoPlayerController.addListener(_onVideoChange);// 設置自動播放_videoPlayerController.play();_isPlaying = true;setState(() {print("111111");});});
添加播放器的視圖:
return VideoPlayer(_videoPlayerController);
退出頁面時,需要銷毀播放器:
void dispose() {_videoPlayerController.dispose();super.dispose();}
- 完整代碼
import 'dart:async';import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';class VideoPlayerDemo extends StatefulWidget {const VideoPlayerDemo({super.key});State<VideoPlayerDemo> createState() => _VideoPlayerDemoState();
}class _VideoPlayerDemoState extends State<VideoPlayerDemo> {late VideoPlayerController _videoPlayerController;bool _isPlaying = false;double _progress = 0.0;// 添加播放狀態的訂閱,避免每次調用setState 重刷頁面late StreamController _isPlayingController;// 添加播放進度的訂閱,避免每次調用setState 重刷頁面late StreamController _progressController;void initState() {super.initState();_isPlayingController = StreamController.broadcast();_progressController = StreamController.broadcast();Uri url = Uri.parse("https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4");_videoPlayerController = VideoPlayerController.networkUrl(url);_videoPlayerController.initialize().then((_){print("播放器初始化完成");// 添加播放器的監聽_videoPlayerController.addListener(_onVideoChange);// 設置自動播放_videoPlayerController.play();_isPlaying = true;setState(() {});});}void dispose() {_videoPlayerController.dispose();_isPlayingController.close();_progressController.close();super.dispose();}// 自定義播放器的監聽回調的方法void _onVideoChange() {print("播放器的監聽回調");if (_videoPlayerController.value.isInitialized) {final isPlaying = _videoPlayerController.value.isPlaying;if (isPlaying != _isPlaying) {_isPlaying = isPlaying;_isPlayingController.sink.add(_isPlaying);}// 更新播放進度final position = _videoPlayerController.value.position;final duration = _videoPlayerController.value.duration;if (duration != null) {_progress = position.inMilliseconds / duration.inMilliseconds;print("進度 = $_progress");_progressController.sink.add(_progress);}// 檢查視頻是否播放完畢if (position >= duration) {print('Video has completed playing.');_videoPlayerController.seekTo(Duration.zero); // 重置到開始位置_videoPlayerController.pause(); // 暫停播放_isPlaying = false;_isPlayingController.add(_isPlaying);}}}// 播放器的視圖Widget _palyerViewWidget() {if (_videoPlayerController.value.isInitialized) {// 初始化成功return AspectRatio(aspectRatio: _videoPlayerController.value.aspectRatio,child: Stack(children: [// 播放器VideoPlayer(_videoPlayerController),// 添加進度條Align(alignment: Alignment.bottomCenter,child: _progressWidget(),)],));} else {// loading視圖return CircularProgressIndicator();}}// 進度條Widget _progressWidget() {// 進度條變化比較頻繁:用 StreamBuilder 減少內存的消耗return StreamBuilder(stream: _progressController.stream, builder: (context, snapshot) {print("更新進度條");return SizedBox(height: 35,child: Slider(value: _progress,onChanged: (value) {print("onChanged");setState(() {_videoPlayerController.seekTo(Duration(milliseconds: (value * _videoPlayerController.value.duration.inMilliseconds).round()));});},),);});}Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("Video_Player_demo"),),body: Center(child: _palyerViewWidget(),),floatingActionButton: FloatingActionButton(onPressed: (){if (_isPlaying) {// 正在播放_videoPlayerController.pause();_isPlaying = false;} else {_videoPlayerController.play();_isPlaying = true;}_isPlayingController.add(_isPlaying);},// 這個按鈕變化比較頻繁:用 StreamBuilder 減少內存的消耗child: StreamBuilder(stream: _isPlayingController.stream, builder: (context, snapshot) {return Icon(_isPlaying ? Icons.pause : Icons.play_arrow);}),),);}
}
- 效果圖如下:
2. chewie 播放視頻
在 Flutter 里官方提供了一個
video_player插件
可以播放視頻,但video_player
有一些局限性:沒法控制底部播放進度等。
所以可以用另外一個三方的視頻播放庫chewie
。
chewie
是一個非官方的第三方視頻播放組件,看起來好像是基于 HTML5 播放的組件。
chewie 相對 video_player 來說,有控制欄和全屏的功能
。
Chewie
使用video_player
引擎并將其包裹在友好的 Material 或 Cupertino UI中!
插件地址:https://pub.dev/packages/chewie
- 引入插件
chewie基于video_player,所以要使用chewie必須配置video_player
- 導入頭文件
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';
- Android配置(iOS不用配置)
修改這個文件:
/android/app/src/main/AndroidManifest.xml
;
添加下面的配置:
<uses-permission android:name="android.permission.INTERNET"/>
- 核心代碼
import 'package:chewie/chewie.dart';
import 'package:video_player/video_player.dart';final videoPlayerController = VideoPlayerController.networkUrl(Uri.parse('https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4'));await videoPlayerController.initialize();final chewieController = ChewieController(videoPlayerController: videoPlayerController,autoPlay: true,looping: true,
);final playerWidget = Chewie(controller: chewieController,
);
退出頁面時,需要銷毀播放器:
void dispose() {_videoPlayerController.dispose();_chewieController.dispose();super.dispose();}
- 完整代碼
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';class ChewieDemo extends StatefulWidget {const ChewieDemo({super.key});State<ChewieDemo> createState() => _ChewieDemoState();
}class _ChewieDemoState extends State<ChewieDemo> {late VideoPlayerController _videoPlayerController;late ChewieController _chewieController;void initState() {super.initState();// 初始化播放器_initVideo();}void dispose() {_videoPlayerController.dispose();_chewieController.dispose();super.dispose();}// 初始化播放器void _initVideo() async {Uri url = Uri.parse("https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4");_videoPlayerController = VideoPlayerController.networkUrl(url);await _videoPlayerController.initialize();_chewieController = ChewieController(videoPlayerController: _videoPlayerController,aspectRatio: _videoPlayerController.value.aspectRatio,autoPlay: true,looping: false);setState(() {});}Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("Chewie demo-在線播放視頻"),),body: Center(child: _videoPlayerController.value.isInitialized ? AspectRatio(aspectRatio: _videoPlayerController.value.aspectRatio,child: Chewie(controller: _chewieController),) : CircularProgressIndicator(),),);}
}
- 效果圖: