view.dart 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import 'package:fis_measure/index.dart';
  2. import 'package:fis_measure/interfaces/process/player/play_controller.dart';
  3. import 'package:fis_vid/data_host/data_host.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:get/get.dart';
  6. import 'package:image/image.dart';
  7. import 'package:vid_player_demo/controller/player_controller.dart';
  8. import 'package:vid_player_demo/widgets/image_cache.dart';
  9. import 'widgets/canvas_player.dart';
  10. class CanvasPlayerView extends StatefulWidget {
  11. const CanvasPlayerView(
  12. this.vidURL, {
  13. Key? key,
  14. this.viewSize = const Size(600, 500),
  15. }) : super(key: key);
  16. final String vidURL;
  17. final Size viewSize;
  18. @override
  19. _CanvasPlayerViewState createState() => _CanvasPlayerViewState();
  20. }
  21. class _CanvasPlayerViewState extends State<CanvasPlayerView> {
  22. VidPlayerController? _playerController;
  23. VidPlayerController get playerController => _playerController!;
  24. VidDataHost? _vidDataHost;
  25. VidDataHost get dataHost => _vidDataHost!;
  26. bool _ifInit = false;
  27. double _brightness = 0;
  28. double _contrast = 0;
  29. double _matrixBrightness = 0.0;
  30. double _matrixContrast = 1.0;
  31. final colorFiltersMatrix = {
  32. "原色": <double>[
  33. 1, 0, 0, 0, 0, // red
  34. 0, 1, 0, 0, 0, // green
  35. 0, 0, 1, 0, 0, // blue
  36. 0, 0, 0, 1, 0, // alpha
  37. ],
  38. "红色通道": <double>[
  39. 1, 0, 0, 0, 0, // red
  40. 0, 0, 0, 0, 0, // green
  41. 0, 0, 0, 0, 0, // blue
  42. 0, 0, 0, 1, 0, // alpha
  43. ],
  44. "绿色通道": <double>[
  45. 0, 0, 0, 0, 0, // red
  46. 1, 0, 0, 0, 0, // green
  47. 0, 0, 0, 0, 0, // blue
  48. 0, 0, 0, 1, 0, // alpha
  49. ],
  50. "蓝色通道": <double>[
  51. 0, 0, 0, 0, 0, // red
  52. 0, 0, 0, 0, 0, // green
  53. 1, 0, 0, 0, 0, // blue
  54. 0, 0, 0, 1, 0, // alpha
  55. ],
  56. "低对比度": <double>[
  57. 0.5, 0, 0, 0, 0, // red
  58. 0, 0.5, 0, 0, 0, // green
  59. 0, 0, 0.5, 0, 0, // blue
  60. 0, 0, 0, 1, 0, // alpha
  61. ],
  62. "高对比度": <double>[
  63. 2, 0, 0, 0, 0, // red
  64. 0, 2, 0, 0, 0, // green
  65. 0, 0, 2, 0, 0, // blue
  66. 0, 0, 0, 1, 0, // alpha
  67. ]
  68. };
  69. /// 外部播放状态控制器
  70. PlayerStateController? _playerStateController;
  71. PlayerStateController get playerStateController => _playerStateController!;
  72. void loadVidDataHost(String url) {
  73. print("${DateTime.now()} Load vid data host");
  74. _vidDataHost = VidDataHost(url);
  75. _playerController = VidPlayerController(dataHost: dataHost);
  76. }
  77. void clickPlay() {
  78. print("${DateTime.now()} Click play");
  79. if (_ifInit) {
  80. playerController.play();
  81. } else {
  82. dataHost.load().then((value) {
  83. if (value == null) {
  84. // TOOO: add log
  85. } else {
  86. playerController.setLoadState(true);
  87. Future.delayed(const Duration(milliseconds: 100), () {
  88. playerController.play();
  89. });
  90. print("${DateTime.now()} Load vid data host success");
  91. }
  92. _ifInit = true;
  93. });
  94. }
  95. }
  96. void clickPause() {
  97. print("${DateTime.now()} Click pause");
  98. playerController.pause();
  99. }
  100. void onClickPlay(Object sender, dynamic e) {
  101. print("${DateTime.now()} receive Play $e");
  102. clickPlay();
  103. }
  104. ///设置亮度传入的value范围为-100 ~ 100,brightness的范围为 -1 ~ 1
  105. void setBrightness(value) {
  106. final brightness = value / 100;
  107. if (brightness < -1 || brightness > 1) {
  108. return;
  109. }
  110. _matrixBrightness = brightness;
  111. final fliterMatrix = <double>[
  112. _matrixContrast, 0, 0, 0, _matrixBrightness, // red
  113. 0, _matrixContrast, 0, 0, _matrixBrightness, // green
  114. 0, 0, _matrixContrast, 0, _matrixBrightness, // blue
  115. 0, 0, 0, 1, 0, // alpha
  116. ];
  117. playerController.setFilterMatrix(fliterMatrix);
  118. }
  119. ///设置对比度传入的value范围为value范围为-100 ~ 100,brightness的范围为 0 ~ 10
  120. void setContrast(value) {
  121. double contrast = 1;
  122. if (value < 0) {
  123. contrast = (value + 100) / 100;
  124. } else if (value >= 0) {
  125. contrast = value / 100 * 9 + 1;
  126. }
  127. if (contrast < 0 || contrast > 10) {
  128. return;
  129. }
  130. _matrixContrast = contrast;
  131. final fliterMatrix = <double>[
  132. _matrixContrast, 0, 0, 0, _matrixBrightness, // red
  133. 0, _matrixContrast, 0, 0, _matrixBrightness, // green
  134. 0, 0, _matrixContrast, 0, _matrixBrightness, // blue
  135. 0, 0, 0, 1, 0, // alpha
  136. ];
  137. playerController.setFilterMatrix(fliterMatrix);
  138. }
  139. @override
  140. void initState() {
  141. super.initState();
  142. loadVidDataHost(widget.vidURL);
  143. _playerStateController = Get.find<PlayerStateController>();
  144. playerStateController.trigglePlay.addListener(onClickPlay);
  145. }
  146. @override
  147. Widget build(BuildContext context) {
  148. return Center(
  149. child: Column(
  150. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  151. children: [
  152. SizedBox(
  153. width: widget.viewSize.width,
  154. height: widget.viewSize.height,
  155. child: RepaintBoundary(
  156. child: VidCanvasPlayer(
  157. _playerController as VidPlayerController,
  158. ),
  159. ),
  160. ),
  161. const Text('基于 Canvas 的播放器'),
  162. Row(
  163. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  164. children: [
  165. ElevatedButton(
  166. onPressed: () {
  167. clickPlay();
  168. },
  169. child: const Text('▶ Play')),
  170. ElevatedButton(
  171. onPressed: () {
  172. clickPause();
  173. },
  174. child: const Text('⏸ Pause')),
  175. ...colorFiltersMatrix.keys.map((key) {
  176. return ElevatedButton(
  177. onPressed: () {
  178. playerController.setFilterMatrix(colorFiltersMatrix[key]!);
  179. },
  180. child: Text(key),
  181. );
  182. }).toList(),
  183. ],
  184. ),
  185. const SizedBox(
  186. height: 20,
  187. ),
  188. Row(children: [
  189. const Text("明亮度"),
  190. SizedBox(
  191. width: 800,
  192. child: Slider(
  193. value: _brightness,
  194. max: 100,
  195. min: -100,
  196. divisions: 200,
  197. label: _brightness.round().toString(),
  198. onChanged: (double value) {
  199. setBrightness(value);
  200. setState(() {
  201. _brightness = value;
  202. });
  203. },
  204. ),
  205. )
  206. ]),
  207. Row(children: [
  208. const Text("对比度"),
  209. SizedBox(
  210. width: 800,
  211. child: Slider(
  212. value: _contrast,
  213. max: 100,
  214. min: -100,
  215. divisions: 200,
  216. label: _contrast.round().toString(),
  217. onChanged: (double value) {
  218. setContrast(value);
  219. setState(() {
  220. _contrast = value;
  221. });
  222. },
  223. ),
  224. )
  225. ])
  226. ],
  227. ),
  228. );
  229. }
  230. @override
  231. void dispose() {
  232. print("CanvasPlayerView dispose");
  233. playerController.dispose();
  234. dataHost.release();
  235. playerStateController.trigglePlay.removeListener(onClickPlay);
  236. super.dispose();
  237. }
  238. }