flutter_aliplayer/example/lib/util/aliyun_download_manager.dart

208 lines
8.0 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'package:flutter_aliplayer/flutter_alidownloader.dart';
import 'package:flutter_aliplayer/flutter_avpdef.dart';
import 'package:flutter_aliplayer_example/config.dart';
import 'package:flutter_aliplayer_example/model/custom_downloader_model.dart';
import 'package:flutter_aliplayer_example/util/database_utils.dart';
import 'package:path_provider/path_provider.dart';
class AliyunDownloadManager {
static AliyunDownloadManager _instance =
AliyunDownloadManager._privateConstructor();
FlutterAliDownloader _flutterAliDownloader;
DBUtils _dbUtils;
//下载保存地址
String _downloadSavePath;
//prepared集合
List<CustomDownloaderModel> _preparedList = List();
Map<String, StreamController> _controllerMap = Map();
static AliyunDownloadManager get instance {
return _instance;
}
AliyunDownloadManager._privateConstructor() {
_dbUtils = DBUtils.instance;
_flutterAliDownloader = FlutterAliDownloader.init();
if (Platform.isAndroid) {
getExternalStorageDirectories().then((value) {
if (value.length > 0) {
_downloadSavePath = value[0].path + "/download/";
return Directory(_downloadSavePath);
}
}).then((value) {
return value.exists();
}).then((value) {
if (!value) {
Directory directory = Directory(_downloadSavePath);
directory.create();
}
return _downloadSavePath;
}).then((value) {
_flutterAliDownloader.setSaveDir(_downloadSavePath);
});
} else if (Platform.isIOS) {
//TODO IOS
_flutterAliDownloader.setSaveDir('download');
}
}
///比较两个对象是否相等
bool _compareTo(CustomDownloaderModel src, CustomDownloaderModel dst) {
return src != null &&
dst != null &&
src.videoId == dst.videoId &&
src.vodDefinition == dst.vodDefinition;
}
Future<List<CustomDownloaderModel>> findAllDownload() {
return _dbUtils.selectAll().then((value) {
if (_preparedList.length > 0) {
_preparedList.clear();
}
value.forEach((element) {
CustomDownloaderModel customDownloaderModel =
CustomDownloaderModel.fromJson(element);
if (customDownloaderModel != null) {
if (customDownloaderModel.downloadState != DownloadState.COMPLETE) {
customDownloaderModel.downloadState = DownloadState.PREPARE;
customDownloaderModel.stateMsg = "准备完成";
}
_preparedList.add(customDownloaderModel);
}
});
return _preparedList;
});
}
Future<dynamic> prepare(Map map) {
return _flutterAliDownloader
.prepare(
map[DataSourceRelated.TYPE_KEY], map[DataSourceRelated.VID_KEY],
accessKeyId: map[DataSourceRelated.ACCESSKEYID_KEY],
accessKeySecret: map[DataSourceRelated.ACCESSKEYSECRET_KEY],
securityToken: map[DataSourceRelated.SECURITYTOKEN_KEY],
playAuth: map[DataSourceRelated.PLAYAUTH_KEY],
index: map[DataSourceRelated.INDEX_KEY])
.then((value) {
return value;
});
}
Future<dynamic> add(CustomDownloaderModel customDownloaderModel) async {
await Future.forEach(_preparedList, (element) {
if (_compareTo(element, customDownloaderModel)) {
return Future.error(
'${customDownloaderModel.videoId} , ${customDownloaderModel.vodDefinition} has added');
}
});
var json = customDownloaderModel.toJson();
_preparedList.add(customDownloaderModel);
_flutterAliDownloader.selectItem(
customDownloaderModel.videoId, customDownloaderModel.index);
_dbUtils.insert(json);
return Future.value(customDownloaderModel);
}
Stream<dynamic> start(CustomDownloaderModel customDownloaderModel) {
String key = customDownloaderModel.videoId +
'_' +
customDownloaderModel.index.toString();
StreamController _controller = _controllerMap[key];
if (_controller == null) {
_controller = StreamController<dynamic>();
_controllerMap.putIfAbsent(key, () => _controller);
}
StreamController<dynamic> _callbackController = StreamController();
StreamSink<dynamic> _sink = _callbackController.sink;
customDownloaderModel.downloadState = DownloadState.START;
_controller.addStream(_flutterAliDownloader.start(
customDownloaderModel.videoId, customDownloaderModel.index));
if (!_controller.hasListener) {
_controller.stream.listen((event) {
if (event[EventChanneldef.TYPE_KEY] ==
EventChanneldef.DOWNLOAD_PROGRESS &&
customDownloaderModel.videoId == event['vid'] &&
customDownloaderModel.index == event['index'] &&
customDownloaderModel.downloadState != DownloadState.STOP) {
//调用stop后,放置event时间消息继续发送,而导致其实已经停止了下载,但是界面还是在继续消费管道中的下载进度消息
customDownloaderModel.stateMsg =
event[EventChanneldef.DOWNLOAD_PROGRESS] + "%";
_sink.add(customDownloaderModel);
} else if (event[EventChanneldef.TYPE_KEY] ==
EventChanneldef.DOWNLOAD_PROCESS &&
customDownloaderModel.videoId == event['vid'] &&
customDownloaderModel.index == event['index']) {
customDownloaderModel.stateMsg = "ProcessingProgress \n" +
event[EventChanneldef.DOWNLOAD_PROGRESS] +
"%";
_sink.add(customDownloaderModel);
} else if (event[EventChanneldef.TYPE_KEY] ==
EventChanneldef.DOWNLOAD_COMPLETION &&
customDownloaderModel.videoId == event['vid'] &&
customDownloaderModel.index == event['index']) {
customDownloaderModel.downloadState = DownloadState.COMPLETE;
customDownloaderModel.stateMsg = "下载完成";
customDownloaderModel.savePath = event['savePath'];
_dbUtils.update(customDownloaderModel.toJson());
_sink.add(customDownloaderModel);
String key = customDownloaderModel.videoId +
'_' +
customDownloaderModel.index.toString();
_controllerMap.remove(key);
} else if (event[EventChanneldef.TYPE_KEY] ==
EventChanneldef.DOWNLOAD_ERROR &&
customDownloaderModel.videoId == event['vid'] &&
customDownloaderModel.index == event['index']) {
customDownloaderModel.downloadState = DownloadState.ERROR;
print(
"aliyun : download_error --- ${event['errorCode']} ------ ${event['errorMsg']}");
customDownloaderModel.stateMsg = event['errorMsg'];
_sink.add(customDownloaderModel);
}
});
}
return _callbackController.stream;
}
Future<dynamic> stop(CustomDownloaderModel customDownloaderModel) {
if (customDownloaderModel.downloadState == DownloadState.START ||
customDownloaderModel.downloadState == DownloadState.PREPARE) {
_flutterAliDownloader.stop(
customDownloaderModel.videoId, customDownloaderModel.index);
customDownloaderModel.downloadState = DownloadState.STOP;
customDownloaderModel.stateMsg = "暂停下载";
String key = customDownloaderModel.videoId +
'_' +
customDownloaderModel.index.toString();
_controllerMap.remove(key);
return Future.value(customDownloaderModel);
}
}
Future<dynamic> delete(CustomDownloaderModel customDownloaderModel) {
var map = customDownloaderModel.toJson();
_preparedList.remove(customDownloaderModel);
_dbUtils.delete(map);
_flutterAliDownloader.delete(
customDownloaderModel.videoId, customDownloaderModel.index);
_flutterAliDownloader.release(
customDownloaderModel.videoId, customDownloaderModel.index);
String key = customDownloaderModel.videoId +
'_' +
customDownloaderModel.index.toString();
_controllerMap.remove(key);
return Future.value(customDownloaderModel);
}
Future<dynamic> getFullSavePathForIOS(String savePath) {
return _flutterAliDownloader.getFullSaveForIOS(savePath);
}
}