controller.dart 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. part of '../ijkplayer.dart';
  2. /// Media Controller
  3. class IjkMediaController
  4. with IjkMediaControllerMixin, IjkMediaControllerStreamMixin {
  5. /// It will automatically correct the direction of the video.
  6. bool autoRotate;
  7. int index;
  8. String get debugLabel => index.toString();
  9. /// MediaController
  10. IjkMediaController({
  11. this.autoRotate = true,
  12. }) {
  13. index = IjkMediaPlayerManager().add(this);
  14. }
  15. /// create ijk texture id from native
  16. Future<void> _initIjk() async {
  17. try {
  18. var id = await _createIjk();
  19. this.textureId = id;
  20. _plugin = _IjkPlugin(id);
  21. eventChannel = _IJKEventChannel(this);
  22. await eventChannel.init();
  23. volume = 100;
  24. } catch (e) {
  25. LogUtils.warning(e);
  26. LogUtils.warning("初始化失败");
  27. }
  28. }
  29. /// [reset] and close all controller
  30. void dispose() async {
  31. await reset();
  32. await _disposeStream();
  33. IjkMediaPlayerManager().remove(this);
  34. }
  35. /// dispose all resource
  36. Future<void> reset() async {
  37. volume = 100;
  38. this.textureId = null;
  39. _plugin?.dispose();
  40. _plugin = null;
  41. eventChannel?.dispose();
  42. eventChannel = null;
  43. _ijkStatus = IjkStatus.noDatasource;
  44. }
  45. /// set net DataSource
  46. Future<void> setNetworkDataSource(
  47. String url, {
  48. Map<String, String> headers = const {},
  49. bool autoPlay = false,
  50. }) async {
  51. _ijkStatus = IjkStatus.preparing;
  52. await _initDataSource(() async {
  53. await _plugin?.setNetworkDataSource(
  54. uri: url,
  55. headers: headers,
  56. );
  57. _ijkStatus = IjkStatus.prepared;
  58. }, autoPlay);
  59. }
  60. /// set asset DataSource
  61. Future<void> setAssetDataSource(
  62. String name, {
  63. String package,
  64. bool autoPlay = false,
  65. }) async {
  66. _ijkStatus = IjkStatus.preparing;
  67. await _initDataSource(() async {
  68. await _plugin?.setAssetDataSource(name, package);
  69. _ijkStatus = IjkStatus.prepared;
  70. }, autoPlay);
  71. }
  72. /// Set datasource with [DataSource]
  73. Future<void> setDataSource(
  74. DataSource source, {
  75. bool autoPlay = false,
  76. }) async {
  77. switch (source._type) {
  78. case DataSourceType.asset:
  79. await setAssetDataSource(
  80. source._assetName,
  81. package: source._assetPackage,
  82. autoPlay: autoPlay,
  83. );
  84. break;
  85. case DataSourceType.file:
  86. await setFileDataSource(
  87. source._file,
  88. autoPlay: autoPlay,
  89. );
  90. break;
  91. case DataSourceType.network:
  92. await setNetworkDataSource(
  93. source._netWorkUrl,
  94. headers: source._headers,
  95. autoPlay: autoPlay,
  96. );
  97. break;
  98. default:
  99. }
  100. }
  101. /// set file DataSource
  102. Future<void> setFileDataSource(
  103. File file, {
  104. bool autoPlay = false,
  105. }) async {
  106. _ijkStatus = IjkStatus.preparing;
  107. await _initDataSource(() async {
  108. await _plugin?.setFileDataSource(file.absolute.path);
  109. _ijkStatus = IjkStatus.prepared;
  110. }, autoPlay);
  111. }
  112. /// dispose last textureId resource
  113. Future<void> _initDataSource(
  114. Future setDataSource(),
  115. bool autoPlay,
  116. ) async {
  117. autoPlay ??= false;
  118. if (this.textureId != null) {
  119. await _plugin?.dispose();
  120. }
  121. await _initIjk();
  122. Future playFuture = _autoPlay(autoPlay);
  123. await setDataSource();
  124. return playFuture;
  125. }
  126. /// Play or pause according to your current status
  127. Future<void> playOrPause({
  128. pauseOther = false,
  129. }) async {
  130. var videoInfo = await getVideoInfo();
  131. var playing = videoInfo.isPlaying;
  132. if (playing) {
  133. await pause();
  134. } else {
  135. await play(pauseOther: pauseOther);
  136. }
  137. }
  138. /// play media
  139. Future<void> play({
  140. pauseOther = false,
  141. }) async {
  142. if (pauseOther) {
  143. await pauseOtherController();
  144. }
  145. LogUtils.info("$this play");
  146. await _plugin?.play();
  147. refreshVideoInfo();
  148. _ijkStatus = IjkStatus.playing;
  149. }
  150. /// pause media
  151. Future<void> pause() async {
  152. LogUtils.info("$this pause");
  153. await _plugin?.pause();
  154. refreshVideoInfo();
  155. _ijkStatus = IjkStatus.pause;
  156. }
  157. /// seek to second
  158. ///
  159. /// [target] unit is second
  160. Future<void> seekTo(double target) async {
  161. await _plugin?.seekTo(target);
  162. _ijkStatus = IjkStatus.pause;
  163. refreshVideoInfo();
  164. }
  165. /// seek to progress
  166. Future<void> seekToProgress(double progress) async {
  167. var videoInfo = await getVideoInfo();
  168. var target = videoInfo.duration * progress;
  169. await this.seekTo(target);
  170. refreshVideoInfo();
  171. }
  172. /// get video info from native
  173. Future<VideoInfo> getVideoInfo() async {
  174. Map<String, dynamic> result = await _plugin?.getInfo();
  175. var info = VideoInfo.fromMap(result);
  176. return info;
  177. }
  178. /// request info and notify
  179. Future<void> refreshVideoInfo() async {
  180. var info = await getVideoInfo();
  181. _videoInfo = info;
  182. isPlaying = info.isPlaying;
  183. if (info.hasData) {
  184. _videoInfoController?.add(info);
  185. LogUtils.verbose("onrefreshInfo = $info");
  186. }
  187. }
  188. /// AutoPlay use
  189. Future<void> _autoPlay(bool autoPlay) async {
  190. if (autoPlay) {
  191. await eventChannel?.autoPlay(this);
  192. } else {
  193. await eventChannel?.disableAutoPlay(this);
  194. }
  195. }
  196. /// set video volume
  197. Future<void> _setVolume(int volume) async {
  198. await _plugin?.setVolume(volume);
  199. }
  200. /// [pause] and [seekTo] 0
  201. Future<void> stop() async {
  202. // await _plugin?.stop();
  203. // refreshVideoInfo();
  204. await _plugin?.pause();
  205. await _plugin?.seekTo(0);
  206. refreshVideoInfo();
  207. }
  208. /// get system volume
  209. Future<int> getSystemVolume() async {
  210. return IjkManager.getSystemVolume();
  211. }
  212. /// set system volume
  213. Future<void> setSystemVolume(int volume) async {
  214. await IjkManager.setSystemVolume(volume);
  215. }
  216. /// Pause all other players.
  217. Future<void> pauseOtherController() async {
  218. await IjkMediaPlayerManager().pauseOther(this);
  219. }
  220. @override
  221. String toString() {
  222. return "IJKController[$index]";
  223. }
  224. Future<void> hideSystemVolumeBar() async {
  225. await IjkManager.hideSystemVolumeBar();
  226. }
  227. void _onPlayFinish() {
  228. isPlaying = videoInfo.isPlaying;
  229. refreshVideoInfo();
  230. _playFinishController?.add(this);
  231. _ijkStatus = IjkStatus.complete;
  232. }
  233. /// Intercept the video frame image and get the `Uint8List` format.
  234. ///
  235. /// Player UI is not included. If you need the effect of the player, use the screenshot of the system.
  236. Future<Uint8List> screenShot() {
  237. return _plugin.screenShot();
  238. }
  239. }