in_overlay_page.dart 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
  3. import 'package:ijkplayer_example/i18n/i18n.dart';
  4. class InOverlayPage extends StatefulWidget {
  5. @override
  6. _InOverlayPageState createState() => _InOverlayPageState();
  7. }
  8. class _InOverlayPageState extends State<InOverlayPage> {
  9. IjkMediaController controller = IjkMediaController();
  10. OverlayEntry entry;
  11. @override
  12. void initState() {
  13. super.initState();
  14. controller.setDataSource(
  15. DataSource.network(
  16. "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4",
  17. ),
  18. autoPlay: true,
  19. );
  20. }
  21. @override
  22. void deactivate() {
  23. super.deactivate();
  24. entry?.remove();
  25. entry = null;
  26. }
  27. @override
  28. void dispose() {
  29. controller?.dispose();
  30. super.dispose();
  31. }
  32. @override
  33. Widget build(BuildContext context) {
  34. return Scaffold(
  35. appBar: AppBar(
  36. title: Text(currentI18n.overlayPageTitle),
  37. ),
  38. body: ListView(
  39. children: <Widget>[
  40. AspectRatio(
  41. child: IjkPlayer(
  42. mediaController: controller,
  43. ),
  44. aspectRatio: 1,
  45. ),
  46. FlatButton(
  47. child: Text("showInOverlay"),
  48. onPressed: showInOverlay,
  49. ),
  50. ],
  51. ),
  52. );
  53. }
  54. void showInOverlay() async {
  55. var info = await controller.getVideoInfo();
  56. OverlayEntry _entry;
  57. _entry = OverlayEntry(
  58. builder: (BuildContext context) {
  59. return OverlayWidget(
  60. controller: controller,
  61. initVideoInfo: info,
  62. onTapClose: () {
  63. _entry?.remove();
  64. },
  65. );
  66. },
  67. );
  68. Overlay.of(context).insert(_entry);
  69. }
  70. }
  71. class OverlayWidget extends StatefulWidget {
  72. final VideoInfo initVideoInfo;
  73. final IjkMediaController controller;
  74. final Function onTapClose;
  75. const OverlayWidget({
  76. Key key,
  77. this.initVideoInfo,
  78. this.controller,
  79. this.onTapClose,
  80. }) : super(key: key);
  81. @override
  82. _OverlayWidgetState createState() => _OverlayWidgetState();
  83. }
  84. const double _overlayWidth = 100;
  85. class _OverlayWidgetState extends State<OverlayWidget> {
  86. double dx = 0;
  87. double dy = 1;
  88. @override
  89. Widget build(BuildContext context) {
  90. return NotificationListener<OffsetNotication>(
  91. onNotification: _onOffsetNoticiation,
  92. child: Align(
  93. alignment: Alignment(dx, dy),
  94. child: Container(
  95. width: _overlayWidth,
  96. child: AspectRatio(
  97. aspectRatio: widget.initVideoInfo.ratio,
  98. child: IjkPlayer(
  99. mediaController: widget.controller,
  100. controllerWidgetBuilder: (ctl) {
  101. return OverlayControllerWidget(
  102. controller: ctl,
  103. onTapClose: widget.onTapClose,
  104. );
  105. },
  106. ),
  107. ),
  108. ),
  109. ),
  110. );
  111. }
  112. Offset _startOffset;
  113. bool _onOffsetNoticiation(OffsetNotication notification) {
  114. if (notification.type == OffsetType.start) {
  115. _startOffset = Offset(dx, dy);
  116. return true;
  117. }
  118. var offset = notification.offset;
  119. var size = MediaQuery.of(context).size;
  120. dx = _startOffset.dx + offset.dx / size.width * 2;
  121. dy = _startOffset.dy + offset.dy / size.height * 2;
  122. print("dx = $dx");
  123. print("dy = $dy");
  124. if (dx > 1) {
  125. dx = 1;
  126. } else if (dx < -1) {
  127. dx = -1;
  128. }
  129. if (dy > 1) {
  130. dy = 1;
  131. } else if (dy < -1) {
  132. dy = -1;
  133. }
  134. setState(() {});
  135. return true;
  136. }
  137. }
  138. class OverlayControllerWidget extends StatefulWidget {
  139. final IjkMediaController controller;
  140. final Function onTapClose;
  141. const OverlayControllerWidget({
  142. Key key,
  143. this.controller,
  144. this.onTapClose,
  145. }) : super(key: key);
  146. @override
  147. _OverlayControllerWidgetState createState() =>
  148. _OverlayControllerWidgetState();
  149. }
  150. class _OverlayControllerWidgetState extends State<OverlayControllerWidget> {
  151. bool showController = false;
  152. @override
  153. Widget build(BuildContext context) {
  154. Widget child;
  155. if (!showController) {
  156. child = Container();
  157. } else {
  158. child = Container(
  159. color: Colors.black.withOpacity(0.6),
  160. child: Align(
  161. alignment: Alignment.topRight,
  162. child: Container(
  163. child: IconButton(
  164. color: Colors.white,
  165. icon: Icon(Icons.close),
  166. onPressed: widget.onTapClose,
  167. ),
  168. ),
  169. ),
  170. );
  171. }
  172. return GestureDetector(
  173. child: child,
  174. behavior: HitTestBehavior.opaque,
  175. onTap: () => setState(() => showController = !showController),
  176. // onPanUpdate: (detail) {
  177. // var notification = OffsetNotication()
  178. // ..offset = detail.delta
  179. // ..type = OffsetType.update;
  180. // notification.dispatch(context);
  181. // },
  182. // onPanStart: (detail) {
  183. // var notication = OffsetNotication()..type = OffsetType.start;
  184. // notication.dispatch(context);
  185. // },
  186. onLongPressMoveUpdate: (detail) {
  187. var notification = OffsetNotication()
  188. ..offset = detail.offsetFromOrigin
  189. ..type = OffsetType.update;
  190. notification.dispatch(context);
  191. },
  192. onLongPressStart: (detail) {
  193. var n = OffsetNotication()..type = OffsetType.start;
  194. n.dispatch(context);
  195. },
  196. );
  197. }
  198. }
  199. class OffsetNotication extends Notification {
  200. Offset offset;
  201. OffsetType type;
  202. }
  203. enum OffsetType {
  204. start,
  205. update,
  206. }