part of './ijkplayer.dart'; /// Media Controller class IjkMediaController { IjkMediaController({ this.autoRotate = true, }); int _textureId; bool autoRotate; int get textureId => _textureId; set textureId(int id) { _textureId = id; _textureIdController.add(id); } StreamController _textureIdController = StreamController.broadcast(); Stream get textureIdStream => _textureIdController.stream; _IjkPlugin _plugin; bool get isInit => textureId == null; IJKEventChannel eventChannel; bool _isPlaying = false; bool get isPlaying => _isPlaying == true; set isPlaying(bool value) { this._isPlaying = value; _playingController.add(value); } StreamController _playingController = StreamController.broadcast(); Stream get playingStream => _playingController.stream; StreamController _videoInfoController = StreamController.broadcast(); Stream get videoInfoStream => _videoInfoController.stream; StreamController _volumeController = StreamController.broadcast(); Stream get volumeStream => _volumeController.stream; int _volume = 100; set volume(int value) { this._volume = value; _volumeController.add(volume); _setVolume(value); } int get volume => _volume; Future _initIjk() async { try { var id = await _createIjk(); this.textureId = id; _plugin = _IjkPlugin(id); eventChannel = IJKEventChannel(this); await eventChannel.init(); volume = 100; } catch (e) { print(e); print("初始化失败"); } } void dispose() async { await reset(); _playingController.close(); _videoInfoController.close(); _textureIdController.close(); _volumeController.close(); } Future reset() async { volume = 100; this.textureId = null; _plugin?.dispose(); _plugin = null; eventChannel?.dispose(); eventChannel = null; } Future setNetworkDataSource( String url, { bool autoPlay = false, }) async { await _initDataSource(() async { await _plugin?.setNetworkDataSource(uri: url); }, autoPlay); } Future setAssetDataSource( String name, { String package, bool autoPlay = false, }) async { await _initDataSource(() async { await _plugin?.setAssetDataSource(name, package); }, autoPlay); } Future setFileDataSource( File file, { bool autoPlay = false, }) async { await _initDataSource(() async { await _plugin?.setFileDataSource(file.absolute.path); }, autoPlay); } Future _initDataSource( Future setDataSource(), bool autoPlay, ) async { autoPlay ??= false; if (this.textureId != null) { await _plugin?.dispose(); } await _initIjk(); _autoPlay(autoPlay); await setDataSource(); } Future playOrPause() async { var videoInfo = await getVideoInfo(); var playing = videoInfo.isPlaying; if (playing) { await _plugin?.pause(); } else { await _plugin?.play(); } refreshVideoInfo(); } Future play() async { await _plugin?.play(); refreshVideoInfo(); } Future pause() async { await _plugin?.pause(); refreshVideoInfo(); } Future seekTo(double target) async { await _plugin?.seekTo(target); refreshVideoInfo(); } Future getVideoInfo() async { Map result = await _plugin?.getInfo(); var info = VideoInfo.fromMap(result); return info; } Future refreshVideoInfo() async { var info = await getVideoInfo(); isPlaying = info.isPlaying; if (info.hasData) _videoInfoController?.add(info); print("info = $info"); } void _autoPlay(bool autoPlay) { if (autoPlay) { eventChannel?.autoPlay(this); } } Future _setVolume(int volume) async { await _plugin?.setVolume(volume); } Future stop() async { // await _plugin?.stop(); // refreshVideoInfo(); await _plugin?.pause(); await _plugin?.seekTo(0); refreshVideoInfo(); } } /// about channel MethodChannel _globalChannel = MethodChannel("top.kikt/ijkplayer"); Future _createIjk() async { int id = await _globalChannel.invokeMethod("create"); return id; } /// For the hot reload/ hot restart to release last texture resource. Release version does not have hot reload, so you can not call it. /// /// release版本可不调用, 主要是为了释放hot restart/hot reload的资源,因为原生资源不参与热重载 /// /// /// If this method is not invoked in the debug version, the sound before the hot reload will continue to play. Future initIJKPlayer() async { _globalChannel.invokeMethod("init"); } class _IjkPlugin { MethodChannel get channel => MethodChannel("top.kikt/ijkplayer/$textureId"); int textureId; _IjkPlugin(this.textureId); Future dispose() async { await _globalChannel.invokeMethod("dispose", {"id": textureId}); } Future play() async { await channel.invokeMethod("play"); } Future pause() async { await channel.invokeMethod("pause"); } Future stop() async { await channel.invokeMethod("stop"); } Future setNetworkDataSource({String uri}) async { print("id = $textureId net uri = $uri"); await channel.invokeMethod("setNetworkDataSource", {"uri": uri}); } Future setAssetDataSource(String name, String package) async { print("id = $textureId asset name = $name package = $package"); var params = { "name": name, }; if (package != null) { params["package"] = package; } await channel.invokeMethod("setAssetDataSource", params); } Future setFileDataSource(String path) async { if (!File(path).existsSync()) { return Error.fileNotExists; } await channel.invokeMethod("setFileDataSource", { "path": path, }); print("id = $textureId file path = $path"); } Future> getInfo() async { var map = await channel.invokeMethod("getInfo"); if (map == null) { return null; } else { return map.cast(); } } Future seekTo(double target) async { await channel.invokeMethod("seekTo", { "target": target, }); } Future setVolume(int volume) async { await channel.invokeMethod("setVolume", { "volume": volume, }); } }