controller.dart 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. part of './ijkplayer.dart';
  2. /// Media Controller
  3. class IjkMediaController {
  4. IjkMediaController({
  5. this.autoRotate = true,
  6. });
  7. int _textureId;
  8. bool autoRotate;
  9. int get textureId => _textureId;
  10. set textureId(int id) {
  11. _textureId = id;
  12. _textureIdController.add(id);
  13. }
  14. StreamController<int> _textureIdController = StreamController.broadcast();
  15. Stream<int> get textureIdStream => _textureIdController.stream;
  16. _IjkPlugin _plugin;
  17. bool get isInit => textureId == null;
  18. IJKEventChannel eventChannel;
  19. bool _isPlaying = false;
  20. bool get isPlaying => _isPlaying == true;
  21. set isPlaying(bool value) {
  22. this._isPlaying = value;
  23. _playingController.add(value);
  24. }
  25. StreamController<bool> _playingController = StreamController.broadcast();
  26. Stream<bool> get playingStream => _playingController.stream;
  27. StreamController<VideoInfo> _videoInfoController =
  28. StreamController.broadcast();
  29. Stream<VideoInfo> get videoInfoStream => _videoInfoController.stream;
  30. StreamController<int> _volumeController = StreamController.broadcast();
  31. Stream<int> get volumeStream => _volumeController.stream;
  32. int _volume = 100;
  33. set volume(int value) {
  34. this._volume = value;
  35. _volumeController.add(volume);
  36. _setVolume(value);
  37. }
  38. int get volume => _volume;
  39. Future<void> _initIjk() async {
  40. try {
  41. var id = await _createIjk();
  42. this.textureId = id;
  43. _plugin = _IjkPlugin(id);
  44. eventChannel = IJKEventChannel(this);
  45. await eventChannel.init();
  46. volume = 100;
  47. } catch (e) {
  48. print(e);
  49. print("初始化失败");
  50. }
  51. }
  52. void dispose() async {
  53. await reset();
  54. _playingController.close();
  55. _videoInfoController.close();
  56. _textureIdController.close();
  57. _volumeController.close();
  58. }
  59. Future<void> reset() async {
  60. volume = 100;
  61. this.textureId = null;
  62. _plugin?.dispose();
  63. _plugin = null;
  64. eventChannel?.dispose();
  65. eventChannel = null;
  66. }
  67. Future<void> setNetworkDataSource(
  68. String url, {
  69. bool autoPlay = false,
  70. }) async {
  71. await _initDataSource(() async {
  72. await _plugin?.setNetworkDataSource(uri: url);
  73. }, autoPlay);
  74. }
  75. Future<void> setAssetDataSource(
  76. String name, {
  77. String package,
  78. bool autoPlay = false,
  79. }) async {
  80. await _initDataSource(() async {
  81. await _plugin?.setAssetDataSource(name, package);
  82. }, autoPlay);
  83. }
  84. Future<void> setFileDataSource(
  85. File file, {
  86. bool autoPlay = false,
  87. }) async {
  88. await _initDataSource(() async {
  89. await _plugin?.setFileDataSource(file.absolute.path);
  90. }, autoPlay);
  91. }
  92. Future<void> _initDataSource(
  93. Future setDataSource(),
  94. bool autoPlay,
  95. ) async {
  96. autoPlay ??= false;
  97. if (this.textureId != null) {
  98. await _plugin?.dispose();
  99. }
  100. await _initIjk();
  101. _autoPlay(autoPlay);
  102. await setDataSource();
  103. }
  104. Future<void> playOrPause() async {
  105. var videoInfo = await getVideoInfo();
  106. var playing = videoInfo.isPlaying;
  107. if (playing) {
  108. await _plugin?.pause();
  109. } else {
  110. await _plugin?.play();
  111. }
  112. refreshVideoInfo();
  113. }
  114. Future<void> play() async {
  115. await _plugin?.play();
  116. refreshVideoInfo();
  117. }
  118. Future<void> pause() async {
  119. await _plugin?.pause();
  120. refreshVideoInfo();
  121. }
  122. Future<void> seekTo(double target) async {
  123. await _plugin?.seekTo(target);
  124. refreshVideoInfo();
  125. }
  126. Future<VideoInfo> getVideoInfo() async {
  127. Map<String, dynamic> result = await _plugin?.getInfo();
  128. var info = VideoInfo.fromMap(result);
  129. return info;
  130. }
  131. Future<void> refreshVideoInfo() async {
  132. var info = await getVideoInfo();
  133. isPlaying = info.isPlaying;
  134. if (info.hasData) _videoInfoController?.add(info);
  135. print("info = $info");
  136. }
  137. void _autoPlay(bool autoPlay) {
  138. if (autoPlay) {
  139. eventChannel?.autoPlay(this);
  140. }
  141. }
  142. Future<void> _setVolume(int volume) async {
  143. await _plugin?.setVolume(volume);
  144. }
  145. Future<void> stop() async {
  146. // await _plugin?.stop();
  147. // refreshVideoInfo();
  148. await _plugin?.pause();
  149. await _plugin?.seekTo(0);
  150. refreshVideoInfo();
  151. }
  152. }
  153. /// about channel
  154. MethodChannel _globalChannel = MethodChannel("top.kikt/ijkplayer");
  155. Future<int> _createIjk() async {
  156. int id = await _globalChannel.invokeMethod("create");
  157. return id;
  158. }
  159. /// For the hot reload/ hot restart to release last texture resource. Release version does not have hot reload, so you can not call it.
  160. ///
  161. /// release版本可不调用, 主要是为了释放hot restart/hot reload的资源,因为原生资源不参与热重载
  162. ///
  163. ///
  164. /// If this method is not invoked in the debug version, the sound before the hot reload will continue to play.
  165. Future<void> initIJKPlayer() async {
  166. _globalChannel.invokeMethod("init");
  167. }
  168. class _IjkPlugin {
  169. MethodChannel get channel => MethodChannel("top.kikt/ijkplayer/$textureId");
  170. int textureId;
  171. _IjkPlugin(this.textureId);
  172. Future<void> dispose() async {
  173. await _globalChannel.invokeMethod("dispose", {"id": textureId});
  174. }
  175. Future<void> play() async {
  176. await channel.invokeMethod("play");
  177. }
  178. Future<void> pause() async {
  179. await channel.invokeMethod("pause");
  180. }
  181. Future<void> stop() async {
  182. await channel.invokeMethod("stop");
  183. }
  184. Future<void> setNetworkDataSource({String uri}) async {
  185. print("id = $textureId net uri = $uri");
  186. await channel.invokeMethod("setNetworkDataSource", {"uri": uri});
  187. }
  188. Future<void> setAssetDataSource(String name, String package) async {
  189. print("id = $textureId asset name = $name package = $package");
  190. var params = <String, dynamic>{
  191. "name": name,
  192. };
  193. if (package != null) {
  194. params["package"] = package;
  195. }
  196. await channel.invokeMethod("setAssetDataSource", params);
  197. }
  198. Future<void> setFileDataSource(String path) async {
  199. if (!File(path).existsSync()) {
  200. return Error.fileNotExists;
  201. }
  202. await channel.invokeMethod("setFileDataSource", <String, dynamic>{
  203. "path": path,
  204. });
  205. print("id = $textureId file path = $path");
  206. }
  207. Future<Map<String, dynamic>> getInfo() async {
  208. var map = await channel.invokeMethod("getInfo");
  209. if (map == null) {
  210. return null;
  211. } else {
  212. return map.cast<String, dynamic>();
  213. }
  214. }
  215. Future<void> seekTo(double target) async {
  216. await channel.invokeMethod("seekTo", <String, dynamic>{
  217. "target": target,
  218. });
  219. }
  220. Future<void> setVolume(int volume) async {
  221. await channel.invokeMethod("setVolume", <String, dynamic>{
  222. "volume": volume,
  223. });
  224. }
  225. }