part of './ijkplayer.dart'; /// Media Controller class IjkMediaController { /// MediaController IjkMediaController({ this.autoRotate = true, }); /// texture id from native int _textureId; /// It will automatically correct the direction of the video. bool autoRotate; /// texture id from native int get textureId => _textureId; /// set texture id, Normally the user does not call set textureId(int id) { _textureId = id; _textureIdController.add(id); } /// on texture id change StreamController _textureIdController = StreamController.broadcast(); /// on texture id change Stream get textureIdStream => _textureIdController.stream; /// Channel of flutter and native. _IjkPlugin _plugin; /// Whether texture id is null bool get isInit => textureId == null; /// channel of native to flutter _IJKEventChannel eventChannel; /// playing state bool _isPlaying = false; /// playing state bool get isPlaying => _isPlaying == true; /// playing state set isPlaying(bool value) { this._isPlaying = value; _playingController.add(value); } /// playing state stream controller StreamController _playingController = StreamController.broadcast(); /// playing state stream Stream get playingStream => _playingController.stream; /// video info stream controller StreamController _videoInfoController = StreamController.broadcast(); /// video info stream Stream get videoInfoStream => _videoInfoController.stream; /// video volume stream controller StreamController _volumeController = StreamController.broadcast(); /// video volume stream Stream get volumeStream => _volumeController.stream; /// video volume, not system volume int _volume = 100; /// video volume, not system volume set volume(int value) { if (value > 100) { value = 100; } else if (value < 0) { value = 0; } this._volume = value; _volumeController.add(value); _setVolume(value); } /// video volume, not system volume int get volume => _volume; /// create ijk texture id from native Future _initIjk() async { try { var id = await _createIjk(); this.textureId = id; _plugin = _IjkPlugin(id); eventChannel = _IJKEventChannel(this); await eventChannel.init(); volume = 100; } catch (e) { LogUtils.log(e); LogUtils.log("初始化失败"); } } /// [reset] and close all controller void dispose() async { await reset(); _playingController.close(); _videoInfoController.close(); _textureIdController.close(); _volumeController.close(); } /// dispose all resource Future reset() async { volume = 100; this.textureId = null; _plugin?.dispose(); _plugin = null; eventChannel?.dispose(); eventChannel = null; } /// set net DataSource Future setNetworkDataSource( String url, { bool autoPlay = false, }) async { await _initDataSource(() async { await _plugin?.setNetworkDataSource(uri: url); }, autoPlay); } /// set asset DataSource Future setAssetDataSource( String name, { String package, bool autoPlay = false, }) async { await _initDataSource(() async { await _plugin?.setAssetDataSource(name, package); }, autoPlay); } /// set file DataSource Future setFileDataSource( File file, { bool autoPlay = false, }) async { await _initDataSource(() async { await _plugin?.setFileDataSource(file.absolute.path); }, autoPlay); } /// dispose last textureId resource Future _initDataSource( Future setDataSource(), bool autoPlay, ) async { autoPlay ??= false; if (this.textureId != null) { await _plugin?.dispose(); } await _initIjk(); _autoPlay(autoPlay); await setDataSource(); } /// Play or pause according to your current status Future playOrPause() async { var videoInfo = await getVideoInfo(); var playing = videoInfo.isPlaying; if (playing) { await _plugin?.pause(); } else { await _plugin?.play(); } refreshVideoInfo(); } /// play media Future play() async { await _plugin?.play(); refreshVideoInfo(); } /// pause media Future pause() async { await _plugin?.pause(); refreshVideoInfo(); } /// seek to second /// /// [target] unit is second Future seekTo(double target) async { await _plugin?.seekTo(target); refreshVideoInfo(); } /// get video info from native Future getVideoInfo() async { Map result = await _plugin?.getInfo(); var info = VideoInfo.fromMap(result); return info; } /// request info and notify Future refreshVideoInfo() async { var info = await getVideoInfo(); isPlaying = info.isPlaying; if (info.hasData) _videoInfoController?.add(info); LogUtils.log("info = $info"); } /// AutoPlay use void _autoPlay(bool autoPlay) { if (autoPlay) { eventChannel?.autoPlay(this); } } /// set video volume Future _setVolume(int volume) async { await _plugin?.setVolume(volume); } /// [pause] and [seekTo] 0 Future stop() async { // await _plugin?.stop(); // refreshVideoInfo(); await _plugin?.pause(); await _plugin?.seekTo(0); refreshVideoInfo(); } /// get system volume Future getSystemVolume() async { return IjkManager.getSystemVolume(); } /// set system volume Future setSystemVolume(int volume) async { await IjkManager.setSystemVolume(volume); } } /// about channel MethodChannel _globalChannel = MethodChannel("top.kikt/ijkplayer"); Future _createIjk() async { int id = await _globalChannel.invokeMethod("create"); return id; } class _IjkPlugin { MethodChannel get channel => MethodChannel("top.kikt/ijkplayer/$textureId"); /// texture id 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 { LogUtils.log("id = $textureId net uri = $uri"); await channel.invokeMethod("setNetworkDataSource", {"uri": uri}); } Future setAssetDataSource(String name, String package) async { LogUtils.log("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, }); LogUtils.log("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, }); } }