|
@ -0,0 +1,36 @@
|
|||
gradlew
|
||||
gradlew.bat
|
||||
pubspec.lock
|
||||
local.properties
|
||||
.gradle/6.1.1/gc.properties
|
||||
.gradle/6.1.1/fileChanges/last-build.bin
|
||||
.gradle/6.1.1/fileHashes/fileHashes.lock
|
||||
.gradle/buildOutputCleanup/buildOutputCleanup.lock
|
||||
.gradle/buildOutputCleanup/cache.properties
|
||||
.gradle/checksums/checksums.lock
|
||||
.gradle/vcs-1/gc.properties
|
||||
.idea
|
||||
.idea/$CACHE_FILE$
|
||||
.idea/gradle.xml
|
||||
.idea/misc.xml
|
||||
.idea/modules.xml
|
||||
.idea/runConfigurations.xml
|
||||
.idea/vcs.xml
|
||||
.idea/caches/build_file_checksums.ser
|
||||
.idea/codeStyles/Project.xml
|
||||
.idea/libraries/Dart_Packages.xml
|
||||
.idea/libraries/Dart_SDK.xml
|
||||
.idea/libraries/Flutter_Plugins.xml
|
||||
.idea/modules/flutter_aliplayer.iml
|
||||
android/.idea/.name
|
||||
android/.idea/gradle.xml
|
||||
android/.idea/jarRepositories.xml
|
||||
android/.idea/misc.xml
|
||||
android/.idea/modules.xml
|
||||
android/.idea/vcs.xml
|
||||
android/.idea/caches/build_file_checksums.ser
|
||||
android/.idea/codeStyles/Project.xml
|
||||
gradle/wrapper/gradle-wrapper.jar
|
||||
gradle/wrapper/gradle-wrapper.properties
|
||||
.dart_tool/*
|
||||
.packages
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "flutter_aliplayer",
|
||||
"request": "launch",
|
||||
"type": "dart"
|
||||
},
|
||||
{
|
||||
"name": "example",
|
||||
"cwd": "example",
|
||||
"request": "launch",
|
||||
"type": "dart"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
## 5.5.6
|
||||
----------------------------------
|
||||
1. 更新播放器 SDK 至 5.5.6.0,并增加对应 SDK 接口
|
||||
2. Demo 增加水印,打点,缩略图,画中画等功能
|
||||
|
||||
## 5.4.10
|
||||
----------------------------------
|
||||
1. 修复 Android 创建 ListPlayer 出现错误日志问题
|
||||
2. 修复 Android 调用截图接口,在图片未完全保存到本地时,回调截图成功问题
|
||||
3. iOS 增加接口,用于下载后获取全路径
|
||||
4. AliPlayerView 增加 aliPlayerViewType 属性,用于指定渲染 View 的类型(仅对 Android 有效)
|
||||
5. Android 适配低版本 SDK 运行报错问题
|
||||
6. iOS 修改为本地集成播放器原生SDK
|
||||
|
||||
## 5.4.9-dev.1.3
|
||||
----------------------------------
|
||||
1. iOS 修改为本地集成播放器原生SDK
|
||||
|
||||
## 5.4.9-dev.1.2
|
||||
----------------------------------
|
||||
1. Android 适配低版本 SDK 运行报错问题
|
||||
|
||||
## 5.4.9-dev.1.1
|
||||
----------------------------------
|
||||
1. AliPlayerView 增加 aliPlayerViewType 属性,用于指定渲染 View 的类型(仅对 Android 有效)
|
||||
|
||||
## 5.4.9-dev.1.0
|
||||
----------------------------------
|
||||
1. 修复 Android 创建 ListPlayer 出现错误日志问题
|
||||
2. 修复 Android 调用截图接口,在图片未完全保存到本地时,回调截图成功问题
|
||||
3. iOS 增加接口,用于下载后获取全路径
|
||||
|
||||
## 5.4.9
|
||||
----------------------------------
|
||||
1. 更新播放器 SDK(更新 OpenSSL)
|
||||
2. 修复 Android 播放 hdr 视频问题
|
||||
3. 修复 Android、iOS 部分接口调用报错问题
|
||||
|
||||
## 5.4.8-dev.1.2
|
||||
----------------------------------
|
||||
1. 修复 Android 播放报错问题
|
||||
2. 修复 iOS 播放时,偶现 onInfo 没有回调的问题
|
||||
3. flutter 接口增加空类型支持
|
||||
|
||||
## 5.4.8-dev.1.0
|
||||
----------------------------------
|
||||
1. 更新 Anddroid、iOS播放器SDK为 5.4.8.0
|
||||
2. 移除 flutter_aliplayer_artc 和 flutter_rts,需要使用 Rts SDK,请自行在 Android、iOS 项目里添加依赖
|
||||
3. 新增接口
|
||||
## 5.4.3-dev.5
|
||||
----------------------------------
|
||||
1. 增加 Sei 、SubtitleHeader 接口调用
|
||||
2. 增加 FlutterAliPlayerFactory.loadRtsLibrary() 接口,(Android)
|
||||
3. 修复 5.4.2 编译报错问题
|
||||
4. 修复集成 Rts 低延时直播无法播放问题
|
||||
5. 修复 AliPlayer、AliListPlayer、AliLiveShiftPlayer 依次创建后,先创建的对象失效问题
|
||||
|
||||
## 5.4.2
|
||||
----------------------------------
|
||||
阿里云播放器版本更新至:5.4.2.0
|
||||
flutter_aliplayer_artc : ^5.4.2
|
||||
flutter_rts : ^1.9.0
|
||||
|
||||
1. 增加直播时移功能(测试中)
|
||||
2. 修复下载无法设置 region 问题
|
||||
3. 重复创建 AliPlayer 对象,导致先创建的 AliPlayer 对象回调监听失效问题
|
||||
|
||||
## 5.4.0
|
||||
----------------------------------
|
||||
阿里云播放器版本更新至:5.4.0
|
||||
flutter_aliplayer_artc : ^5.4.0
|
||||
flutter_rts : ^1.6.0
|
||||
|
||||
1. 支持多个播放实例,具体可以参照demo代码`multiple_player_page.dart`
|
||||
2. 播放器回调添加playerId参数,用于多实例调用的区分
|
||||
3. 添加`setPlayerView`方法,创建播放器后,需要绑定view到播发器
|
||||
4. 去除原列表播放器管道,在android和iOS源码层AliListPlayer与AliPlayer公用一个管道
|
||||
5. `initService`、`getSDKVersion`以及log级别开关等方法改为静态方法,与原生sdk对齐
|
||||
|
||||
## 5.2.2
|
||||
----------------------------------
|
||||
1. Docking Aliyun Player SDK (PlatForm include Android、iOS)
|
||||
2. RenderView: Android uses TextureView,iOS uses UIView
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
MIT LICENSE
|
||||
|
||||
Copyright (c) 2019-present Alibaba Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,404 @@
|
|||
# flutter_aliplayer
|
||||
|
||||
A new flutter plugin project , The project supports Android and iOS base on AliyunPlayerSDK
|
||||
[Android SDK URL](https://help.aliyun.com/document_detail/94328.html?spm=a2c4g.11186623.6.979.1d5c67b4gEmBvH)
|
||||
[iOS SDK URL](https://help.aliyun.com/document_detail/94428.html?spm=a2c4g.11186623.6.980.7fc22a88xOI4gc)
|
||||
|
||||
## Installation
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
flutter_aliplayer: ^{{latest version}}
|
||||
```
|
||||
|
||||
## 说明
|
||||
|
||||
flutter 播放器在原生层是基于 Android 播放器 SDK 和 iOS 播放器 SDK 的。可能部分原生播放器 SDK 的接口有遗漏,在 flutter 播放器插件中没有暴露出来。目前我们已将源码提供出来,开发者可以自行添加。也可以通知给我们,我们会对遗漏的接口进行补充。
|
||||
|
||||
## AliPlayer
|
||||
|
||||
### 1. 播放控制
|
||||
|
||||
```dart
|
||||
///1、创建播放器
|
||||
FlutterAliplayer fAliplayer = FlutterAliPlayerFactory.createAliPlayer();
|
||||
///多实例播放器创建方式,需要 flutter 层管理 playerId,其他接口一样,在播放器的回调中会返回对应的 playerId 来通知 flutter 层是哪一个播放器对象
|
||||
//FlutterAliplayer fAliplayer = FlutterAliPlayerFactory.createAliPlayer(playerId: playerId);
|
||||
|
||||
///2、设置监听,只列举了部分接口,更多接口可以参考播放器 Android\iOS 接口文档
|
||||
///准备成功
|
||||
fAliplayer.setOnPrepared((playerId) {});
|
||||
///首帧显示
|
||||
fAliplayer.setOnRenderingStart((playerId) {});
|
||||
///视频宽高变化
|
||||
fAliplayer.setOnVideoSizeChanged((width, height,playerId) {});
|
||||
///播放器状态变化
|
||||
fAliplayer.setOnStateChanged((newState,playerId) {});
|
||||
///加载状态
|
||||
fAliplayer.setOnLoadingStatusListener(
|
||||
loadingBegin: (playerId) {},
|
||||
loadingProgress: (percent, netSpeed,playerId) {},
|
||||
loadingEnd: (playerId) {});
|
||||
///拖动完成
|
||||
fAliplayer.setOnSeekComplete((playerId) {});
|
||||
///播放器事件信息回调,包括 buffer、当前播放进度 等等信息,根据 infoCode 来判断,对应 FlutterAvpdef.infoCode
|
||||
fAliplayer.setOnInfo((infoCode, extraValue, extraMsg,playerId) {});
|
||||
///播放完成
|
||||
fAliplayer.setOnCompletion((playerId) {});
|
||||
///设置流准备完成
|
||||
fAliplayer.setOnTrackReady((playerId) {});
|
||||
///截图结果
|
||||
fAliplayer.setOnSnapShot((path,playerId) {});
|
||||
///错误结果
|
||||
fAliplayer.setOnError((errorCode, errorExtra, errorMsg,playerId) {});
|
||||
///切换流变化
|
||||
fAliplayer.setOnTrackChanged((value,playerId) {});
|
||||
|
||||
///3、设置渲染的 View
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var x = 0.0;
|
||||
var y = 0.0;
|
||||
Orientation orientation = MediaQuery.of(context).orientation;
|
||||
var width = MediaQuery.of(context).size.width;
|
||||
|
||||
var height;
|
||||
if (orientation == Orientation.portrait) {
|
||||
height = width * 9.0 / 16.0;
|
||||
} else {
|
||||
height = MediaQuery.of(context).size.height;
|
||||
}
|
||||
AliPlayerView aliPlayerView = AliPlayerView(
|
||||
onCreated: onViewPlayerCreated,
|
||||
x: x,
|
||||
y: y,
|
||||
width: width,
|
||||
height: height);
|
||||
return OrientationBuilder(
|
||||
builder: (BuildContext context, Orientation orientation) {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
Container(
|
||||
color: Colors.black,
|
||||
child: aliPlayerView,
|
||||
width: width,
|
||||
height: height),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
///4、设置播放源
|
||||
///说明:STS 播放方式,vid、region、accessKeyId、accessKeySecret、securityToken 为必填,其他参数可选
|
||||
/// AUTH 播放方式,vid、region、playAuth 为必填,其他参数可选
|
||||
/// 每个 Map 对应的key 在 flutter 的 Demo 的 config.dart 中查看,fAliplayer 为播放器对象,如果还未创建,参考后续文档创建播放器
|
||||
void onViewPlayerCreated(viewId) async {
|
||||
///将 渲染 View 设置给播放器
|
||||
fAliplayer.setPlayerView(viewId);
|
||||
//设置播放源
|
||||
switch (_playMode) {
|
||||
//URL 播放方式
|
||||
case ModeType.URL:
|
||||
this.fAliplayer.setUrl(_dataSourceMap[DataSourceRelated.URL_KEY]);
|
||||
break;
|
||||
//STS 播放方式
|
||||
case ModeType.STS:
|
||||
this.fAliplayer.setVidSts(
|
||||
vid: _dataSourceMap[DataSourceRelated.VID_KEY],
|
||||
region: _dataSourceMap[DataSourceRelated.REGION_KEY],
|
||||
accessKeyId: _dataSourceMap[DataSourceRelated.ACCESSKEYID_KEY],
|
||||
accessKeySecret:
|
||||
_dataSourceMap[DataSourceRelated.ACCESSKEYSECRET_KEY],
|
||||
securityToken: _dataSourceMap[DataSourceRelated.SECURITYTOKEN_KEY],
|
||||
definitionList: _dataSourceMap[DataSourceRelated.DEFINITION_LIST],
|
||||
previewTime: _dataSourceMap[DataSourceRelated.PREVIEWTIME_KEY]);
|
||||
break;
|
||||
//AUTH 播放方式
|
||||
case ModeType.AUTH:
|
||||
this.fAliplayer.setVidAuth(
|
||||
vid: _dataSourceMap[DataSourceRelated.VID_KEY],
|
||||
region: _dataSourceMap[DataSourceRelated.REGION_KEY],
|
||||
playAuth: _dataSourceMap[DataSourceRelated.PLAYAUTH_KEY],
|
||||
definitionList: _dataSourceMap[DataSourceRelated.DEFINITION_LIST],
|
||||
previewTime: _dataSourceMap[DataSourceRelated.PREVIEWTIME_KEY]);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
///可选步骤:开启自动播放,默认关闭
|
||||
fAliplayer.setAutoPlay(true);
|
||||
///5、prepare
|
||||
fAliplayer.prepare();
|
||||
///说明:如果开启了自动播放,则调用 prepare 后即可,播放器在 prepare 成功后会自动播放,如果未开启自动播放,则需要在 setOnPrepard() 准备成功回调中,调用 fAliplayer.play() 开始播放
|
||||
|
||||
//暂停播放
|
||||
///暂停播放后,恢复播放直接调用 play 即可
|
||||
fAliplayer.pause();
|
||||
|
||||
//停止播放
|
||||
///停止播放后,恢复播放需要重新走一遍播放流程:prepare --> play
|
||||
fAliplayer.stop();
|
||||
|
||||
//销毁
|
||||
fAliplayer.release();
|
||||
|
||||
//seek
|
||||
///seekMode 可选值:FlutterAvpdef.ACCURATE(精准seek) 和 FlutterAvpdef.INACCURATE(非精准seek)
|
||||
fAliplayer.seek(position,seekMode);
|
||||
|
||||
//循环播放
|
||||
fAliplayer.setLoop(true);
|
||||
|
||||
//静音、音量控制
|
||||
fAliplayer.setMute(true);
|
||||
///设置播放器音量,范围0~1.
|
||||
fAliPlayer.setVolume(1);
|
||||
|
||||
//倍速播放
|
||||
///可选值:0.5,1.0,1.5,2.0
|
||||
fAliplayer.setRate(1.0);
|
||||
|
||||
//切换多码率,自动码率切换
|
||||
///在prepare成功之后,通过getMediaInfo可以获取到各个码流的信息,即TrackInfo
|
||||
fAliplayer.getMediaInfo().then((value) {
|
||||
//value 为 map,value['tracks'] 可以获取对应的 TrackInfos 列表信息,可以参考 Demo 中 AVPMediaInfo info = AVPMediaInfo.fromJson(value); 如何解析 TrackInfo
|
||||
};
|
||||
///在播放过程中,可以通过调用播放器的selectTrack方法切换播放的码流,参数为 TrackInfo 中的 trackIndex,切换的结果会在OnTrackChangedListener监听之后会回调
|
||||
fAliplayer.selectTrack(index);
|
||||
|
||||
///自动码率切换
|
||||
fAliplayer.selectTrack(-1);
|
||||
|
||||
//画面旋转、填充、镜像操作
|
||||
//设置画面的镜像模式:水平镜像,垂直镜像,无镜像。
|
||||
fAliplayer.setMirrorMode(FlutterAvpdef.AVP_MIRRORMODE_NONE);
|
||||
//设置画面旋转模式:旋转0度,90度,180度,270度
|
||||
fAliplayer.setRotateMode(FlutterAvpdef.AVP_ROTATE_0);
|
||||
//设置画面缩放模式:宽高比填充,宽高比适应,拉伸填充
|
||||
fAliplayer.setScalingMode(FlutterAvpdef.AVP_SCALINGMODE_SCALETOFILL);
|
||||
```
|
||||
|
||||
### 2. 边播边缓存
|
||||
|
||||
需要在 prepare 之前设置给播放器
|
||||
|
||||
```dart
|
||||
var map = {
|
||||
"mMaxSizeMB": _mMaxSizeMBController.text,///缓存目录的最大占用空间
|
||||
"mMaxDurationS": _mMaxDurationSController.text,///设置能够缓存的单个文件的最大时长
|
||||
"mDir": _mDirController.text,///缓存目录
|
||||
"mEnable": mEnableCacheConfig,///是否开启缓存功能
|
||||
};
|
||||
fAliplayer.setCacheConfig(map);
|
||||
```
|
||||
|
||||
### 3. 播放器其他配置
|
||||
|
||||
需要在 prepare 之前设置给播放器
|
||||
|
||||
```dart
|
||||
var configMap = {
|
||||
'mStartBufferDuration':_mStartBufferDurationController.text,///起播缓冲区时长
|
||||
'mHighBufferDuratio':_mHighBufferDurationController.text,///高缓冲时长
|
||||
'mMaxBufferDuration':_mMaxBufferDurationController.text,///最大缓冲区时长
|
||||
'mMaxDelayTime': _mMaxDelayTimeController.text,///最大延迟。注意:直播有效
|
||||
'mNetworkTimeout': _mNetworkTimeoutController.text,///网络超时时间
|
||||
'mNetworkRetryCount':_mNetworkRetryCountController.text,///网络重试次数
|
||||
'mMaxProbeSize': _mMaxProbeSizeController.text,///最大probe大小
|
||||
'mReferrer': _mReferrerController.text,///referrer
|
||||
'mHttpProxy': _mHttpProxyController.text,///http代理
|
||||
'mEnableSEI': mEnableSEI,///是否启用SEI
|
||||
'mClearFrameWhenStop': !mShowFrameWhenStop,///停止后是否清空画面
|
||||
'mDisableVideo': mDisableVideo,///禁用Video
|
||||
'mDisableAudio': mDisableAudio///禁用Audio
|
||||
};
|
||||
widget.fAliplayer.setConfig(configMap);
|
||||
```
|
||||
|
||||
## AliListPlayer
|
||||
|
||||
```dart
|
||||
//1.创建列表播放器
|
||||
FlutterAliListPlayer fAliListPlayer = FlutterAliPlayerFactory.createAliListPlayer();
|
||||
|
||||
//2.添加资源、移除资源。列表播放器目前只支持两种播放方式,URL 和 STS
|
||||
///uid是视频的唯一标志。用于区分视频是否一样。如果uid一样,则认为是一样的
|
||||
fAliListPlayer.addUrlSource(url,uid);
|
||||
fAliListPlayer.addVidSource(vid,uid);
|
||||
fAliListPlayer.removeSource(uid);
|
||||
|
||||
//设置预加载个数
|
||||
fAliListPlayer.setPreloadCount(count);
|
||||
|
||||
//播放视频源
|
||||
///uid 为必填项,如果是 URL 播放方式,只需要 uid 即可,如果是 STS 方式,则需要填写 STS 信息
|
||||
fAliListPlayer.moveTo();
|
||||
```
|
||||
|
||||
## AliLiveShiftPlayer
|
||||
|
||||
```dart
|
||||
//创建直播时移播放器
|
||||
FlutterAliLiveShiftPlayer _flutterAliLiveShiftPlayer = FlutterAliPlayerFactory.createAliLiveShiftPlayer();
|
||||
|
||||
//设置渲染 View
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var x = 0.0;
|
||||
var y = 0.0;
|
||||
Orientation orientation = MediaQuery.of(context).orientation;
|
||||
var width = MediaQuery.of(context).size.width;
|
||||
|
||||
var height;
|
||||
if (orientation == Orientation.portrait) {
|
||||
height = width * 9.0 / 16.0;
|
||||
} else {
|
||||
height = MediaQuery.of(context).size.height;
|
||||
}
|
||||
AliPlayerView aliPlayerView = AliPlayerView(
|
||||
onCreated: onViewPlayerCreated,
|
||||
x: x,
|
||||
y: y,
|
||||
width: width,
|
||||
height: height);
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Plugin for LiveShiftPlayer'),
|
||||
),
|
||||
body: Column(children: [
|
||||
Container(
|
||||
width: width,
|
||||
height: height,
|
||||
child: aliPlayerView,
|
||||
),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
///setPlayerView(viewId) 给播放器设置渲染 View
|
||||
///setDataSource(timelineUrl,url) 设置播放源,其中 url 为播放地址,timelineurl 为时移请求地址
|
||||
void onViewPlayerCreated(int viewId) {
|
||||
this._flutterAliLiveShiftPlayer.setPlayerView(viewId);
|
||||
int time = (new DateTime.now().millisecondsSinceEpoch / 1000).round();
|
||||
var timeLineUrl =
|
||||
"$_timeLineUrl&lhs_start_unix_s_0=${time - 5 * 60}&lhs_end_unix_s_0=${time + 5 * 60}";
|
||||
_flutterAliLiveShiftPlayer.setDataSource(timeLineUrl, _url);
|
||||
}
|
||||
}
|
||||
|
||||
///时移到某个时间
|
||||
_flutterAliLiveShiftPlayer.seekToLiveTime();
|
||||
|
||||
///获取当前直播的播放时间
|
||||
flutterAliLiveShiftPlayer.getCurrentTime().then((value) {});
|
||||
|
||||
///获取当前直播的现实时间
|
||||
_flutterAliLiveShiftPlayer.getCurrentLiveTime().then((value) {});
|
||||
|
||||
///准备
|
||||
_flutterAliLiveShiftPlayer.prepare();
|
||||
|
||||
///开始播放
|
||||
_flutterAliLiveShiftPlayer.play();
|
||||
|
||||
///停止
|
||||
_flutterAliLiveShiftPlayer?.stop();
|
||||
///销毁
|
||||
_flutterAliLiveShiftPlayer?.destroy();
|
||||
|
||||
///时移seek完成通知。playerTime:实际播放的时间
|
||||
_flutterAliLiveShiftPlayer.setOnSeekLiveCompletion(playTime, playerId) {});
|
||||
|
||||
//时移时间更新监听事件。currentTime - 当前现实时间,shiftStartTime - 可时移的起始时间,shiftEndTime - 可时移的结束时间
|
||||
_flutterAliLiveShiftPlayer.setOnTimeShiftUpdater((currentTime, shiftStartTime, shiftEndTime, playerId) {});
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 下载
|
||||
|
||||
可选步骤,如果是安全下载,需要配置自己的加密校验文件到 SDK 中,普通下载则不需要
|
||||
|
||||
```dart
|
||||
//配置加密校验文件,尽可能提前配置(可选)
|
||||
FlutterAliPlayerFactory.initService(byteData);
|
||||
|
||||
//创建下载器
|
||||
FlutterAliDownloader donwloader = FlutterAliDownloader.init();
|
||||
///设置保存路径
|
||||
donwloader.setSaveDir(path)
|
||||
|
||||
//开始下载
|
||||
///1.prepare
|
||||
///参数说明:type 可选值为 FlutterAvpdef.DOWNLOADTYPE_STS / FlutterAvpdef.DOWNLOADTYPE_AUTH 。当 type 为 DOWNLOADTYPE_STS 时候,必填参数为: {vid,accessKeyId,accessKeySecret,securityToken},当 type 为 DOWNLOADTYPE_AUTH 时,必须填参数为 {vid,playAuth}
|
||||
downloader.prepare(type, vid).then((value) {
|
||||
//value 为 map,对应 Demo 中的 DownloadModel 自定义下载类
|
||||
DownloadModel downloadModel = DownloadModel.fromJson(value);
|
||||
//2.selectItem,根据不同的 trackInfo 来确定需要下载哪个清晰度
|
||||
List<TrackInfoModel> trackInfos = downloadModel.trackInfos;
|
||||
downloader.selectItem(vid,trackInfos[0].index);
|
||||
//3.start
|
||||
downloader.start(vid, trackInfos[0].index).listen((event) {
|
||||
//说明:event 可能会有多种信息,可参考 FlutterAvpdef.EventChanneldef 中的信息,以下为具体说明:
|
||||
if (event[EventChanneldef.TYPE_KEY] == EventChanneldef.DOWNLOAD_PROGRESS){
|
||||
//下载进度百分比信息,获取下载进度百分比:event[EventChanneldef.DOWNLOAD_PROGRESS]
|
||||
}else if(event[EventChanneldef.TYPE_KEY] == EventChanneldef.DOWNLOAD_PROCESS){
|
||||
//处理进度百分比信息,获取处理进度百分比:event[EventChanneldef.DOWNLOAD_PROCESS]
|
||||
}else if(event[EventChanneldef.TYPE_KEY] == EventChanneldef.DOWNLOAD_COMPLETION){
|
||||
//下载完成,可以通过 event['vid']、event['index'] 获取对应的 vid 和 index 用于判断是哪个视频下载完成,event['savePath'] 用于获取下载完成视频的本地路径
|
||||
|
||||
// 'savePath'在iOS中是相对路径,每次进行播放时可以通过调用getFullSaveForIOS('savePath')进行获取全路径,保证路径获取的正确性,安卓直接使用就可以
|
||||
if (Platform.isIOS) {
|
||||
donwloader.getFullSavePathForIOS(event['savePath']).then((value) {
|
||||
// value是最新的全路径,可以拿这个路径去播放
|
||||
});
|
||||
}
|
||||
}else if(event[EventChanneldef.TYPE_KEY] == EventChanneldef.DOWNLOAD_ERROR){
|
||||
//下载失败,可以通过 event['vid']、event['index'] 获取对应的 vid 和 index 用于判断是哪个视频下载失败,event['errorCode']、event['errorMsg'] 可以获取对应的错误码,和错误信息
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//停止下载、删除和释放
|
||||
downloader.stop(vid, index)
|
||||
//可以删除下载的本地文件
|
||||
downloader.delete(vid, index)
|
||||
downloader.release(vid, index)
|
||||
```
|
||||
|
||||
## 加载 RtsSDK
|
||||
如果需要支持 artc 协议,首先需要引入如下两个插件:
|
||||
```yaml
|
||||
//flutter_aliplayer_artc: 对应版本号
|
||||
//flutter_aliplayer_rts: 对应版本号
|
||||
|
||||
```
|
||||
|
||||
Android 在build.gradle中添加依赖即可
|
||||
```
|
||||
dependencies{
|
||||
implementation 'com.aliyun.sdk.android:AlivcArtc:$version'
|
||||
implementation 'com.aliyun.rts.android:RtsSDK:$version'
|
||||
}
|
||||
```
|
||||
|
||||
iOS在Podfile文件中添加依赖即可
|
||||
```
|
||||
target 'Runner' do
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
|
||||
pod 'AliPlayerSDK_iOS_ARTC', '$version' #$version比如5.4.9.1
|
||||
pod 'RtsSDK', '$version' #$version比如2.5.0
|
||||
|
||||
end
|
||||
```
|
||||
|
||||
|
||||
Android 需要额外调用如下代码(尽可能提前):
|
||||
```dart
|
||||
FlutterAliPlayerFactory.loadRtsLibrary();
|
||||
```
|
|
@ -0,0 +1,8 @@
|
|||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
|
@ -0,0 +1,52 @@
|
|||
group 'com.alibaba.fplayer.flutter_aliplayer'
|
||||
version '1.0'
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version='1.6.10'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
maven { url "https://maven.aliyun.com/nexus/content/repositories/releases" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
maven { url "https://maven.aliyun.com/nexus/content/repositories/releases" }
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 31
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
}
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
}
|
||||
|
||||
buildTypes{
|
||||
debug {
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
|
||||
release {
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.aliyun.sdk.android:AliyunPlayer:5.5.6.0-full'
|
||||
implementation 'com.google.code.gson:gson:2.8.6'
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
org.gradle.jvmargs=-Xmx1536M
|
||||
android.enableR8=true
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
|
@ -0,0 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
|
|
@ -0,0 +1 @@
|
|||
rootProject.name = 'flutter_aliplayer'
|
|
@ -0,0 +1,3 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.alibaba.fplayer.flutter_aliplayer">
|
||||
</manifest>
|
|
@ -0,0 +1,413 @@
|
|||
package com.alibaba.fplayer.flutter_aliplayer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.aliyun.downloader.AliDownloaderFactory;
|
||||
import com.aliyun.downloader.AliMediaDownloader;
|
||||
import com.aliyun.downloader.DownloaderConfig;
|
||||
import com.aliyun.player.bean.ErrorInfo;
|
||||
import com.aliyun.player.nativeclass.MediaInfo;
|
||||
import com.aliyun.player.source.VidAuth;
|
||||
import com.aliyun.player.source.VidSts;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin;
|
||||
import io.flutter.plugin.common.EventChannel;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
import com.aliyun.player.nativeclass.TrackInfo;
|
||||
|
||||
public class FlutterAliDownloader implements FlutterPlugin, MethodChannel.MethodCallHandler, EventChannel.StreamHandler {
|
||||
|
||||
private static final String SEPARA_SYMBOLS = "_";
|
||||
private MethodChannel mMethodChannel;
|
||||
private EventChannel mEventChannel;
|
||||
private EventChannel.EventSink mEventSink;
|
||||
private Context mContext;
|
||||
private String mSavePath;
|
||||
private Map<String, AliMediaDownloader> mAliMediaDownloadMap = new HashMap<>();
|
||||
|
||||
public FlutterAliDownloader(Context context, FlutterPlugin.FlutterPluginBinding flutterPluginBinding) {
|
||||
this.mContext = context;
|
||||
this.mMethodChannel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "plugins.flutter_alidownload");
|
||||
this.mEventChannel = new EventChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "plugins.flutter_alidownload_event");
|
||||
this.mEventChannel.setStreamHandler(this);
|
||||
this.mMethodChannel.setMethodCallHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodCall(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) {
|
||||
switch (methodCall.method) {
|
||||
case "create":
|
||||
createMediaDownloader();
|
||||
break;
|
||||
case "prepare": {
|
||||
Map<String, Object> prepareMap = (Map<String, Object>) methodCall.arguments;
|
||||
Integer index = (Integer) prepareMap.get("index");
|
||||
String type = (String) prepareMap.get("type");
|
||||
String vid = (String) prepareMap.get("vid");
|
||||
String region = (String) prepareMap.get("region");
|
||||
if (type != null && type.equals("download_sts")) {
|
||||
VidSts vidSts = new VidSts();
|
||||
vidSts.setVid(vid);
|
||||
vidSts.setRegion(region);
|
||||
vidSts.setAccessKeyId((String) prepareMap.get("accessKeyId"));
|
||||
vidSts.setAccessKeySecret((String) prepareMap.get("accessKeySecret"));
|
||||
vidSts.setSecurityToken((String) prepareMap.get("securityToken"));
|
||||
if (index == null) {
|
||||
prepare(vidSts, result);
|
||||
} else {
|
||||
prepare(vidSts, index, result);
|
||||
}
|
||||
|
||||
} else if (type != null && type.equals("download_auth")) {
|
||||
VidAuth vidAuth = new VidAuth();
|
||||
vidAuth.setVid(vid);
|
||||
vidAuth.setRegion(region);
|
||||
vidAuth.setPlayAuth((String) prepareMap.get("playAuth"));
|
||||
if (index == null) {
|
||||
prepare(vidAuth, result);
|
||||
} else {
|
||||
prepare(vidAuth, index, result);
|
||||
}
|
||||
}
|
||||
// result.success(null);
|
||||
}
|
||||
break;
|
||||
case "setSaveDir": {
|
||||
mSavePath = (String) methodCall.arguments;
|
||||
result.success(null);
|
||||
}
|
||||
break;
|
||||
case "selectItem": {
|
||||
Map<String, Object> selectItem = (Map<String, Object>) methodCall.arguments;
|
||||
String videoId = (String) selectItem.get("vid");
|
||||
Integer index = (Integer) selectItem.get("index");
|
||||
if (mAliMediaDownloadMap.containsKey(videoId)) {
|
||||
AliMediaDownloader aliMediaDownloader = mAliMediaDownloadMap.get(videoId);
|
||||
if (aliMediaDownloader != null) {
|
||||
mAliMediaDownloadMap.remove(videoId);
|
||||
mAliMediaDownloadMap.put(videoId + SEPARA_SYMBOLS + index, aliMediaDownloader);
|
||||
selectItem(aliMediaDownloader, index);
|
||||
}
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
break;
|
||||
case "start": {
|
||||
Map<String, Object> startMap = (Map<String, Object>) methodCall.arguments;
|
||||
String videoId = (String) startMap.get("vid");
|
||||
Integer index = (Integer) startMap.get("index");
|
||||
AliMediaDownloader aliMediaDownloader = mAliMediaDownloadMap.get(videoId + SEPARA_SYMBOLS + index);
|
||||
if (aliMediaDownloader != null) {
|
||||
aliMediaDownloader.setSaveDir(mSavePath);
|
||||
start(aliMediaDownloader, startMap);
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
break;
|
||||
case "stop": {
|
||||
Map<String, Object> stopMap = (Map<String, Object>) methodCall.arguments;
|
||||
String videoId = (String) stopMap.get("vid");
|
||||
Integer index = (Integer) stopMap.get("index");
|
||||
AliMediaDownloader aliMediaDownloader = mAliMediaDownloadMap.get(videoId + SEPARA_SYMBOLS + index);
|
||||
if (aliMediaDownloader != null) {
|
||||
stop(aliMediaDownloader);
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
break;
|
||||
case "delete": {
|
||||
Map<String, Object> deleteMap = (Map<String, Object>) methodCall.arguments;
|
||||
String videoId = (String) deleteMap.get("vid");
|
||||
Integer index = (Integer) deleteMap.get("index");
|
||||
AliMediaDownloader aliMediaDownloader = mAliMediaDownloadMap.get(videoId + SEPARA_SYMBOLS + index);
|
||||
if (aliMediaDownloader != null) {
|
||||
delete(aliMediaDownloader);
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
break;
|
||||
case "getFilePath": {
|
||||
Map<String, Object> getFilePathMap = (Map<String, Object>) methodCall.arguments;
|
||||
String videoId = (String) getFilePathMap.get("vid");
|
||||
Integer index = (Integer) getFilePathMap.get("index");
|
||||
AliMediaDownloader aliMediaDownloader = mAliMediaDownloadMap.get(videoId + SEPARA_SYMBOLS + index);
|
||||
if (aliMediaDownloader != null) {
|
||||
String filePath = getFilePath(aliMediaDownloader);
|
||||
getFilePathMap.put("savePath", filePath);
|
||||
result.success(filePath);
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
break;
|
||||
case "release": {
|
||||
Map<String, Object> releasMap = (Map<String, Object>) methodCall.arguments;
|
||||
String videoId = (String) releasMap.get("vid");
|
||||
Integer index = (Integer) releasMap.get("index");
|
||||
AliMediaDownloader aliMediaDownloader = mAliMediaDownloadMap.remove(videoId + SEPARA_SYMBOLS + index);
|
||||
if (aliMediaDownloader != null) {
|
||||
release(aliMediaDownloader);
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
break;
|
||||
case "updateSource": {
|
||||
Map<String, Object> updateSourceMap = (Map<String, Object>) methodCall.arguments;
|
||||
Integer index = (Integer) updateSourceMap.get("index");
|
||||
String type = (String) updateSourceMap.get("type");
|
||||
String vid = (String) updateSourceMap.get("vid");
|
||||
String region = (String) updateSourceMap.get("region");
|
||||
AliMediaDownloader aliMediaDownloader = mAliMediaDownloadMap.remove(vid + SEPARA_SYMBOLS + index);
|
||||
if (aliMediaDownloader != null) {
|
||||
if (type != null && type.equals("download_sts")) {
|
||||
VidSts vidSts = new VidSts();
|
||||
vidSts.setVid(vid);
|
||||
vidSts.setRegion(region);
|
||||
vidSts.setAccessKeyId((String) updateSourceMap.get("accessKeyId"));
|
||||
vidSts.setAccessKeySecret((String) updateSourceMap.get("accessKeySecret"));
|
||||
vidSts.setSecurityToken((String) updateSourceMap.get("securityToken"));
|
||||
updateSource(aliMediaDownloader, vidSts);
|
||||
|
||||
} else if (type != null && type.equals("download_auth")) {
|
||||
VidAuth vidAuth = new VidAuth();
|
||||
vidAuth.setVid(vid);
|
||||
vidAuth.setRegion(region);
|
||||
vidAuth.setPlayAuth((String) updateSourceMap.get("playAuth"));
|
||||
updateSource(aliMediaDownloader, vidAuth);
|
||||
}
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
break;
|
||||
case "setDownloaderConfig": {
|
||||
Map<String, Object> downloadConfigMap = (Map<String, Object>) methodCall.arguments;
|
||||
String videoId = (String) downloadConfigMap.get("vid");
|
||||
Integer index = (Integer) downloadConfigMap.get("index");
|
||||
AliMediaDownloader aliMediaDownloader = mAliMediaDownloadMap.remove(videoId + SEPARA_SYMBOLS + index);
|
||||
if (aliMediaDownloader != null) {
|
||||
DownloaderConfig downloaderConfig = new DownloaderConfig();
|
||||
String mUserAgent = (String) downloadConfigMap.get("UserAgent");
|
||||
downloaderConfig.mUserAgent = TextUtils.isEmpty(mUserAgent) ? "" : mUserAgent;
|
||||
|
||||
String mReferrer = (String) downloadConfigMap.get("Referrer");
|
||||
downloaderConfig.mReferrer = TextUtils.isEmpty(mReferrer) ? "" : mReferrer;
|
||||
|
||||
String mHttpProxy = (String) downloadConfigMap.get("HttpProxy");
|
||||
downloaderConfig.mHttpProxy = TextUtils.isEmpty(mHttpProxy) ? "" : mHttpProxy;
|
||||
|
||||
Integer mConnectTimeoutS = (Integer) downloadConfigMap.get("ConnectTimeoutS");
|
||||
downloaderConfig.mConnectTimeoutS = mConnectTimeoutS == null ? 0 : mConnectTimeoutS;
|
||||
|
||||
Integer mNetworkTimeoutMs = (Integer) downloadConfigMap.get("NetworkTimeoutMs");
|
||||
downloaderConfig.mNetworkTimeoutMs = mNetworkTimeoutMs == null ? 0 : mNetworkTimeoutMs;
|
||||
|
||||
setDownloaderConfig(aliMediaDownloader, downloaderConfig);
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListen(Object arguments, EventChannel.EventSink events) {
|
||||
this.mEventSink = events;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(Object arguments) {
|
||||
}
|
||||
|
||||
private void createMediaDownloader() {
|
||||
AliMediaDownloader aliMediaDownloader = AliDownloaderFactory.create(mContext);
|
||||
}
|
||||
|
||||
private void prepare(VidAuth vidAuth, final int index, final MethodChannel.Result result) {
|
||||
AliMediaDownloader aliMediaDownloader = AliDownloaderFactory.create(mContext);
|
||||
mAliMediaDownloadMap.put(vidAuth.getVid(), aliMediaDownloader);
|
||||
final AliMediaDownloader finalAliMediaDownloader = aliMediaDownloader;
|
||||
aliMediaDownloader.setOnPreparedListener(new AliMediaDownloader.OnPreparedListener() {
|
||||
@Override
|
||||
public void onPrepared(MediaInfo mediaInfo) {
|
||||
Gson gson = new Gson();
|
||||
String mediaInfoJson = gson.toJson(mediaInfo);
|
||||
finalAliMediaDownloader.selectItem(index);
|
||||
mAliMediaDownloadMap.put(mediaInfo.getVideoId() + SEPARA_SYMBOLS + index, finalAliMediaDownloader);
|
||||
result.success(mediaInfoJson);
|
||||
}
|
||||
});
|
||||
|
||||
aliMediaDownloader.setOnErrorListener(new AliMediaDownloader.OnErrorListener() {
|
||||
@Override
|
||||
public void onError(ErrorInfo errorInfo) {
|
||||
result.error(errorInfo.getCode().toString(), errorInfo.getMsg(), errorInfo.getExtra());
|
||||
}
|
||||
});
|
||||
aliMediaDownloader.prepare(vidAuth);
|
||||
}
|
||||
|
||||
private void prepare(VidAuth vidAuth, final MethodChannel.Result result) {
|
||||
AliMediaDownloader aliMediaDownloader = AliDownloaderFactory.create(mContext);
|
||||
mAliMediaDownloadMap.put(vidAuth.getVid(), aliMediaDownloader);
|
||||
aliMediaDownloader.setOnPreparedListener(new AliMediaDownloader.OnPreparedListener() {
|
||||
@Override
|
||||
public void onPrepared(MediaInfo mediaInfo) {
|
||||
Gson gson = new Gson();
|
||||
String mediaInfoJson = gson.toJson(mediaInfo);
|
||||
List<TrackInfo> trackInfos = mediaInfo.getTrackInfos();
|
||||
result.success(mediaInfoJson);
|
||||
}
|
||||
});
|
||||
|
||||
aliMediaDownloader.setOnErrorListener(new AliMediaDownloader.OnErrorListener() {
|
||||
@Override
|
||||
public void onError(ErrorInfo errorInfo) {
|
||||
result.error(errorInfo.getCode().toString(), errorInfo.getMsg(), errorInfo.getExtra());
|
||||
}
|
||||
});
|
||||
|
||||
aliMediaDownloader.prepare(vidAuth);
|
||||
}
|
||||
|
||||
private void prepare(VidSts vidSts, final int index, final MethodChannel.Result result) {
|
||||
AliMediaDownloader aliMediaDownloader = AliDownloaderFactory.create(mContext);
|
||||
mAliMediaDownloadMap.put(vidSts.getVid(), aliMediaDownloader);
|
||||
final AliMediaDownloader finalAliMediaDownloader = aliMediaDownloader;
|
||||
aliMediaDownloader.setOnPreparedListener(new AliMediaDownloader.OnPreparedListener() {
|
||||
@Override
|
||||
public void onPrepared(MediaInfo mediaInfo) {
|
||||
Gson gson = new Gson();
|
||||
String mediaInfoJson = gson.toJson(mediaInfo);
|
||||
finalAliMediaDownloader.selectItem(index);
|
||||
mAliMediaDownloadMap.put(mediaInfo.getVideoId() + SEPARA_SYMBOLS + index, finalAliMediaDownloader);
|
||||
result.success(mediaInfoJson);
|
||||
}
|
||||
});
|
||||
|
||||
aliMediaDownloader.setOnErrorListener(new AliMediaDownloader.OnErrorListener() {
|
||||
@Override
|
||||
public void onError(ErrorInfo errorInfo) {
|
||||
result.error(errorInfo.getCode().toString(), errorInfo.getMsg(), errorInfo.getExtra());
|
||||
}
|
||||
});
|
||||
aliMediaDownloader.prepare(vidSts);
|
||||
}
|
||||
|
||||
private void prepare(VidSts vidSts, final MethodChannel.Result result) {
|
||||
AliMediaDownloader aliMediaDownloader = AliDownloaderFactory.create(mContext);
|
||||
mAliMediaDownloadMap.put(vidSts.getVid(), aliMediaDownloader);
|
||||
aliMediaDownloader.setOnPreparedListener(new AliMediaDownloader.OnPreparedListener() {
|
||||
@Override
|
||||
public void onPrepared(MediaInfo mediaInfo) {
|
||||
Gson gson = new Gson();
|
||||
String mediaInfoJson = gson.toJson(mediaInfo);
|
||||
result.success(mediaInfoJson);
|
||||
}
|
||||
});
|
||||
|
||||
aliMediaDownloader.setOnErrorListener(new AliMediaDownloader.OnErrorListener() {
|
||||
@Override
|
||||
public void onError(ErrorInfo errorInfo) {
|
||||
result.error(errorInfo.getCode().toString(), errorInfo.getMsg(), errorInfo.getExtra());
|
||||
}
|
||||
});
|
||||
|
||||
aliMediaDownloader.prepare(vidSts);
|
||||
}
|
||||
|
||||
private void start(final AliMediaDownloader aliMediaDownloader, final Map<String, Object> startMap) {
|
||||
aliMediaDownloader.setOnErrorListener(new AliMediaDownloader.OnErrorListener() {
|
||||
@Override
|
||||
public void onError(ErrorInfo errorInfo) {
|
||||
startMap.put("method", "download_error");
|
||||
startMap.put("errorCode", errorInfo.getCode() + "");
|
||||
startMap.put("errorMsg", errorInfo.getMsg());
|
||||
mEventSink.success(startMap);
|
||||
}
|
||||
});
|
||||
|
||||
aliMediaDownloader.setOnProgressListener(new AliMediaDownloader.OnProgressListener() {
|
||||
@Override
|
||||
public void onDownloadingProgress(int i) {
|
||||
startMap.put("method", "download_progress");
|
||||
startMap.put("download_progress", i + "");
|
||||
mEventSink.success(startMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProcessingProgress(int i) {
|
||||
startMap.put("method", "download_process");
|
||||
startMap.put("download_process", i + "");
|
||||
mEventSink.success(startMap);
|
||||
}
|
||||
});
|
||||
|
||||
aliMediaDownloader.setOnCompletionListener(new AliMediaDownloader.OnCompletionListener() {
|
||||
@Override
|
||||
public void onCompletion() {
|
||||
startMap.put("method", "download_completion");
|
||||
startMap.put("savePath", aliMediaDownloader.getFilePath());
|
||||
mEventSink.success(startMap);
|
||||
}
|
||||
});
|
||||
aliMediaDownloader.start();
|
||||
}
|
||||
|
||||
private void selectItem(AliMediaDownloader aliMediaDownloader, int index) {
|
||||
aliMediaDownloader.selectItem(index);
|
||||
}
|
||||
|
||||
private void stop(AliMediaDownloader aliMediaDownloader) {
|
||||
aliMediaDownloader.stop();
|
||||
}
|
||||
|
||||
private void delete(AliMediaDownloader aliMediaDownloader) {
|
||||
|
||||
aliMediaDownloader.deleteFile();
|
||||
}
|
||||
|
||||
private void release(AliMediaDownloader aliMediaDownloader) {
|
||||
aliMediaDownloader.release();
|
||||
}
|
||||
|
||||
private void setSaveDir(AliMediaDownloader aliMediaDownloader, String path) {
|
||||
aliMediaDownloader.setSaveDir(path);
|
||||
}
|
||||
|
||||
private String getFilePath(AliMediaDownloader aliMediaDownloader) {
|
||||
return aliMediaDownloader.getFilePath();
|
||||
}
|
||||
|
||||
private void updateSource(AliMediaDownloader aliMediaDownloader, VidSts vidSts) {
|
||||
aliMediaDownloader.updateSource(vidSts);
|
||||
}
|
||||
|
||||
private void updateSource(AliMediaDownloader aliMediaDownloader, VidAuth vidAuth) {
|
||||
aliMediaDownloader.updateSource(vidAuth);
|
||||
}
|
||||
|
||||
private void setDownloaderConfig(AliMediaDownloader aliMediaDownloader, DownloaderConfig downloaderConfig) {
|
||||
aliMediaDownloader.setDownloaderConfig(downloaderConfig);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
package com.alibaba.fplayer.flutter_aliplayer;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.os.Build;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class FlutterAliFloatWindowManager {
|
||||
|
||||
private final WindowManager mWindowManager;
|
||||
private final DisplayMetrics mDisplayMetrics;
|
||||
private final WindowManager.LayoutParams mLayoutParams;
|
||||
private final SurfaceView mSurfaceView;
|
||||
private Context mContext;
|
||||
private FlutterAliPlayerView mCurrentView;
|
||||
private Boolean isMove = false;
|
||||
private int lastX;
|
||||
private int lastY;
|
||||
private int paramX;
|
||||
private int paramY;
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
public FlutterAliFloatWindowManager(Context context) {
|
||||
this.mContext = context;
|
||||
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
|
||||
mDisplayMetrics = mContext.getResources().getDisplayMetrics();
|
||||
mLayoutParams = new WindowManager.LayoutParams(350, 450, 0, 0, PixelFormat.TRANSPARENT);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||
} else {
|
||||
mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
|
||||
}
|
||||
// layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
||||
// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||
// | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
|
||||
mLayoutParams.format = PixelFormat.RGBA_8888; //窗口透明
|
||||
// layoutParams.gravity = Gravity.END | Gravity.BOTTOM;
|
||||
mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||
mLayoutParams.x = mDisplayMetrics.widthPixels - 100;
|
||||
mLayoutParams.y = mDisplayMetrics.heightPixels - 100;
|
||||
|
||||
mSurfaceView = new SurfaceView(context);
|
||||
mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
|
||||
@Override
|
||||
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
|
||||
if (mCurrentView != null) {
|
||||
mCurrentView.getPlayer().setDisplay(surfaceHolder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
|
||||
if (mCurrentView != null) {
|
||||
mCurrentView.getPlayer().surfaceChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
mSurfaceView.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||
switch (motionEvent.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
lastX = (int) motionEvent.getRawX();
|
||||
lastY = (int) motionEvent.getRawY();
|
||||
paramX = mLayoutParams.x;
|
||||
paramY = mLayoutParams.y;
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
int dx = (int) motionEvent.getRawX() - lastX;
|
||||
int dy = (int) motionEvent.getRawY() - lastY;
|
||||
mLayoutParams.x = paramX + dx;
|
||||
mLayoutParams.y = paramY + dy;
|
||||
mWindowManager.updateViewLayout(mSurfaceView, mLayoutParams);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void showFloatWindow(FlutterAliPlayerView flutterAliPlayerView) {
|
||||
this.mCurrentView = flutterAliPlayerView;
|
||||
mWindowManager.addView(mSurfaceView, mLayoutParams);
|
||||
}
|
||||
|
||||
public void hideFloatWindow() {
|
||||
if (mSurfaceView != null) {
|
||||
mWindowManager.removeView(mSurfaceView);
|
||||
}
|
||||
if (mCurrentView != null) {
|
||||
mCurrentView.sendSetRenderViewMessage();
|
||||
mCurrentView = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,819 @@
|
|||
package com.alibaba.fplayer.flutter_aliplayer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.aliyun.player.AliListPlayer;
|
||||
import com.aliyun.player.AliPlayerFactory;
|
||||
import com.aliyun.player.IPlayer;
|
||||
import com.aliyun.player.bean.ErrorInfo;
|
||||
import com.aliyun.player.bean.InfoBean;
|
||||
import com.aliyun.player.nativeclass.CacheConfig;
|
||||
import com.aliyun.player.nativeclass.MediaInfo;
|
||||
import com.aliyun.player.nativeclass.PlayerConfig;
|
||||
import com.aliyun.player.nativeclass.Thumbnail;
|
||||
import com.aliyun.player.nativeclass.TrackInfo;
|
||||
import com.aliyun.player.source.StsInfo;
|
||||
import com.aliyun.player.source.UrlSource;
|
||||
import com.aliyun.player.source.VidAuth;
|
||||
import com.aliyun.player.source.VidMps;
|
||||
import com.aliyun.player.source.VidSts;
|
||||
import com.aliyun.thumbnail.ThumbnailBitmapInfo;
|
||||
import com.aliyun.thumbnail.ThumbnailHelper;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin;
|
||||
import io.flutter.plugin.common.EventChannel;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
public class FlutterAliListPlayer extends FlutterPlayerBase implements EventChannel.StreamHandler {
|
||||
|
||||
private FlutterPlugin.FlutterPluginBinding mFlutterPluginBinding;
|
||||
|
||||
private final Gson mGson;
|
||||
private Context mContext;
|
||||
private EventChannel.EventSink mEventSink;
|
||||
private EventChannel mEventChannel;
|
||||
private AliListPlayer mAliListPlayer;
|
||||
private ThumbnailHelper mThumbnailHelper;
|
||||
private Map<Integer, FlutterAliPlayerView> mFlutterAliPlayerViewMap;
|
||||
|
||||
public FlutterAliListPlayer(FlutterPlugin.FlutterPluginBinding flutterPluginBinding) {
|
||||
this.mFlutterPluginBinding = flutterPluginBinding;
|
||||
this.mContext = flutterPluginBinding.getApplicationContext();
|
||||
mGson = new Gson();
|
||||
mAliListPlayer = AliPlayerFactory.createAliListPlayer(flutterPluginBinding.getApplicationContext());
|
||||
// MethodChannel mAliListPlayerMethodChannel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(),"flutter_alilistplayer");
|
||||
// mAliListPlayerMethodChannel.setMethodCallHandler(this);
|
||||
mEventChannel = new EventChannel(mFlutterPluginBinding.getFlutterEngine().getDartExecutor(), "flutter_aliplayer_event");
|
||||
mEventChannel.setStreamHandler(this);
|
||||
initListener(mAliListPlayer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListen(Object arguments, EventChannel.EventSink events) {
|
||||
this.mEventSink = events;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(Object arguments) {
|
||||
}
|
||||
|
||||
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
|
||||
switch (methodCall.method) {
|
||||
case "setPreloadCount":
|
||||
Integer count = (Integer) methodCall.argument("arg");
|
||||
setPreloadCount(count);
|
||||
result.success(null);
|
||||
break;
|
||||
case "setPlayerView":
|
||||
// Integer viewId = (Integer) methodCall.argument("arg");
|
||||
// FlutterAliPlayerView flutterAliPlayerView = mFlutterAliPlayerViewMap.get(viewId);
|
||||
// if(flutterAliPlayerView != null){
|
||||
// flutterAliPlayerView.setPlayer(mAliListPlayer);
|
||||
// }
|
||||
break;
|
||||
case "prepare":
|
||||
prepare();
|
||||
result.success(null);
|
||||
break;
|
||||
case "play":
|
||||
start();
|
||||
result.success(null);
|
||||
break;
|
||||
case "pause":
|
||||
pause();
|
||||
result.success(null);
|
||||
break;
|
||||
case "stop":
|
||||
stop();
|
||||
result.success(null);
|
||||
break;
|
||||
case "destroy":
|
||||
release();
|
||||
result.success(null);
|
||||
break;
|
||||
case "getCurrentUid":
|
||||
result.success(getCurrentUid());
|
||||
break;
|
||||
case "seekTo": {
|
||||
Map<String, Object> seekToMap = (Map<String, Object>) methodCall.argument("arg");
|
||||
Integer position = (Integer) seekToMap.get("position");
|
||||
Integer seekMode = (Integer) seekToMap.get("seekMode");
|
||||
seekTo(position, seekMode);
|
||||
result.success(null);
|
||||
}
|
||||
break;
|
||||
case "setMaxPreloadMemorySizeMB":
|
||||
Integer maxPreloadMemoryMB = methodCall.argument("arg");
|
||||
setMaxPreloadMemorySizeMB(maxPreloadMemoryMB);
|
||||
result.success(null);
|
||||
break;
|
||||
case "getMediaInfo": {
|
||||
MediaInfo mediaInfo = getMediaInfo();
|
||||
if (mediaInfo != null) {
|
||||
Map<String, Object> getMediaInfoMap = new HashMap<>();
|
||||
getMediaInfoMap.put("title", mediaInfo.getTitle());
|
||||
getMediaInfoMap.put("status", mediaInfo.getStatus());
|
||||
getMediaInfoMap.put("mediaType", mediaInfo.getMediaType());
|
||||
getMediaInfoMap.put("duration", mediaInfo.getDuration());
|
||||
getMediaInfoMap.put("transcodeMode", mediaInfo.getTransCodeMode());
|
||||
getMediaInfoMap.put("coverURL", mediaInfo.getCoverUrl());
|
||||
List<Thumbnail> thumbnail = mediaInfo.getThumbnailList();
|
||||
List<Map<String, Object>> thumbailList = new ArrayList<>();
|
||||
for (Thumbnail thumb : thumbnail) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("url", thumb.mURL);
|
||||
thumbailList.add(map);
|
||||
getMediaInfoMap.put("thumbnails", thumbailList);
|
||||
}
|
||||
List<TrackInfo> trackInfos = mediaInfo.getTrackInfos();
|
||||
List<Map<String, Object>> trackInfoList = new ArrayList<>();
|
||||
for (TrackInfo trackInfo : trackInfos) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("vodFormat", trackInfo.getVodFormat());
|
||||
map.put("videoHeight", trackInfo.getVideoHeight());
|
||||
map.put("videoWidth", trackInfo.getVideoHeight());
|
||||
map.put("subtitleLanguage", trackInfo.getSubtitleLang());
|
||||
map.put("trackBitrate", trackInfo.getVideoBitrate());
|
||||
map.put("vodFileSize", trackInfo.getVodFileSize());
|
||||
map.put("trackIndex", trackInfo.getIndex());
|
||||
map.put("trackDefinition", trackInfo.getVodDefinition());
|
||||
map.put("audioSampleFormat", trackInfo.getAudioSampleFormat());
|
||||
map.put("audioLanguage", trackInfo.getAudioLang());
|
||||
map.put("vodPlayUrl", trackInfo.getVodPlayUrl());
|
||||
map.put("trackType", trackInfo.getType().ordinal());
|
||||
map.put("audioSamplerate", trackInfo.getAudioSampleRate());
|
||||
map.put("audioChannels", trackInfo.getAudioChannels());
|
||||
trackInfoList.add(map);
|
||||
getMediaInfoMap.put("tracks", trackInfoList);
|
||||
}
|
||||
result.success(getMediaInfoMap);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "snapshot":
|
||||
mSnapShotPath = methodCall.argument("arg").toString();
|
||||
snapshot();
|
||||
result.success(null);
|
||||
break;
|
||||
case "setLoop":
|
||||
setLoop((Boolean) methodCall.argument("arg"));
|
||||
result.success(null);
|
||||
break;
|
||||
case "isLoop":
|
||||
result.success(isLoop());
|
||||
break;
|
||||
case "setAutoPlay":
|
||||
setAutoPlay((Boolean) methodCall.argument("arg"));
|
||||
result.success(null);
|
||||
break;
|
||||
case "isAutoPlay":
|
||||
result.success(isAutoPlay());
|
||||
break;
|
||||
case "setMuted":
|
||||
setMuted((Boolean) methodCall.argument("arg"));
|
||||
result.success(null);
|
||||
break;
|
||||
case "isMuted":
|
||||
result.success(isMuted());
|
||||
break;
|
||||
case "setEnableHardwareDecoder":
|
||||
Boolean setEnableHardwareDecoderArgumnt = (Boolean) methodCall.argument("arg");
|
||||
setEnableHardWareDecoder(setEnableHardwareDecoderArgumnt);
|
||||
result.success(null);
|
||||
break;
|
||||
case "setScalingMode":
|
||||
setScaleMode((Integer) methodCall.argument("arg"));
|
||||
result.success(null);
|
||||
break;
|
||||
case "getScalingMode":
|
||||
result.success(getScaleMode());
|
||||
break;
|
||||
case "setMirrorMode":
|
||||
setMirrorMode((Integer) methodCall.argument("arg"));
|
||||
result.success(null);
|
||||
break;
|
||||
case "getMirrorMode":
|
||||
result.success(getMirrorMode());
|
||||
break;
|
||||
case "setRotateMode":
|
||||
setRotateMode((Integer) methodCall.argument("arg"));
|
||||
result.success(null);
|
||||
break;
|
||||
case "getRotateMode":
|
||||
result.success(getRotateMode());
|
||||
break;
|
||||
case "setRate":
|
||||
setSpeed((Double) methodCall.argument("arg"));
|
||||
result.success(null);
|
||||
break;
|
||||
case "getRate":
|
||||
result.success(getSpeed());
|
||||
break;
|
||||
case "setVideoBackgroundColor":
|
||||
setVideoBackgroundColor((Integer) methodCall.argument("arg"));
|
||||
result.success(null);
|
||||
break;
|
||||
case "setVolume":
|
||||
setVolume((Double) methodCall.argument("arg"));
|
||||
result.success(null);
|
||||
break;
|
||||
case "getVolume":
|
||||
result.success(getVolume());
|
||||
break;
|
||||
case "setConfig": {
|
||||
Map<String, Object> setConfigMap = (Map<String, Object>) methodCall.argument("arg");
|
||||
PlayerConfig config = getConfig();
|
||||
if (config != null) {
|
||||
String configJson = mGson.toJson(setConfigMap);
|
||||
config = mGson.fromJson(configJson, PlayerConfig.class);
|
||||
setConfig(config);
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
break;
|
||||
case "getConfig":
|
||||
PlayerConfig config = getConfig();
|
||||
String json = mGson.toJson(config);
|
||||
Map<String, Object> configMap = mGson.fromJson(json, Map.class);
|
||||
result.success(configMap);
|
||||
break;
|
||||
case "getCacheConfig":
|
||||
CacheConfig cacheConfig = getCacheConfig();
|
||||
String cacheConfigJson = mGson.toJson(cacheConfig);
|
||||
Map<String, Object> cacheConfigMap = mGson.fromJson(cacheConfigJson, Map.class);
|
||||
result.success(cacheConfigMap);
|
||||
break;
|
||||
case "setCacheConfig":
|
||||
Map<String, Object> setCacheConnfigMap = (Map<String, Object>) methodCall.argument("arg");
|
||||
String setCacheConfigJson = mGson.toJson(setCacheConnfigMap);
|
||||
CacheConfig setCacheConfig = mGson.fromJson(setCacheConfigJson, CacheConfig.class);
|
||||
setCacheConfig(setCacheConfig);
|
||||
result.success(null);
|
||||
break;
|
||||
case "getCurrentTrack":
|
||||
Integer currentTrackIndex = (Integer) methodCall.argument("arg");
|
||||
TrackInfo currentTrack = getCurrentTrack(currentTrackIndex);
|
||||
if (currentTrack != null) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("vodFormat", currentTrack.getVodFormat());
|
||||
map.put("videoHeight", currentTrack.getVideoHeight());
|
||||
map.put("videoWidth", currentTrack.getVideoHeight());
|
||||
map.put("subtitleLanguage", currentTrack.getSubtitleLang());
|
||||
map.put("trackBitrate", currentTrack.getVideoBitrate());
|
||||
map.put("vodFileSize", currentTrack.getVodFileSize());
|
||||
map.put("trackIndex", currentTrack.getIndex());
|
||||
map.put("trackDefinition", currentTrack.getVodDefinition());
|
||||
map.put("audioSampleFormat", currentTrack.getAudioSampleFormat());
|
||||
map.put("audioLanguage", currentTrack.getAudioLang());
|
||||
map.put("vodPlayUrl", currentTrack.getVodPlayUrl());
|
||||
map.put("trackType", currentTrack.getType().ordinal());
|
||||
map.put("audioSamplerate", currentTrack.getAudioSampleRate());
|
||||
map.put("audioChannels", currentTrack.getAudioChannels());
|
||||
result.success(map);
|
||||
}
|
||||
break;
|
||||
case "selectTrack":
|
||||
Map<String, Object> selectTrackMap = (Map<String, Object>) methodCall.argument("arg");
|
||||
Integer trackIdx = (Integer) selectTrackMap.get("trackIdx");
|
||||
Integer accurate = (Integer) selectTrackMap.get("accurate");
|
||||
selectTrack(trackIdx, accurate == 1);
|
||||
result.success(null);
|
||||
break;
|
||||
case "addExtSubtitle":
|
||||
String extSubtitlUrl = (String) methodCall.arguments;
|
||||
addExtSubtitle(extSubtitlUrl);
|
||||
result.success(null);
|
||||
break;
|
||||
case "selectExtSubtitle":
|
||||
Map<String, Object> selectExtSubtitleMap = (Map<String, Object>) methodCall.argument("arg");
|
||||
Integer trackIndex = (Integer) selectExtSubtitleMap.get("trackIndex");
|
||||
Boolean selectExtSubtitlEnable = (Boolean) selectExtSubtitleMap.get("enable");
|
||||
selectExtSubtitle(trackIndex, selectExtSubtitlEnable);
|
||||
result.success(null);
|
||||
break;
|
||||
case "addVidSource":
|
||||
Map<String, Object> addVidSourceMap = methodCall.argument("arg");
|
||||
String addSourceVid = (String) addVidSourceMap.get("vid");
|
||||
String vidUid = (String) addVidSourceMap.get("uid");
|
||||
addVidSource(addSourceVid, vidUid);
|
||||
result.success(null);
|
||||
break;
|
||||
case "addUrlSource":
|
||||
Map<String, Object> addSourceUrlMap = methodCall.argument("arg");
|
||||
String addSourceUrl = (String) addSourceUrlMap.get("url");
|
||||
String urlUid = (String) addSourceUrlMap.get("uid");
|
||||
addUrlSource(addSourceUrl, urlUid);
|
||||
result.success(null);
|
||||
break;
|
||||
case "removeSource":
|
||||
String removeUid = methodCall.arguments();
|
||||
removeSource(removeUid);
|
||||
result.success(null);
|
||||
break;
|
||||
case "clear":
|
||||
clear();
|
||||
result.success(null);
|
||||
break;
|
||||
case "moveToNext":
|
||||
Map<String, Object> moveToNextMap = methodCall.argument("arg");
|
||||
String moveToNextAccessKeyId = (String) moveToNextMap.get("accId");
|
||||
String moveToNextAccessKeySecret = (String) moveToNextMap.get("accKey");
|
||||
String moveToNextSecurityToken = (String) moveToNextMap.get("token");
|
||||
String moveToNextRegion = (String) moveToNextMap.get("region");
|
||||
if (TextUtils.isEmpty(moveToNextAccessKeyId)
|
||||
|| TextUtils.isEmpty(moveToNextAccessKeySecret) || TextUtils.isEmpty(moveToNextSecurityToken)) {
|
||||
moveToNext(null);
|
||||
} else {
|
||||
StsInfo moveToNextStsInfo = new StsInfo();
|
||||
moveToNextStsInfo.setAccessKeyId(moveToNextAccessKeyId);
|
||||
moveToNextStsInfo.setAccessKeySecret(moveToNextAccessKeySecret);
|
||||
moveToNextStsInfo.setSecurityToken(moveToNextSecurityToken);
|
||||
moveToNextStsInfo.setRegion(moveToNextRegion);
|
||||
moveToNext(moveToNextStsInfo);
|
||||
}
|
||||
|
||||
result.success(null);
|
||||
break;
|
||||
case "moveToPre":
|
||||
Map<String, Object> moveToPreMap = methodCall.argument("arg");
|
||||
String moveToPreAccessKeyId = (String) moveToPreMap.get("accId");
|
||||
String moveToPreAccessKeySecret = (String) moveToPreMap.get("accKey");
|
||||
String moveToPreSecurityToken = (String) moveToPreMap.get("token");
|
||||
String moveToPreRegion = (String) moveToPreMap.get("region");
|
||||
if (TextUtils.isEmpty(moveToPreAccessKeyId) || TextUtils.isEmpty(moveToPreAccessKeySecret)
|
||||
|| TextUtils.isEmpty(moveToPreSecurityToken) || TextUtils.isEmpty(moveToPreRegion)) {
|
||||
moveToPre(null);
|
||||
} else {
|
||||
StsInfo moveToPreStsInfo = new StsInfo();
|
||||
moveToPreStsInfo.setAccessKeyId(moveToPreAccessKeyId);
|
||||
moveToPreStsInfo.setAccessKeySecret(moveToPreAccessKeySecret);
|
||||
moveToPreStsInfo.setSecurityToken(moveToPreSecurityToken);
|
||||
moveToPreStsInfo.setRegion(moveToPreRegion);
|
||||
moveToPre(moveToPreStsInfo);
|
||||
}
|
||||
result.success(null);
|
||||
break;
|
||||
case "moveTo":
|
||||
Map<String, Object> moveToMap = methodCall.argument("arg");
|
||||
String moveToAccessKeyId = (String) moveToMap.get("accId");
|
||||
String moveToAccessKeySecret = (String) moveToMap.get("accKey");
|
||||
String moveToSecurityToken = (String) moveToMap.get("token");
|
||||
String moveToRegion = (String) moveToMap.get("region");
|
||||
String moveToUid = (String) moveToMap.get("uid");
|
||||
if (!TextUtils.isEmpty(moveToAccessKeyId)) {
|
||||
StsInfo moveToStsInfo = new StsInfo();
|
||||
moveToStsInfo.setAccessKeyId(moveToAccessKeyId);
|
||||
moveToStsInfo.setAccessKeySecret(moveToAccessKeySecret);
|
||||
moveToStsInfo.setSecurityToken(moveToSecurityToken);
|
||||
moveToStsInfo.setRegion(moveToRegion);
|
||||
moveTo(moveToUid, moveToStsInfo);
|
||||
} else {
|
||||
moveTo(moveToUid);
|
||||
}
|
||||
result.success(null);
|
||||
|
||||
break;
|
||||
case "createThumbnailHelper":
|
||||
String thhumbnailUrl = (String) methodCall.argument("arg");
|
||||
createThumbnailHelper(thhumbnailUrl);
|
||||
result.success(null);
|
||||
break;
|
||||
case "requestBitmapAtPosition":
|
||||
Integer requestBitmapProgress = (Integer) methodCall.argument("arg");
|
||||
requestBitmapAtPosition(requestBitmapProgress);
|
||||
result.success(null);
|
||||
break;
|
||||
default:
|
||||
result.notImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
public IPlayer getAliPlayer() {
|
||||
return mAliListPlayer;
|
||||
}
|
||||
|
||||
private void setPreloadCount(int count) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.setPreloadCount(count);
|
||||
}
|
||||
}
|
||||
|
||||
private void setDataSource(String url) {
|
||||
if (mAliListPlayer != null) {
|
||||
UrlSource urlSource = new UrlSource();
|
||||
urlSource.setUri(url);
|
||||
mAliListPlayer.setDataSource(urlSource);
|
||||
}
|
||||
}
|
||||
|
||||
private void setDataSource(VidSts vidSts) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.setDataSource(vidSts);
|
||||
}
|
||||
}
|
||||
|
||||
private void setDataSource(VidAuth vidAuth) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.setDataSource(vidAuth);
|
||||
}
|
||||
}
|
||||
|
||||
private void setDataSource(VidMps vidMps) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.setDataSource(vidMps);
|
||||
}
|
||||
}
|
||||
|
||||
private String getCurrentUid() {
|
||||
return mAliListPlayer.getCurrentUid();
|
||||
}
|
||||
|
||||
private void prepare() {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.prepare();
|
||||
}
|
||||
}
|
||||
|
||||
private void start() {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.start();
|
||||
}
|
||||
}
|
||||
|
||||
private void pause() {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.pause();
|
||||
}
|
||||
}
|
||||
|
||||
private void stop() {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void release() {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.release();
|
||||
mAliListPlayer = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void seekTo(long position, int seekMode) {
|
||||
if (mAliListPlayer != null) {
|
||||
IPlayer.SeekMode mSeekMode;
|
||||
if (seekMode == IPlayer.SeekMode.Accurate.getValue()) {
|
||||
mSeekMode = IPlayer.SeekMode.Accurate;
|
||||
} else {
|
||||
mSeekMode = IPlayer.SeekMode.Inaccurate;
|
||||
}
|
||||
mAliListPlayer.seekTo(position, mSeekMode);
|
||||
}
|
||||
}
|
||||
|
||||
private MediaInfo getMediaInfo() {
|
||||
if (mAliListPlayer != null) {
|
||||
return mAliListPlayer.getMediaInfo();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void snapshot() {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.snapshot();
|
||||
}
|
||||
}
|
||||
|
||||
private void setLoop(Boolean isLoop) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.setLoop(isLoop);
|
||||
}
|
||||
}
|
||||
|
||||
private Boolean isLoop() {
|
||||
return mAliListPlayer != null && mAliListPlayer.isLoop();
|
||||
}
|
||||
|
||||
private void setAutoPlay(Boolean isAutoPlay) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.setAutoPlay(isAutoPlay);
|
||||
}
|
||||
}
|
||||
|
||||
private Boolean isAutoPlay() {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.isAutoPlay();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setMuted(Boolean muted) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.setMute(muted);
|
||||
}
|
||||
}
|
||||
|
||||
private Boolean isMuted() {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.isMute();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setEnableHardWareDecoder(Boolean mEnableHardwareDecoder) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.enableHardwareDecoder(mEnableHardwareDecoder);
|
||||
}
|
||||
}
|
||||
|
||||
private void setScaleMode(int model) {
|
||||
if (mAliListPlayer != null) {
|
||||
IPlayer.ScaleMode mScaleMode = IPlayer.ScaleMode.SCALE_ASPECT_FIT;
|
||||
if (model == IPlayer.ScaleMode.SCALE_ASPECT_FIT.getValue()) {
|
||||
mScaleMode = IPlayer.ScaleMode.SCALE_ASPECT_FIT;
|
||||
} else if (model == IPlayer.ScaleMode.SCALE_ASPECT_FILL.getValue()) {
|
||||
mScaleMode = IPlayer.ScaleMode.SCALE_ASPECT_FILL;
|
||||
} else if (model == IPlayer.ScaleMode.SCALE_TO_FILL.getValue()) {
|
||||
mScaleMode = IPlayer.ScaleMode.SCALE_TO_FILL;
|
||||
}
|
||||
mAliListPlayer.setScaleMode(mScaleMode);
|
||||
}
|
||||
}
|
||||
|
||||
private int getScaleMode() {
|
||||
int scaleMode = IPlayer.ScaleMode.SCALE_ASPECT_FIT.getValue();
|
||||
if (mAliListPlayer != null) {
|
||||
scaleMode = mAliListPlayer.getScaleMode().getValue();
|
||||
}
|
||||
return scaleMode;
|
||||
}
|
||||
|
||||
private void setMirrorMode(int mirrorMode) {
|
||||
if (mAliListPlayer != null) {
|
||||
IPlayer.MirrorMode mMirrorMode;
|
||||
if (mirrorMode == IPlayer.MirrorMode.MIRROR_MODE_HORIZONTAL.getValue()) {
|
||||
mMirrorMode = IPlayer.MirrorMode.MIRROR_MODE_HORIZONTAL;
|
||||
} else if (mirrorMode == IPlayer.MirrorMode.MIRROR_MODE_VERTICAL.getValue()) {
|
||||
mMirrorMode = IPlayer.MirrorMode.MIRROR_MODE_VERTICAL;
|
||||
} else {
|
||||
mMirrorMode = IPlayer.MirrorMode.MIRROR_MODE_NONE;
|
||||
}
|
||||
mAliListPlayer.setMirrorMode(mMirrorMode);
|
||||
}
|
||||
}
|
||||
|
||||
private int getMirrorMode() {
|
||||
int mirrorMode = IPlayer.MirrorMode.MIRROR_MODE_NONE.getValue();
|
||||
if (mAliListPlayer != null) {
|
||||
mirrorMode = mAliListPlayer.getMirrorMode().getValue();
|
||||
}
|
||||
return mirrorMode;
|
||||
}
|
||||
|
||||
private void setRotateMode(int rotateMode) {
|
||||
if (mAliListPlayer != null) {
|
||||
IPlayer.RotateMode mRotateMode;
|
||||
if (rotateMode == IPlayer.RotateMode.ROTATE_90.getValue()) {
|
||||
mRotateMode = IPlayer.RotateMode.ROTATE_90;
|
||||
} else if (rotateMode == IPlayer.RotateMode.ROTATE_180.getValue()) {
|
||||
mRotateMode = IPlayer.RotateMode.ROTATE_180;
|
||||
} else if (rotateMode == IPlayer.RotateMode.ROTATE_270.getValue()) {
|
||||
mRotateMode = IPlayer.RotateMode.ROTATE_270;
|
||||
} else {
|
||||
mRotateMode = IPlayer.RotateMode.ROTATE_0;
|
||||
}
|
||||
mAliListPlayer.setRotateMode(mRotateMode);
|
||||
}
|
||||
}
|
||||
|
||||
private int getRotateMode() {
|
||||
int rotateMode = IPlayer.RotateMode.ROTATE_0.getValue();
|
||||
if (mAliListPlayer != null) {
|
||||
rotateMode = mAliListPlayer.getRotateMode().getValue();
|
||||
}
|
||||
return rotateMode;
|
||||
}
|
||||
|
||||
private void setSpeed(double speed) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.setSpeed((float) speed);
|
||||
}
|
||||
}
|
||||
|
||||
private double getSpeed() {
|
||||
double speed = 0;
|
||||
if (mAliListPlayer != null) {
|
||||
speed = mAliListPlayer.getSpeed();
|
||||
}
|
||||
return speed;
|
||||
}
|
||||
|
||||
private void setVideoBackgroundColor(int color) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.setVideoBackgroundColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
private void setVolume(double volume) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.setVolume((float) volume);
|
||||
}
|
||||
}
|
||||
|
||||
private double getVolume() {
|
||||
double volume = 1.0;
|
||||
if (mAliListPlayer != null) {
|
||||
volume = mAliListPlayer.getVolume();
|
||||
}
|
||||
return volume;
|
||||
}
|
||||
|
||||
private void setConfig(PlayerConfig playerConfig) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.setConfig(playerConfig);
|
||||
}
|
||||
}
|
||||
|
||||
private PlayerConfig getConfig() {
|
||||
if (mAliListPlayer != null) {
|
||||
return mAliListPlayer.getConfig();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private CacheConfig getCacheConfig() {
|
||||
return new CacheConfig();
|
||||
}
|
||||
|
||||
private void setCacheConfig(CacheConfig cacheConfig) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.setCacheConfig(cacheConfig);
|
||||
}
|
||||
}
|
||||
|
||||
private TrackInfo getCurrentTrack(int currentTrackIndex) {
|
||||
if (mAliListPlayer != null) {
|
||||
return mAliListPlayer.currentTrack(currentTrackIndex);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void selectTrack(int trackId, boolean accurate) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.selectTrack(trackId, accurate);
|
||||
}
|
||||
}
|
||||
|
||||
private void addExtSubtitle(String url) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.addExtSubtitle(url);
|
||||
}
|
||||
}
|
||||
|
||||
private void selectExtSubtitle(int trackIndex, boolean enable) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.selectExtSubtitle(trackIndex, enable);
|
||||
}
|
||||
}
|
||||
|
||||
private void createThumbnailHelper(String url) {
|
||||
mThumbnailHelper = new ThumbnailHelper(url);
|
||||
mThumbnailHelper.setOnPrepareListener(new ThumbnailHelper.OnPrepareListener() {
|
||||
@Override
|
||||
public void onPrepareSuccess() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "thumbnail_onPrepared_Success");
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareFail() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "thumbnail_onPrepared_Fail");
|
||||
mEventSink.success(map);
|
||||
}
|
||||
});
|
||||
|
||||
mThumbnailHelper.setOnThumbnailGetListener(new ThumbnailHelper.OnThumbnailGetListener() {
|
||||
@Override
|
||||
public void onThumbnailGetSuccess(long l, ThumbnailBitmapInfo thumbnailBitmapInfo) {
|
||||
if (thumbnailBitmapInfo != null && thumbnailBitmapInfo.getThumbnailBitmap() != null) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
|
||||
Bitmap thumbnailBitmap = thumbnailBitmapInfo.getThumbnailBitmap();
|
||||
if(thumbnailBitmap != null){
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
thumbnailBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
|
||||
thumbnailBitmap.recycle();
|
||||
long[] positionRange = thumbnailBitmapInfo.getPositionRange();
|
||||
|
||||
map.put("method", "onThumbnailGetSuccess");
|
||||
map.put("thumbnailbitmap", stream.toByteArray());
|
||||
map.put("thumbnailRange", positionRange);
|
||||
mEventSink.success(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onThumbnailGetFail(long l, String s) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onThumbnailGetFail");
|
||||
mEventSink.success(map);
|
||||
}
|
||||
});
|
||||
mThumbnailHelper.prepare();
|
||||
}
|
||||
|
||||
private void requestBitmapAtPosition(int position) {
|
||||
if (mThumbnailHelper != null) {
|
||||
mThumbnailHelper.requestBitmapAtPosition(position);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* =========================================================
|
||||
*/
|
||||
|
||||
private void addVidSource(String vid, String uid) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.addVid(vid, uid);
|
||||
}
|
||||
}
|
||||
|
||||
private void addUrlSource(String url, String uid) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.addUrl(url, uid);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeSource(String uid) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.removeSource(uid);
|
||||
}
|
||||
}
|
||||
|
||||
private void clear() {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void setMaxPreloadMemorySizeMB(Integer maxPreloadMemoryMB) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.setMaxPreloadMemorySizeMB(maxPreloadMemoryMB);
|
||||
}
|
||||
}
|
||||
|
||||
private void moveToNext(StsInfo stsInfo) {
|
||||
if (mAliListPlayer != null) {
|
||||
if (stsInfo == null) {
|
||||
mAliListPlayer.moveToNext();
|
||||
} else {
|
||||
mAliListPlayer.moveToNext(stsInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void moveToPre(StsInfo stsInfo) {
|
||||
if (mAliListPlayer != null) {
|
||||
if (stsInfo == null) {
|
||||
mAliListPlayer.moveToPrev();
|
||||
} else {
|
||||
mAliListPlayer.moveToPrev(stsInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void moveTo(String uid, StsInfo stsInfo) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.moveTo(uid, stsInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private void moveTo(String uid) {
|
||||
if (mAliListPlayer != null) {
|
||||
mAliListPlayer.moveTo(uid);
|
||||
}
|
||||
}
|
||||
|
||||
public void setViewMap(Map<Integer, FlutterAliPlayerView> flutterAliPlayerViewMap) {
|
||||
this.mFlutterAliPlayerViewMap = flutterAliPlayerViewMap;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package com.alibaba.fplayer.flutter_aliplayer;
|
||||
|
||||
import com.aliyun.player.AliLiveShiftPlayer;
|
||||
import com.aliyun.player.AliPlayerFactory;
|
||||
import com.aliyun.player.IPlayer;
|
||||
import com.aliyun.player.source.LiveShift;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
public class FlutterAliLiveShiftPlayer extends FlutterPlayerBase{
|
||||
|
||||
private final AliLiveShiftPlayer mAliLiveShiftPlayer;
|
||||
|
||||
public FlutterAliLiveShiftPlayer(FlutterPlugin.FlutterPluginBinding flutterPluginBinding, String playerId) {
|
||||
this.mPlayerId = playerId;
|
||||
this.mContext = flutterPluginBinding.getApplicationContext();
|
||||
mAliLiveShiftPlayer = AliPlayerFactory.createAliLiveShiftPlayer(mContext);
|
||||
initListener(mAliLiveShiftPlayer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPlayer getAliPlayer() {
|
||||
return mAliLiveShiftPlayer;
|
||||
}
|
||||
|
||||
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
|
||||
switch (methodCall.method) {
|
||||
case "getCurrentLiveTime":
|
||||
result.success(getCurrentLiveTime());
|
||||
break;
|
||||
case "getCurrentTime":
|
||||
result.success(getCurrentTime());
|
||||
break;
|
||||
case "seekToLiveTime":
|
||||
int seekToLiveTime = methodCall.argument("arg");
|
||||
seekToLiveTime(seekToLiveTime);
|
||||
result.success(null);
|
||||
break;
|
||||
case "setDataSource":
|
||||
Map<String,Object> dataSourceMap = (Map<String,Object>)methodCall.argument("arg");
|
||||
LiveShift liveShift = new LiveShift();
|
||||
liveShift.setTimeLineUrl((String) dataSourceMap.get("timeLineUrl"));
|
||||
liveShift.setUrl((String) dataSourceMap.get("url"));
|
||||
liveShift.setCoverPath((String) dataSourceMap.get("coverPath"));
|
||||
liveShift.setFormat((String) dataSourceMap.get("format"));
|
||||
liveShift.setTitle((String) dataSourceMap.get("title"));
|
||||
setDataSource(liveShift);
|
||||
result.success(null);
|
||||
break;
|
||||
case "prepare":
|
||||
prepare();
|
||||
result.success(null);
|
||||
break;
|
||||
case "play":
|
||||
start();
|
||||
result.success(null);
|
||||
break;
|
||||
case "pause":
|
||||
pause();
|
||||
result.success(null);
|
||||
break;
|
||||
case "stop":
|
||||
stop();
|
||||
result.success(null);
|
||||
break;
|
||||
case "destroy":
|
||||
release();
|
||||
result.success(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void prepare(){
|
||||
if(mAliLiveShiftPlayer != null){
|
||||
mAliLiveShiftPlayer.prepare();
|
||||
}
|
||||
}
|
||||
|
||||
private void start(){
|
||||
if(mAliLiveShiftPlayer != null){
|
||||
mAliLiveShiftPlayer.start();
|
||||
}
|
||||
}
|
||||
|
||||
private void pause(){
|
||||
if(mAliLiveShiftPlayer != null){
|
||||
mAliLiveShiftPlayer.pause();
|
||||
}
|
||||
}
|
||||
|
||||
private void stop(){
|
||||
if(mAliLiveShiftPlayer != null){
|
||||
mAliLiveShiftPlayer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void release(){
|
||||
if(mAliLiveShiftPlayer != null){
|
||||
mAliLiveShiftPlayer.release();
|
||||
}
|
||||
}
|
||||
|
||||
private long getCurrentLiveTime() {
|
||||
if(mAliLiveShiftPlayer != null){
|
||||
return mAliLiveShiftPlayer.getCurrentLiveTime();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private long getCurrentTime(){
|
||||
if(mAliLiveShiftPlayer != null){
|
||||
return mAliLiveShiftPlayer.getCurrentTime();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void setDataSource(LiveShift liveShift){
|
||||
if(mAliLiveShiftPlayer != null){
|
||||
mAliLiveShiftPlayer.setDataSource(liveShift);
|
||||
}
|
||||
}
|
||||
|
||||
private void seekToLiveTime(long liveTime){
|
||||
if(mAliLiveShiftPlayer != null){
|
||||
mAliLiveShiftPlayer.seekToLiveTime(liveTime);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package com.alibaba.fplayer.flutter_aliplayer;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.aliyun.loader.MediaLoader;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin;
|
||||
import io.flutter.plugin.common.EventChannel;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
public class FlutterAliMediaLoader implements FlutterPlugin, MethodChannel.MethodCallHandler, EventChannel.StreamHandler {
|
||||
|
||||
private Context mContext;
|
||||
private MethodChannel mMethodChannel;
|
||||
private EventChannel.EventSink mEventSink;
|
||||
private EventChannel mEventChannel;
|
||||
private final MediaLoader mMediaLoader;
|
||||
|
||||
public FlutterAliMediaLoader(Context context, FlutterPlugin.FlutterPluginBinding flutterPluginBinding) {
|
||||
this.mContext = context;
|
||||
mMediaLoader = MediaLoader.getInstance();
|
||||
this.mMethodChannel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "plugins.flutter_aliplayer_media_loader");
|
||||
mMethodChannel.setMethodCallHandler(this);
|
||||
|
||||
mEventChannel = new EventChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "flutter_aliplayer_media_loader_event");
|
||||
mEventChannel.setStreamHandler(this);
|
||||
|
||||
mMediaLoader.setOnLoadStatusListener(new MediaLoader.OnLoadStatusListener() {
|
||||
@Override
|
||||
public void onError(String url, int code, String msg) {
|
||||
Map<String, String> resultMap = new HashMap<>();
|
||||
resultMap.put("method", "onError");
|
||||
resultMap.put("url", url);
|
||||
resultMap.put("code", String.valueOf(code));
|
||||
resultMap.put("msg", msg);
|
||||
mEventSink.success(resultMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompleted(String url) {
|
||||
Map<String, String> resultMap = new HashMap<>();
|
||||
resultMap.put("method", "onCompleted");
|
||||
resultMap.put("url", url);
|
||||
mEventSink.success(resultMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCanceled(String url) {
|
||||
Map<String, String> resultMap = new HashMap<>();
|
||||
resultMap.put("method", "onCanceled");
|
||||
resultMap.put("url", url);
|
||||
mEventSink.success(resultMap);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
||||
switch (call.method) {
|
||||
case "load":
|
||||
Map<String, String> loadMap = call.arguments();
|
||||
String url = loadMap.get("url");
|
||||
String duration = loadMap.get("duration");
|
||||
mMediaLoader.load(url, Long.valueOf(duration));
|
||||
break;
|
||||
case "resume":
|
||||
String resumeUrl = call.arguments();
|
||||
mMediaLoader.resume(resumeUrl);
|
||||
break;
|
||||
case "pause":
|
||||
String pauseUrl = call.arguments();
|
||||
mMediaLoader.pause(pauseUrl);
|
||||
break;
|
||||
case "cancel":
|
||||
String cancelUrl = call.arguments();
|
||||
mMediaLoader.cancel(cancelUrl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListen(Object arguments, EventChannel.EventSink events) {
|
||||
this.mEventSink = events;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(Object arguments) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.alibaba.fplayer.flutter_aliplayer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class FlutterAliPlayerFilterConfigBean {
|
||||
String target;
|
||||
List<String> options;
|
||||
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void setTarget(String target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public List<String> getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public void setOptions(List<String> options) {
|
||||
this.options = options;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package com.alibaba.fplayer.flutter_aliplayer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* AliPlayer 监听接口
|
||||
*/
|
||||
public interface FlutterAliPlayerListener {
|
||||
|
||||
void onPrepared(Map<String,Object> map);
|
||||
|
||||
void onTrackReady(Map<String,Object> map);
|
||||
|
||||
void onCompletion(Map<String,Object> map);
|
||||
|
||||
void onRenderingStart(Map<String,Object> map);
|
||||
|
||||
void onVideoSizeChanged(Map<String,Object> map);
|
||||
|
||||
void onSnapShot(Map<String,Object> map);
|
||||
|
||||
void onTrackChangedSuccess(Map<String,Object> map);
|
||||
|
||||
void onTrackChangedFail(Map<String,Object> map);
|
||||
|
||||
void onSeekComplete(Map<String,Object> map);
|
||||
|
||||
void onSeiData(Map<String,Object> map);
|
||||
|
||||
void onLoadingBegin(Map<String,Object> map);
|
||||
|
||||
void onLoadingProgress(Map<String,Object> map);
|
||||
|
||||
void onLoadingEnd(Map<String,Object> map);
|
||||
|
||||
void onStateChanged(Map<String,Object> map);
|
||||
|
||||
void onSubtitleExtAdded(Map<String,Object> map);
|
||||
|
||||
void onSubtitleShow(Map<String,Object> map);
|
||||
|
||||
void onSubtitleHide(Map<String,Object> map);
|
||||
|
||||
void onSubtitleHeader(Map<String,Object> map);
|
||||
|
||||
void onInfo(Map<String,Object> map);
|
||||
|
||||
void onError(Map<String,Object> map);
|
||||
|
||||
void onThumbnailPrepareSuccess(Map<String,Object> map);
|
||||
|
||||
void onThumbnailPrepareFail(Map<String,Object> map);
|
||||
|
||||
void onThumbnailGetSuccess(Map<String,Object> map);
|
||||
|
||||
void onThumbnailGetFail(Map<String,Object> map);
|
||||
|
||||
void onTimeShiftUpdater(Map<String,Object> map);
|
||||
|
||||
void onSeekLiveCompletion(Map<String,Object> map);
|
||||
|
||||
void onReportEventListener(Map<String,Object> map);
|
||||
|
||||
int onChooseTrackIndex(Map<String,Object> map);
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.alibaba.fplayer.flutter_aliplayer;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class FlutterAliPlayerStringUtils{
|
||||
/**
|
||||
* 获取字符串的 MD5
|
||||
*/
|
||||
public static String stringToMD5(String string) {
|
||||
byte[] hash;
|
||||
|
||||
try {
|
||||
hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder hex = new StringBuilder(hash.length * 2);
|
||||
for (byte b : hash) {
|
||||
if ((b & 0xFF) < 0x10)
|
||||
hex.append("0");
|
||||
hex.append(Integer.toHexString(b & 0xFF));
|
||||
}
|
||||
|
||||
return hex.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
package com.alibaba.fplayer.flutter_aliplayer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.TextureView;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.aliyun.player.AliListPlayer;
|
||||
import com.aliyun.player.IPlayer;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.plugin.platform.PlatformView;
|
||||
|
||||
|
||||
public class FlutterAliPlayerView implements PlatformView {
|
||||
|
||||
private static final String SURFACE_VIEW_TYPE = "surfaceview";
|
||||
private static final String TEXTURE_VIEW_TYPE = "textureview";
|
||||
private static final int ALIYUNN_PLAYER_SETSURFACE = 0x0001;
|
||||
private static final int ALIYUNN_PLAYER_TEXTURE= 0x0002;
|
||||
private Context mContext;
|
||||
private IPlayer mPlayer;
|
||||
private int mViewId;
|
||||
private MyHandler mHandler = new MyHandler(this);
|
||||
|
||||
private SurfaceView mSurfaceView;
|
||||
private TextureView mTextureView;
|
||||
private SurfaceHolder mSurfaceHolder;
|
||||
|
||||
private Surface mSurface;
|
||||
|
||||
private String viewType = SURFACE_VIEW_TYPE;
|
||||
private View flutterAttachedView;
|
||||
|
||||
public FlutterAliPlayerView(Context context, int viewId,Object args) {
|
||||
if (args != null) {
|
||||
Map<String,Object> argsMap = (Map<String, Object>) args;
|
||||
viewType = (String) argsMap.get("viewType");
|
||||
}
|
||||
this.mViewId = viewId;
|
||||
this.mContext = context;
|
||||
if (isTextureView()) {
|
||||
mTextureView = new TextureView(mContext);
|
||||
initRenderView(mTextureView);
|
||||
} else {
|
||||
mSurfaceView = new SurfaceView(mContext);
|
||||
initRenderView(mSurfaceView);
|
||||
}
|
||||
}
|
||||
|
||||
public IPlayer getPlayer() {
|
||||
return mPlayer;
|
||||
}
|
||||
|
||||
public void setPlayer(IPlayer player) {
|
||||
this.mPlayer = player;
|
||||
if (isTextureView()) {
|
||||
mHandler.sendEmptyMessage(ALIYUNN_PLAYER_TEXTURE);
|
||||
} else {
|
||||
mHandler.sendEmptyMessage(ALIYUNN_PLAYER_SETSURFACE);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isTextureView() {
|
||||
return TEXTURE_VIEW_TYPE.equals(viewType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView() {
|
||||
if (isTextureView()) {
|
||||
return mTextureView;
|
||||
} else {
|
||||
return mSurfaceView;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
if(mFlutterAliPlayerViewListener != null){
|
||||
mFlutterAliPlayerViewListener.onDispose(mViewId);
|
||||
}
|
||||
mHandler.removeCallbacksAndMessages(null);
|
||||
mSurfaceHolder = null;
|
||||
}
|
||||
|
||||
private void initRenderView(SurfaceView surfaceView) {
|
||||
|
||||
if (!isTextureView() && surfaceView != null) {
|
||||
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
|
||||
@Override
|
||||
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
|
||||
mSurfaceHolder = surfaceHolder;
|
||||
sendSetRenderViewMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
|
||||
if (mPlayer != null) {
|
||||
mPlayer.surfaceChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
|
||||
if(mPlayer instanceof AliListPlayer){
|
||||
/*
|
||||
当使用 pageView 实现列表播放时,会出现画面卡主,声音正常的问题。
|
||||
原因:滑动到下一个界面后,先设置 Surface 给 ListPlayer,然后上一个
|
||||
Surface 销毁,setSurface(null);
|
||||
部分手机如果不设置为 null,多次调用 setSurface 会导致崩溃。因此在 handler
|
||||
的事件里,先设置为 null,再设置 Surface.
|
||||
*/
|
||||
}else{
|
||||
mPlayer.setSurface(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void initRenderView(TextureView surfaceView) {
|
||||
|
||||
if (surfaceView != null && TEXTURE_VIEW_TYPE.equals(viewType)) {
|
||||
|
||||
surfaceView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surfaceTexture, int i, int i1) {
|
||||
mSurface = new Surface(surfaceTexture);
|
||||
sendSetRenderViewMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surfaceTexture, int i, int i1) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surfaceTexture) {
|
||||
mSurface = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surfaceTexture) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void sendSetRenderViewMessage() {
|
||||
if (isTextureView()) {
|
||||
mHandler.sendEmptyMessage(ALIYUNN_PLAYER_TEXTURE);
|
||||
} else {
|
||||
mHandler.sendEmptyMessage(ALIYUNN_PLAYER_SETSURFACE);
|
||||
}
|
||||
}
|
||||
|
||||
public interface FlutterAliPlayerViewListener{
|
||||
void onDispose(int viewId);
|
||||
}
|
||||
|
||||
private FlutterAliPlayerViewListener mFlutterAliPlayerViewListener;
|
||||
|
||||
public void setFlutterAliPlayerViewListener(FlutterAliPlayerViewListener listener){
|
||||
this.mFlutterAliPlayerViewListener = listener;
|
||||
}
|
||||
|
||||
private static class MyHandler extends Handler {
|
||||
|
||||
private WeakReference<FlutterAliPlayerView> mWeakReference;
|
||||
|
||||
public MyHandler(FlutterAliPlayerView futterAliPlayerView){
|
||||
mWeakReference = new WeakReference<>(futterAliPlayerView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
super.handleMessage(msg);
|
||||
FlutterAliPlayerView flutterAliPlayerView = mWeakReference.get();
|
||||
if(flutterAliPlayerView == null){
|
||||
return ;
|
||||
}
|
||||
switch (msg.what){
|
||||
case ALIYUNN_PLAYER_SETSURFACE:
|
||||
if(flutterAliPlayerView.mPlayer != null && flutterAliPlayerView.mSurfaceHolder != null){
|
||||
flutterAliPlayerView.mPlayer.setDisplay(null);
|
||||
flutterAliPlayerView.mPlayer.setDisplay(flutterAliPlayerView.mSurfaceHolder);
|
||||
}
|
||||
break;
|
||||
case ALIYUNN_PLAYER_TEXTURE:
|
||||
if(flutterAliPlayerView.mPlayer != null && flutterAliPlayerView.mSurface != null){
|
||||
flutterAliPlayerView.mPlayer.setSurface(null);
|
||||
flutterAliPlayerView.mPlayer.setSurface(flutterAliPlayerView.mSurface);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,558 @@
|
|||
package com.alibaba.fplayer.flutter_aliplayer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.aliyun.player.AliPlayerFactory;
|
||||
import com.aliyun.player.AliPlayerGlobalSettings;
|
||||
import com.aliyun.player.IPlayer;
|
||||
import com.aliyun.player.VidPlayerConfigGen;
|
||||
import com.aliyun.private_service.PrivateService;
|
||||
import com.cicada.player.utils.Logger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin;
|
||||
import io.flutter.plugin.common.EventChannel;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
||||
import io.flutter.plugin.common.MethodChannel.Result;
|
||||
import io.flutter.plugin.common.PluginRegistry.Registrar;
|
||||
import io.flutter.plugin.common.StandardMessageCodec;
|
||||
import io.flutter.plugin.platform.PlatformView;
|
||||
import io.flutter.plugin.platform.PlatformViewFactory;
|
||||
|
||||
/**
|
||||
* FlutterAliplayerPlugin
|
||||
*/
|
||||
public class FlutterAliplayerPlugin extends PlatformViewFactory implements FlutterPlugin, MethodCallHandler, EventChannel.StreamHandler, FlutterAliPlayerView.FlutterAliPlayerViewListener {
|
||||
/// The MethodChannel that will the communication between Flutter and native Android
|
||||
///
|
||||
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
|
||||
/// when the Flutter Engine is detached from the Activity
|
||||
private FlutterAliDownloader mAliyunDownload;
|
||||
private FlutterAliMediaLoader mAliyunMediaLoader;
|
||||
private FlutterPluginBinding flutterPluginBinding;
|
||||
private FlutterAliListPlayer mFlutterAliListPlayer;
|
||||
private Map<String, FlutterAliPlayer> mFlutterAliPlayerMap = new HashMap<>();
|
||||
private Map<String, FlutterAliLiveShiftPlayer> mFlutterAliLiveShiftPlayerMap = new HashMap<>();
|
||||
private Map<Integer, FlutterAliPlayerView> mFlutterAliPlayerViewMap = new HashMap<>();
|
||||
private EventChannel.EventSink mEventSink;
|
||||
private EventChannel mEventChannel;
|
||||
private Integer playerType = -1;
|
||||
|
||||
private Handler mMainHandler = new Handler(Looper.getMainLooper());
|
||||
private FlutterAliFloatWindowManager flutterAliFloatWindowManager;
|
||||
private VidPlayerConfigGen mVidPlayerConfigGen;
|
||||
|
||||
public FlutterAliplayerPlugin() {
|
||||
super(StandardMessageCodec.INSTANCE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
|
||||
this.flutterPluginBinding = flutterPluginBinding;
|
||||
flutterPluginBinding.getPlatformViewRegistry().registerViewFactory("flutter_aliplayer_render_view", this);
|
||||
mAliyunDownload = new FlutterAliDownloader(flutterPluginBinding.getApplicationContext(), flutterPluginBinding);
|
||||
mAliyunMediaLoader = new FlutterAliMediaLoader(flutterPluginBinding.getApplicationContext(), flutterPluginBinding);
|
||||
MethodChannel mAliPlayerFactoryMethodChannel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "plugins.flutter_aliplayer_factory");
|
||||
mAliPlayerFactoryMethodChannel.setMethodCallHandler(this);
|
||||
mEventChannel = new EventChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "flutter_aliplayer_event");
|
||||
mEventChannel.setStreamHandler(this);
|
||||
|
||||
flutterAliFloatWindowManager = new FlutterAliFloatWindowManager(flutterPluginBinding.getApplicationContext());
|
||||
|
||||
AliPlayerGlobalSettings.setCacheUrlHashCallback(new AliPlayerGlobalSettings.OnGetUrlHashCallback() {
|
||||
@Override
|
||||
public String getUrlHashCallback(String s) {
|
||||
String result = s;
|
||||
if (s.contains("?")) {
|
||||
String[] split = s.split("\\?");
|
||||
result = split[0];
|
||||
}
|
||||
System.out.println("java urlHashCallback " + s);
|
||||
return FlutterAliPlayerStringUtils.stringToMD5(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// This static function is optional and equivalent to onAttachedToEngine. It supports the old
|
||||
// pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
|
||||
// plugin registration via this function while apps migrate to use the new Android APIs
|
||||
// post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
|
||||
//
|
||||
// It is encouraged to share logic between onAttachedToEngine and registerWith to keep
|
||||
// them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
|
||||
// depending on the user's project. onAttachedToEngine or registerWith must both be defined
|
||||
// in the same class.
|
||||
public static void registerWith(Registrar registrar) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
|
||||
switch (call.method) {
|
||||
case "showFloatViewForAndroid":
|
||||
int showFloatViewId = (int) call.arguments;
|
||||
FlutterAliPlayerView showFlutterAliPlayerView = mFlutterAliPlayerViewMap.get(showFloatViewId);
|
||||
flutterAliFloatWindowManager.showFloatWindow(showFlutterAliPlayerView);
|
||||
result.success(null);
|
||||
break;
|
||||
case "hideFloatViewForAndroid":
|
||||
flutterAliFloatWindowManager.hideFloatWindow();
|
||||
result.success(null);
|
||||
break;
|
||||
case "createAliPlayer":
|
||||
playerType = call.argument("arg");
|
||||
if (0 == playerType) {
|
||||
//AliPlayer
|
||||
String createPlayerId = call.argument("playerId");
|
||||
FlutterAliPlayer flutterAliPlayer = new FlutterAliPlayer(flutterPluginBinding, createPlayerId);
|
||||
initListener(flutterAliPlayer);
|
||||
mFlutterAliPlayerMap.put(createPlayerId, flutterAliPlayer);
|
||||
} else if (1 == playerType) {
|
||||
//AliListPlayer
|
||||
mFlutterAliListPlayer = new FlutterAliListPlayer(flutterPluginBinding);
|
||||
initListener(mFlutterAliListPlayer);
|
||||
} else if (2 == playerType) {
|
||||
//AliLiveShiftPlayer
|
||||
String createPlayerId = call.argument("playerId");
|
||||
FlutterAliLiveShiftPlayer flutterAliLiveShiftPlayer = new FlutterAliLiveShiftPlayer(flutterPluginBinding, createPlayerId);
|
||||
initListener(flutterAliLiveShiftPlayer);
|
||||
mFlutterAliLiveShiftPlayerMap.put(createPlayerId, flutterAliLiveShiftPlayer);
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
result.success(null);
|
||||
break;
|
||||
case "initService":
|
||||
byte[] datas = (byte[]) call.arguments;
|
||||
PrivateService.initService(flutterPluginBinding.getApplicationContext(), datas);
|
||||
result.success(null);
|
||||
break;
|
||||
case "loadRtsLibrary":
|
||||
System.loadLibrary("RtsSDK");
|
||||
break;
|
||||
case "getSDKVersion":
|
||||
result.success(AliPlayerFactory.getSdkVersion());
|
||||
break;
|
||||
case "getDeviceUUID":
|
||||
result.success(AliPlayerFactory.getDeviceUUID());
|
||||
break;
|
||||
case "getLogLevel":
|
||||
result.success(getLogLevel());
|
||||
break;
|
||||
case "enableConsoleLog":
|
||||
Boolean enableLog = (Boolean) call.arguments;
|
||||
enableConsoleLog(enableLog);
|
||||
result.success(null);
|
||||
break;
|
||||
case "setLogLevel":
|
||||
Integer level = (Integer) call.arguments;
|
||||
setLogLevel(level);
|
||||
result.success(null);
|
||||
break;
|
||||
case "createDeviceInfo":
|
||||
result.success(createDeviceInfo());
|
||||
break;
|
||||
case "addBlackDevice":
|
||||
Map<String, String> addBlackDeviceMap = call.arguments();
|
||||
String blackType = addBlackDeviceMap.get("black_type");
|
||||
String blackDevice = addBlackDeviceMap.get("black_device");
|
||||
addBlackDevice(blackType, blackDevice);
|
||||
result.success(null);
|
||||
break;
|
||||
case "setPlayerView":
|
||||
Integer viewId = (Integer) call.argument("arg");
|
||||
FlutterAliPlayerView flutterAliPlayerView = mFlutterAliPlayerViewMap.get(viewId);
|
||||
|
||||
if (playerType == 0) {
|
||||
String setPlayerViewPlayerId = call.argument("playerId");
|
||||
FlutterAliPlayer mSetPlayerViewCurrentFlutterAliPlayer = mFlutterAliPlayerMap.get(setPlayerViewPlayerId);
|
||||
// if(mSetPlayerViewCurrentFlutterAliPlayer != null){
|
||||
// mSetPlayerViewCurrentFlutterAliPlayer.setViewMap(mFlutterAliPlayerViewMap);
|
||||
// }
|
||||
if (flutterAliPlayerView != null && mSetPlayerViewCurrentFlutterAliPlayer != null) {
|
||||
flutterAliPlayerView.setPlayer(mSetPlayerViewCurrentFlutterAliPlayer.getAliPlayer());
|
||||
}
|
||||
} else if (playerType == 1) {
|
||||
// mFlutterAliListPlayer.setViewMap(mFlutterAliPlayerViewMap);
|
||||
if (flutterAliPlayerView != null && mFlutterAliListPlayer != null) {
|
||||
flutterAliPlayerView.setPlayer(mFlutterAliListPlayer.getAliPlayer());
|
||||
}
|
||||
} else if (playerType == 2) {
|
||||
String setPlayerViewPlayerId = call.argument("playerId");
|
||||
FlutterAliLiveShiftPlayer mSetPlayerViewCurrentFlutterAliLiveShiftPlayer = mFlutterAliLiveShiftPlayerMap.get(setPlayerViewPlayerId);
|
||||
if (flutterAliPlayerView != null && mSetPlayerViewCurrentFlutterAliLiveShiftPlayer != null) {
|
||||
flutterAliPlayerView.setPlayer(mSetPlayerViewCurrentFlutterAliLiveShiftPlayer.getAliPlayer());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "setUseHttp2":
|
||||
Boolean enableUseHttp2 = call.arguments();
|
||||
AliPlayerGlobalSettings.setUseHttp2(enableUseHttp2);
|
||||
break;
|
||||
case "enableHttpDns":
|
||||
Boolean enableHttpDns = call.arguments();
|
||||
AliPlayerGlobalSettings.enableHttpDns(enableHttpDns);
|
||||
break;
|
||||
case "setDNSResolve":
|
||||
Map<String, String> dnsResolveMap = call.arguments();
|
||||
if (dnsResolveMap != null) {
|
||||
String dnsResolveHost = dnsResolveMap.get("host");
|
||||
String dnsResolveIP = dnsResolveMap.get("ip");
|
||||
AliPlayerGlobalSettings.setDNSResolve(dnsResolveHost, dnsResolveIP);
|
||||
}
|
||||
|
||||
result.success(null);
|
||||
case "enableNetworkBalance":
|
||||
Boolean enableNetworkBalance = call.arguments();
|
||||
AliPlayerGlobalSettings.enableNetworkBalance(enableNetworkBalance);
|
||||
result.success(null);
|
||||
break;
|
||||
case "enableLocalCache":
|
||||
Map<String, Object> localCacheMap = call.arguments();
|
||||
if (localCacheMap != null) {
|
||||
Boolean enable = (Boolean) localCacheMap.get("enable");
|
||||
String maxBufferMemoryKB = (String) localCacheMap.get("maxBufferMemoryKB");
|
||||
String localCacheDir = (String) localCacheMap.get("localCacheDir");
|
||||
AliPlayerGlobalSettings.enableLocalCache(enable, Integer.valueOf(maxBufferMemoryKB), localCacheDir);
|
||||
}
|
||||
break;
|
||||
case "setCacheFileClearConfig":
|
||||
Map<String, Object> cacheFileClearConfig = call.arguments();
|
||||
if (cacheFileClearConfig != null) {
|
||||
String expireMin = (String) cacheFileClearConfig.get("expireMin");
|
||||
String maxCapacityMB = (String) cacheFileClearConfig.get("maxCapacityMB");
|
||||
String freeStorageMB = (String) cacheFileClearConfig.get("freeStorageMB");
|
||||
AliPlayerGlobalSettings.setCacheFileClearConfig(Long.parseLong(expireMin), Long.parseLong(maxCapacityMB), Long.parseLong(freeStorageMB));
|
||||
}
|
||||
break;
|
||||
case "clearCaches":
|
||||
AliPlayerGlobalSettings.clearCaches();
|
||||
break;
|
||||
case "isFeatureSupport":
|
||||
result.success(AliPlayerFactory.isFeatureSupport(AliPlayerFactory.SupportFeatureType.FeatureDolbyAudio));
|
||||
break;
|
||||
case "setIPResolveType":
|
||||
String setIPResolveTypeStr = call.arguments() == null ? "" : (String) call.arguments();
|
||||
switch (setIPResolveTypeStr) {
|
||||
case "v4":
|
||||
AliPlayerGlobalSettings.setIPResolveType(IPlayer.IPResolveType.IpResolveV4);
|
||||
break;
|
||||
case "v6":
|
||||
AliPlayerGlobalSettings.setIPResolveType(IPlayer.IPResolveType.IpResolveV6);
|
||||
break;
|
||||
default:
|
||||
AliPlayerGlobalSettings.setIPResolveType(IPlayer.IPResolveType.IpResolveWhatEver);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "forceAudioRendingFormat":
|
||||
Map<String, Object> forceAudioRendingFormat = call.arguments();
|
||||
Boolean force = Boolean.getBoolean((String) forceAudioRendingFormat.get("force"));
|
||||
String fmt = (String) forceAudioRendingFormat.get("fmt");
|
||||
Integer channels = Integer.valueOf((String) forceAudioRendingFormat.get("channels"));
|
||||
Integer sample_rate = Integer.valueOf((String) forceAudioRendingFormat.get("sample_rate"));
|
||||
AliPlayerGlobalSettings.forceAudioRendingFormat(force, fmt, channels, sample_rate);
|
||||
break;
|
||||
case "createVidPlayerConfigGenerator":
|
||||
mVidPlayerConfigGen = new VidPlayerConfigGen();
|
||||
result.success(null);
|
||||
break;
|
||||
case "setPreviewTime":
|
||||
String setPreviewTime = call.arguments();
|
||||
if (mVidPlayerConfigGen != null && !TextUtils.isEmpty(setPreviewTime)) {
|
||||
mVidPlayerConfigGen.setPreviewTime(Integer.parseInt(setPreviewTime));
|
||||
}
|
||||
result.success(null);
|
||||
break;
|
||||
case "setHlsUriToken":
|
||||
String setHlsUriToken = call.arguments();
|
||||
if (mVidPlayerConfigGen != null) {
|
||||
mVidPlayerConfigGen.setMtsHlsUriToken(setHlsUriToken);
|
||||
}
|
||||
result.success(null);
|
||||
break;
|
||||
case "addVidPlayerConfigByStringValue":
|
||||
case "addVidPlayerConfigByIntValue":
|
||||
Map<String, String> addVidPlayerConfigByStringValue = (Map<String, String>) call.arguments;
|
||||
if (mVidPlayerConfigGen != null) {
|
||||
for (String s : addVidPlayerConfigByStringValue.keySet()) {
|
||||
mVidPlayerConfigGen.addPlayerConfig(s, addVidPlayerConfigByStringValue.get(s));
|
||||
}
|
||||
}
|
||||
result.success(null);
|
||||
break;
|
||||
case "generatePlayerConfig":
|
||||
String generatePlayerConfig = mVidPlayerConfigGen.genConfig();
|
||||
result.success(generatePlayerConfig);
|
||||
break;
|
||||
default:
|
||||
String otherPlayerId = call.argument("playerId");
|
||||
if (mFlutterAliPlayerMap.containsKey(otherPlayerId)) {
|
||||
String playerId = call.argument("playerId");
|
||||
FlutterAliPlayer mCurrentFlutterAliPlayer = mFlutterAliPlayerMap.get(playerId);
|
||||
if (call.method.equals("destroy")) {
|
||||
mFlutterAliPlayerMap.remove(playerId);
|
||||
}
|
||||
if (mCurrentFlutterAliPlayer != null) {
|
||||
mCurrentFlutterAliPlayer.onMethodCall(call, result);
|
||||
}
|
||||
} else if (mFlutterAliLiveShiftPlayerMap.containsKey(otherPlayerId)) {
|
||||
// String playerId = call.argument("playerId");
|
||||
FlutterAliLiveShiftPlayer mCurrentFlutterAliLiveShiftPlayer = mFlutterAliLiveShiftPlayerMap.get(otherPlayerId);
|
||||
if (call.method.equals("destroy")) {
|
||||
mFlutterAliLiveShiftPlayerMap.remove(otherPlayerId);
|
||||
}
|
||||
if (mCurrentFlutterAliLiveShiftPlayer != null) {
|
||||
mCurrentFlutterAliLiveShiftPlayer.onMethodCall(call, result);
|
||||
}
|
||||
} else {
|
||||
if (mFlutterAliListPlayer != null) {
|
||||
mFlutterAliListPlayer.onMethodCall(call, result);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private Integer getLogLevel() {
|
||||
return Logger.getInstance(flutterPluginBinding.getApplicationContext()).getLogLevel().getValue();
|
||||
}
|
||||
|
||||
private String createDeviceInfo() {
|
||||
AliPlayerFactory.DeviceInfo deviceInfo = new AliPlayerFactory.DeviceInfo();
|
||||
deviceInfo.model = Build.MODEL;
|
||||
return deviceInfo.model;
|
||||
}
|
||||
|
||||
private void addBlackDevice(String blackType, String modelInfo) {
|
||||
AliPlayerFactory.DeviceInfo deviceInfo = new AliPlayerFactory.DeviceInfo();
|
||||
deviceInfo.model = modelInfo;
|
||||
AliPlayerFactory.BlackType aliPlayerBlackType;
|
||||
if (!TextUtils.isEmpty(blackType) && blackType.equals("HW_Decode_H264")) {
|
||||
aliPlayerBlackType = AliPlayerFactory.BlackType.HW_Decode_H264;
|
||||
} else {
|
||||
aliPlayerBlackType = AliPlayerFactory.BlackType.HW_Decode_HEVC;
|
||||
}
|
||||
AliPlayerFactory.addBlackDevice(aliPlayerBlackType, deviceInfo);
|
||||
}
|
||||
|
||||
private void enableConsoleLog(Boolean enableLog) {
|
||||
Logger.getInstance(flutterPluginBinding.getApplicationContext()).enableConsoleLog(enableLog);
|
||||
}
|
||||
|
||||
private void setLogLevel(int level) {
|
||||
Logger.LogLevel mLogLevel;
|
||||
if (level == Logger.LogLevel.AF_LOG_LEVEL_NONE.getValue()) {
|
||||
mLogLevel = Logger.LogLevel.AF_LOG_LEVEL_NONE;
|
||||
} else if (level == Logger.LogLevel.AF_LOG_LEVEL_FATAL.getValue()) {
|
||||
mLogLevel = Logger.LogLevel.AF_LOG_LEVEL_FATAL;
|
||||
} else if (level == Logger.LogLevel.AF_LOG_LEVEL_ERROR.getValue()) {
|
||||
mLogLevel = Logger.LogLevel.AF_LOG_LEVEL_ERROR;
|
||||
} else if (level == Logger.LogLevel.AF_LOG_LEVEL_WARNING.getValue()) {
|
||||
mLogLevel = Logger.LogLevel.AF_LOG_LEVEL_WARNING;
|
||||
} else if (level == Logger.LogLevel.AF_LOG_LEVEL_INFO.getValue()) {
|
||||
mLogLevel = Logger.LogLevel.AF_LOG_LEVEL_INFO;
|
||||
} else if (level == Logger.LogLevel.AF_LOG_LEVEL_DEBUG.getValue()) {
|
||||
mLogLevel = Logger.LogLevel.AF_LOG_LEVEL_DEBUG;
|
||||
} else if (level == Logger.LogLevel.AF_LOG_LEVEL_TRACE.getValue()) {
|
||||
mLogLevel = Logger.LogLevel.AF_LOG_LEVEL_TRACE;
|
||||
} else {
|
||||
mLogLevel = Logger.LogLevel.AF_LOG_LEVEL_NONE;
|
||||
}
|
||||
Logger.getInstance(flutterPluginBinding.getApplicationContext()).setLogLevel(mLogLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置监听
|
||||
*/
|
||||
private void initListener(FlutterPlayerBase flutterPlayerBase) {
|
||||
flutterPlayerBase.setOnFlutterListener(new FlutterAliPlayerListener() {
|
||||
@Override
|
||||
public void onPrepared(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrackReady(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompletion(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRenderingStart(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVideoSizeChanged(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSnapShot(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrackChangedSuccess(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrackChangedFail(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSeekComplete(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSeiData(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingBegin(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingProgress(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingEnd(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateChanged(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubtitleExtAdded(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubtitleShow(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubtitleHide(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubtitleHeader(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInfo(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onThumbnailPrepareSuccess(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onThumbnailPrepareFail(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onThumbnailGetSuccess(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onThumbnailGetFail(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeShiftUpdater(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSeekLiveCompletion(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReportEventListener(final Map<String, Object> map) {
|
||||
mMainHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mEventSink.success(map);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onChooseTrackIndex(Map<String, Object> map) {
|
||||
mEventSink.success(map);
|
||||
return 0;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformView create(Context context, int viewId, Object args) {
|
||||
FlutterAliPlayerView flutterAliPlayerView = new FlutterAliPlayerView(context, viewId, args);
|
||||
flutterAliPlayerView.setFlutterAliPlayerViewListener(this);
|
||||
mFlutterAliPlayerViewMap.put(viewId, flutterAliPlayerView);
|
||||
return flutterAliPlayerView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListen(Object arguments, EventChannel.EventSink events) {
|
||||
this.mEventSink = events;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(Object arguments) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDispose(int viewId) {
|
||||
mFlutterAliPlayerViewMap.remove(viewId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,427 @@
|
|||
package com.alibaba.fplayer.flutter_aliplayer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import com.aliyun.player.AliLiveShiftPlayer;
|
||||
import com.aliyun.player.IPlayer;
|
||||
import com.aliyun.player.bean.ErrorInfo;
|
||||
import com.aliyun.player.bean.InfoBean;
|
||||
import com.aliyun.player.nativeclass.MediaInfo;
|
||||
import com.aliyun.player.nativeclass.TrackInfo;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
|
||||
public abstract class FlutterPlayerBase {
|
||||
|
||||
protected Context mContext;
|
||||
protected String mSnapShotPath;
|
||||
protected String mPlayerId;
|
||||
protected FlutterAliPlayerListener mFlutterAliPlayerListener;
|
||||
private ExecutorService executorService = new ScheduledThreadPoolExecutor(10);
|
||||
|
||||
private Handler mHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
public void setOnFlutterListener(FlutterAliPlayerListener listener) {
|
||||
this.mFlutterAliPlayerListener = listener;
|
||||
}
|
||||
|
||||
public abstract IPlayer getAliPlayer();
|
||||
|
||||
public void initListener(final IPlayer player) {
|
||||
player.setOnPreparedListener(new IPlayer.OnPreparedListener() {
|
||||
@Override
|
||||
public void onPrepared() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onPrepared");
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onPrepared(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.setOnRenderingStartListener(new IPlayer.OnRenderingStartListener() {
|
||||
@Override
|
||||
public void onRenderingStart() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onRenderingStart");
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onRenderingStart(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.setOnChooseTrackIndexListener(new IPlayer.OnChooseTrackIndexListener() {
|
||||
@Override
|
||||
public int onChooseTrackIndex(TrackInfo[] trackInfos) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onChooseTrackIndex");
|
||||
map.put("trackInfos", trackInfos);
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
return mFlutterAliPlayerListener.onChooseTrackIndex(map);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.setOnReportEventListener(new IPlayer.OnReportEventListener() {
|
||||
@Override
|
||||
public void onEventParam(Map<String, String> param) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onEventReportParams");
|
||||
map.put("params", param);
|
||||
map.put("playerId", mPlayerId);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onReportEventListener(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() {
|
||||
@Override
|
||||
public void onVideoSizeChanged(int width, int height) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onVideoSizeChanged");
|
||||
map.put("width", width);
|
||||
map.put("height", height);
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onVideoSizeChanged(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.setOnSnapShotListener(new IPlayer.OnSnapShotListener() {
|
||||
@Override
|
||||
public void onSnapShot(final Bitmap bitmap, int width, int height) {
|
||||
final Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onSnapShot");
|
||||
map.put("snapShotPath", mSnapShotPath);
|
||||
map.put("playerId", mPlayerId);
|
||||
|
||||
|
||||
executorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(bitmap != null){
|
||||
File f = new File(mSnapShotPath);
|
||||
FileOutputStream out = null;
|
||||
if (f.exists()) {
|
||||
f.delete();
|
||||
}
|
||||
try {
|
||||
out = new FileOutputStream(f);
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onSnapShot(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
// mEventSink.success(map);
|
||||
}
|
||||
});
|
||||
|
||||
player.setOnTrackChangedListener(new IPlayer.OnTrackChangedListener() {
|
||||
@Override
|
||||
public void onChangedSuccess(TrackInfo trackInfo) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onTrackChanged");
|
||||
map.put("playerId", mPlayerId);
|
||||
Map<String, Object> infoMap = new HashMap<>();
|
||||
infoMap.put("vodFormat", trackInfo.getVodFormat());
|
||||
infoMap.put("videoHeight", trackInfo.getVideoHeight());
|
||||
infoMap.put("videoWidth", trackInfo.getVideoHeight());
|
||||
infoMap.put("subtitleLanguage", trackInfo.getSubtitleLang());
|
||||
infoMap.put("trackBitrate", trackInfo.getVideoBitrate());
|
||||
infoMap.put("vodFileSize", trackInfo.getVodFileSize());
|
||||
infoMap.put("trackIndex", trackInfo.getIndex());
|
||||
infoMap.put("trackDefinition", trackInfo.getVodDefinition());
|
||||
infoMap.put("audioSampleFormat", trackInfo.getAudioSampleFormat());
|
||||
infoMap.put("audioLanguage", trackInfo.getAudioLang());
|
||||
infoMap.put("vodPlayUrl", trackInfo.getVodPlayUrl());
|
||||
infoMap.put("trackType", trackInfo.getType().ordinal());
|
||||
infoMap.put("audioSamplerate", trackInfo.getAudioSampleRate());
|
||||
infoMap.put("audioChannels", trackInfo.getAudioChannels());
|
||||
map.put("info", infoMap);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onTrackChangedSuccess(map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChangedFail(TrackInfo trackInfo, ErrorInfo errorInfo) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onChangedFail");
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onTrackChangedFail(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.setOnSeekCompleteListener(new IPlayer.OnSeekCompleteListener() {
|
||||
@Override
|
||||
public void onSeekComplete() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onSeekComplete");
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onSeekComplete(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.setOnSeiDataListener(new IPlayer.OnSeiDataListener() {
|
||||
@Override
|
||||
public void onSeiData(int type, byte[] bytes) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onSeiData");
|
||||
map.put("type", type);
|
||||
map.put("data", new String(bytes));
|
||||
map.put("playerId", mPlayerId);
|
||||
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onSeiData(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.setOnLoadingStatusListener(new IPlayer.OnLoadingStatusListener() {
|
||||
@Override
|
||||
public void onLoadingBegin() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onLoadingBegin");
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onLoadingBegin(map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingProgress(int percent, float netSpeed) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onLoadingProgress");
|
||||
map.put("percent", percent);
|
||||
map.put("netSpeed", netSpeed);
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onLoadingProgress(map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingEnd() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onLoadingEnd");
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onLoadingEnd(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.setOnStateChangedListener(new IPlayer.OnStateChangedListener() {
|
||||
@Override
|
||||
public void onStateChanged(int newState) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onStateChanged");
|
||||
map.put("newState", newState);
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onStateChanged(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() {
|
||||
@Override
|
||||
public void onSubtitleExtAdded(int trackIndex, String url) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onSubtitleExtAdded");
|
||||
map.put("trackIndex", trackIndex);
|
||||
map.put("url", url);
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onSubtitleExtAdded(map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubtitleShow(int trackIndex, long id, String data) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onSubtitleShow");
|
||||
map.put("trackIndex", trackIndex);
|
||||
map.put("subtitleID", id);
|
||||
map.put("subtitle", data);
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onSubtitleShow(map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubtitleHide(int trackIndex, long id) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onSubtitleHide");
|
||||
map.put("trackIndex", trackIndex);
|
||||
map.put("subtitleID", id);
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onSubtitleHide(map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubtitleHeader(int trackIndex, String header) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onSubtitleHeader");
|
||||
map.put("trackIndex", trackIndex);
|
||||
map.put("header", header);
|
||||
map.put("playerId", mPlayerId);
|
||||
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onSubtitleHeader(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.setOnInfoListener(new IPlayer.OnInfoListener() {
|
||||
@Override
|
||||
public void onInfo(InfoBean infoBean) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onInfo");
|
||||
map.put("infoCode", infoBean.getCode().getValue());
|
||||
map.put("extraValue", infoBean.getExtraValue());
|
||||
map.put("extraMsg", infoBean.getExtraMsg());
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onInfo(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.setOnErrorListener(new IPlayer.OnErrorListener() {
|
||||
@Override
|
||||
public void onError(ErrorInfo errorInfo) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onError");
|
||||
map.put("errorCode", errorInfo.getCode().getValue());
|
||||
map.put("errorExtra", errorInfo.getExtra());
|
||||
map.put("errorMsg", errorInfo.getMsg());
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onError(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.setOnTrackReadyListener(new IPlayer.OnTrackReadyListener() {
|
||||
@Override
|
||||
public void onTrackReady(MediaInfo mediaInfo) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onTrackReady");
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onTrackReady(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.setOnCompletionListener(new IPlayer.OnCompletionListener() {
|
||||
@Override
|
||||
public void onCompletion() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onCompletion");
|
||||
map.put("playerId", mPlayerId);
|
||||
// mEventSink.success(map);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onCompletion(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (player instanceof AliLiveShiftPlayer) {
|
||||
((AliLiveShiftPlayer) player).setOnTimeShiftUpdaterListener(new AliLiveShiftPlayer.OnTimeShiftUpdaterListener() {
|
||||
@Override
|
||||
public void onUpdater(long currentTime, long shiftStartTime, long shiftEndTime) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onUpdater");
|
||||
map.put("currentTime", currentTime);
|
||||
map.put("shiftStartTime", shiftStartTime);
|
||||
map.put("shiftEndTime", shiftEndTime);
|
||||
map.put("playerId", mPlayerId);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onTimeShiftUpdater(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
((AliLiveShiftPlayer) player).setOnSeekLiveCompletionListener(new AliLiveShiftPlayer.OnSeekLiveCompletionListener() {
|
||||
@Override
|
||||
public void onSeekLiveCompletion(long playTime) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("method", "onSeekLiveCompletion");
|
||||
map.put("playTime", playTime);
|
||||
map.put("playerId", mPlayerId);
|
||||
if (mFlutterAliPlayerListener != null) {
|
||||
mFlutterAliPlayerListener.onSeekLiveCompletion(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.alibaba.fplayer.flutter_aliplayer.listener;
|
||||
|
||||
interface FlutterAliRenderViewListener {
|
||||
void onCreated();
|
||||
|
||||
void onSizeChanged();
|
||||
|
||||
void onDestroy();
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# The .vscode folder contains launch configuration and tasks you configure in
|
||||
# VS Code which you may wish to be included in version control, so this line
|
||||
# is commented out by default.
|
||||
#.vscode/
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
**/doc/api/
|
||||
**/ios/Flutter/.last_build_id
|
||||
.dart_tool/
|
||||
.flutter-plugins
|
||||
.flutter-plugins-dependencies
|
||||
.packages
|
||||
.pub-cache/
|
||||
.pub/
|
||||
/build/
|
||||
pubspec.lock
|
||||
|
||||
# Web related
|
||||
lib/generated_plugin_registrant.dart
|
||||
|
||||
# Symbolication related
|
||||
app.*.symbols
|
||||
|
||||
# Obfuscation related
|
||||
app.*.map.json
|
||||
|
||||
# Exceptions to above rules.
|
||||
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
|
@ -0,0 +1,10 @@
|
|||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: 216dee60c0cc9449f0b29bcf922974d612263e24
|
||||
channel: stable
|
||||
|
||||
project_type: app
|
|
@ -0,0 +1,16 @@
|
|||
# flutter_aliplayer_example
|
||||
|
||||
Demonstrates how to use the flutter_aliplayer plugin.
|
||||
|
||||
## Getting Started
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
|
||||
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
|
||||
|
||||
For help getting started with Flutter, view our
|
||||
[online documentation](https://flutter.dev/docs), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
|
@ -0,0 +1,11 @@
|
|||
gradle-wrapper.jar
|
||||
/.gradle
|
||||
/captures/
|
||||
/gradlew
|
||||
/gradlew.bat
|
||||
/local.properties
|
||||
GeneratedPluginRegistrant.java
|
||||
|
||||
# Remember to never publicly share your keystore.
|
||||
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
|
||||
key.properties
|
|
@ -0,0 +1,81 @@
|
|||
def localProperties = new Properties()
|
||||
def localPropertiesFile = rootProject.file('local.properties')
|
||||
if (localPropertiesFile.exists()) {
|
||||
localPropertiesFile.withReader('UTF-8') { reader ->
|
||||
localProperties.load(reader)
|
||||
}
|
||||
}
|
||||
|
||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
||||
if (flutterRoot == null) {
|
||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = '1'
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = '1.0'
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
android {
|
||||
compileSdkVersion 31
|
||||
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "com.alibaba.fplayer.flutter_aliplayer_example"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 30
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file("$rootDir/debug.keystore")
|
||||
storePassword "android"
|
||||
keyAlias "androiddebugkey"
|
||||
keyPassword "android"
|
||||
}
|
||||
|
||||
release {
|
||||
storeFile file("$rootDir/debug.keystore")
|
||||
storePassword "android"
|
||||
keyAlias "androiddebugkey"
|
||||
keyPassword "android"
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig signingConfigs.release
|
||||
minifyEnabled true
|
||||
useProguard true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../proguard-rules.pro'
|
||||
}
|
||||
debug{
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies{
|
||||
implementation 'com.aliyun.sdk.android:AlivcArtc:5.4.9.1'
|
||||
implementation 'com.aliyun.rts.android:RtsSDK:2.5.0'
|
||||
}
|
||||
|
||||
flutter {
|
||||
source '../..'
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.alibaba.fplayer.flutter_aliplayer_example">
|
||||
<!-- Flutter needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
|
@ -0,0 +1,62 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.alibaba.fplayer.flutter_aliplayer_example">
|
||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||
In most cases you can leave this as-is, but you if you want to provide
|
||||
additional functionality it is fine to subclass or reimplement
|
||||
FlutterApplication and put your custom class here. -->
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
|
||||
<meta-data android:name="flutterEmbedding" android:value="2"/>
|
||||
|
||||
<application
|
||||
android:label="flutter_aliplayer_example"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
<!-- Displays an Android View that continues showing the launch screen
|
||||
Drawable until Flutter paints its first frame, then this splash
|
||||
screen fades out. A splash screen is useful to avoid any visual
|
||||
gap between the end of Android's launch screen and the painting of
|
||||
Flutter's first frame. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.SplashScreenDrawable"
|
||||
android:resource="@drawable/launch_background"
|
||||
/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
|
||||
<meta-data
|
||||
android:name="com.aliyun.alivc_license.licensekey"
|
||||
android:value="xoO3haINz3PXBemBG3f62d8790e434827a960907c6a22e83e" />
|
||||
</application>
|
||||
</manifest>
|
|
@ -0,0 +1,16 @@
|
|||
package com.alibaba.fplayer.flutter_aliplayer_example;
|
||||
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity;
|
||||
|
||||
public class MainActivity extends FlutterActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@android:color/white" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
After Width: | Height: | Size: 544 B |
After Width: | Height: | Size: 442 B |
After Width: | Height: | Size: 721 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
Flutter draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:windowBackground">@android:color/white</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -0,0 +1,7 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.alibaba.fplayer.flutter_aliplayer_example">
|
||||
<!-- Flutter needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
|
@ -0,0 +1,31 @@
|
|||
buildscript {
|
||||
ext.kotlin_version='1.6.10'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.buildDir = '../build'
|
||||
subprojects {
|
||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||
}
|
||||
subprojects {
|
||||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
org.gradle.jvmargs=-Xmx1536M
|
||||
android.enableR8=true
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
extra-gen-snapshot-options=--obfuscate
|
|
@ -0,0 +1,6 @@
|
|||
#Fri Jun 23 08:50:38 CEST 2017
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
|
|
@ -0,0 +1,6 @@
|
|||
-keep class com.alivc.**{*;}
|
||||
-keep class com.aliyun.**{*;}
|
||||
-keep class com.cicada.**{*;}
|
||||
-dontwarn com.alivc.**
|
||||
-dontwarn com.aliyun.**
|
||||
-dontwarn com.cicada.**
|
|
@ -0,0 +1,11 @@
|
|||
include ':app'
|
||||
|
||||
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
|
||||
def properties = new Properties()
|
||||
|
||||
assert localPropertiesFile.exists()
|
||||
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
|
||||
|
||||
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
||||
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
|
|
@ -0,0 +1 @@
|
|||
DE-IEIBW9pv-WZ5jzfO3ANSv9bbCSPxBy21_mFFoH3V-nROmnU3tMKVj_1DkI8U9i0YhafWhQXkOFttehDjfqSdnbh3rl6eKf_Ct-Vb3HOsNhE8_qlLVScqGSrmFzkml4hQD0cS6YSqPJVJin0fp1CjRgDVYS-1JIINI6gytO5nWgou6kB1h5TlIKrmnG-KmC0-zkEU1Dr5d2-9IUGqoXEiGcVu7q_mh4UnjGZsQgof5sWEWwmdSGlM3SJpG36SM0JqUNJByBNhTUwOpmhu_YJZpMelNy_pSlfSJ4yPp9pOpWXiUaCsmO2YBdeqZOzd2xsVizb8cFkM2aU4ibaBu5SIQRFcztMu7cjnRf7vRvsIGCQU3Rbq5VmTKl9260G8y_HhOdwJg9L3pGOyLPRmaypzRePml8jhpzJuHlE6dZzR4LZ_hvdDFAn7uDq_R2UEPAFAqcwoatJhdUZplXs48VLXaIq4KGbNEG8IJYGdnuBPvQFIgtlgJB5vFFbGNKJdmnl38noUgoyytZZy2QzV0STLdxX-ZAsEFyeHJoXw9Y1D0eGmjP1tsCWkGs6JO10OJpg0eNw_p10Xh0SR75X4b7kHyGr9GirzJ4yqUy9911chA9L6mkrRBlWvCzvb3d44nc0thbY-1Nfl6yGEdzzacO-HGrYdB-Cde2OcLYi1b2o9JP31J0CScDGy8ijfKtKbRhYJhmy-saBesNYJ2Ef9O9zuXJCEQF_JTyhr6twhONNhKZ8ZGrPf95ol48YAM9g0wXjrcv16RjjCrpP5LFdt72YoqQ7IcQYeu6PBfUz7FDuUPpQ3FqOCdhXl1Bsayik5c_IhxLVp8LJC-Pe0F19slLpdK1WvmEeEqEfZQm7v2KiiCGKUy41tUCAHXmfKgrm5Gt8s7uD9w2xKk0aRwGqFcSpVegjTUHU5vugwxXBNeoA-bEwCKjxUUKU1N5vAn5qxkumhPXj69z5_alFSPBQKCPkr2PzNjiKmo3rFVmHrZWQEg_rOThwul5ArS73IuvAqwKxpO9Mo0MPpVDWU56cAKY4FJCd1UeiGRv_WSZI6zbYo
|
|
@ -0,0 +1 @@
|
|||
RSjGUwhHWC30lOzeTK1QqGed9iRYlAQssmYrPUkLvSj2XPftmv1-NQMaRw8mWbt7IvC3IsNlWwRc0Grc-x7EZ1OaNz4zc_9D-uvc9aeFZd2XCq4K_zcUVWlB_X98u6_LLrI9vNBfygEVJh39_iuD_xRxBXVCnfkZCjJ5UKssYiH-CXnbWqLe_wQMnAtX-9nKXj_by2_AQFGyK9HQu2RpcJbsZ42O6pqtvs4ZOOAbZfGssVt0IAU2rXY85qFD0eHmO8GdIyU-BKuh0aoFA9ADDN9peCmneJ_Q3FoPXviWsnJlpTnmDg1QDSiqD3OuxlVqi7JFMTxqRueAYvob31qng0Z5Goudp-K8ZKHKch0OjDUsbYq_Z9VetXDQx_Sy-DoobSmUZKP7fXpAACFiCaA-4AFlYGZd172SCGhZsdQTkOaUujWISHprV40ZedE7rHEfHxf-xMfCDP21CdLYidFj-OWu68mW3G-VhEXRm1mbDjHISzZWvC8CoDVXAQRgmlQZJEZk2IrKp-Q2jOICT6ABGnczH-PNgWL81VDxOUA9HA5xSmXSx1UtiZAmm5JMBUxv28xFCECTBYEGVT4Ll-V62wu0J-526W7QLMWPNiuxIbVOJy-aNQGeCHMD4BVAXVpAobFFsuwsmehKQvIsmCQrnEnmsUcu3JzHf2csvCZw9W-PzByL7F3DQ74svm_iK0SXpTkfcV3_zZDh_busTJ1dOMJeoc0kmEn4qmLFLq8M9x-Cx3EYTpiIreZ5KCJSSX6-yQgAC0f3XYEfzVHpy4q4YeoYVli_ljJP1-fPnpZe4TbuzcprHzj9t_siHmTrK0HuAGuziua3LH4PuTuqanQLsehJGBYn-brc_vQfG9YacGeXL8SmxulrWwuDjMf90G1s4m_OVaVOEAaZ--bUCPzq2-q4fYiPWY0m3BFczmMSeodMy4jM1SsEj9dLja-O_swRdXh9oYyRIwCV5_6ahtJJqUF36LIuJh1-_ilI5u1aJABShcat2yJhdr4q6Q9nFn_0jilemOFDzCHksxvwqncextP34Qh4fU3Bk3wXTb6TSg4YfyRPmk2hlcxq5wr6gxJOuFWCbZHpuENPob4gP5n601Apux-TbKY7x3oWt9cSSdxL7qm1F-_eao6zfqHYfjCeAtDrCrKKHw0KJ1XjitHd-G-5YQuKP3bEcOYEOFYjHwtfh-iL-PoCTmpsf6u5ShHEPYewArvcGi5ZN8Vy9FMfxFhsppOUUyJERHVo2DWOE0JaPypsEijSxJsGVQT5Bs8VatGjJdBAdd4ADffuL9O9UZlGEUvZ89JlE22PzHzbd69jSRKYUyaXlD_fqLOBq9TlJOdsPRC-W5isPAnGdwIuQA
|
After Width: | Height: | Size: 388 KiB |
After Width: | Height: | Size: 16 KiB |
|
@ -0,0 +1,32 @@
|
|||
*.mode1v3
|
||||
*.mode2v3
|
||||
*.moved-aside
|
||||
*.pbxuser
|
||||
*.perspectivev3
|
||||
**/*sync/
|
||||
.sconsign.dblite
|
||||
.tags*
|
||||
**/.vagrant/
|
||||
**/DerivedData/
|
||||
Icon?
|
||||
**/Pods/
|
||||
**/.symlinks/
|
||||
profile
|
||||
xcuserdata
|
||||
**/.generated/
|
||||
Flutter/App.framework
|
||||
Flutter/Flutter.framework
|
||||
Flutter/Flutter.podspec
|
||||
Flutter/Generated.xcconfig
|
||||
Flutter/app.flx
|
||||
Flutter/app.zip
|
||||
Flutter/flutter_assets/
|
||||
Flutter/flutter_export_environment.sh
|
||||
ServiceDefinitions.json
|
||||
Runner/GeneratedPluginRegistrant.*
|
||||
|
||||
# Exceptions to above rules.
|
||||
!default.mode1v3
|
||||
!default.mode2v3
|
||||
!default.pbxuser
|
||||
!default.perspectivev3
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>App</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>io.flutter.flutter.app</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>App</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>9.0</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,2 @@
|
|||
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "Generated.xcconfig"
|
|
@ -0,0 +1,2 @@
|
|||
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "Generated.xcconfig"
|
|
@ -0,0 +1,51 @@
|
|||
# Uncomment this line to define a global platform for your project
|
||||
platform :ios, '11.0'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
project 'Runner', {
|
||||
'Debug' => :debug,
|
||||
'Profile' => :release,
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||
end
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
|
||||
end
|
||||
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_ios_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
|
||||
pod 'AliPlayerSDK_iOS_ARTC', '5.5.6.0'
|
||||
pod 'RtsSDK', '2.5.0'
|
||||
|
||||
end
|
||||
|
||||
# post_install do |installer|
|
||||
# installer.pods_project.targets.each do |target|
|
||||
# flutter_additional_ios_build_settings(target)
|
||||
# end
|
||||
# end
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_ios_build_settings(target)
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
||||
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,89 @@
|
|||
PODS:
|
||||
- AliPlayerSDK_iOS (5.5.6.0):
|
||||
- AliPlayerSDK_iOS/AliPlayerSDK (= 5.5.6.0)
|
||||
- AliPlayerSDK_iOS/AliPlayerSDK (5.5.6.0)
|
||||
- AliPlayerSDK_iOS_ARTC (5.5.6.0):
|
||||
- AliPlayerSDK_iOS_ARTC/AliPlayerSDK (= 5.5.6.0)
|
||||
- AliPlayerSDK_iOS_ARTC/AliPlayerSDK (5.5.6.0)
|
||||
- connectivity (0.0.1):
|
||||
- Flutter
|
||||
- Reachability
|
||||
- Flutter (1.0.0)
|
||||
- flutter_aliplayer (5.5.6):
|
||||
- AliPlayerSDK_iOS (= 5.5.6.0)
|
||||
- Flutter
|
||||
- MJExtension
|
||||
- fluttertoast (0.0.2):
|
||||
- Flutter
|
||||
- Toast
|
||||
- FMDB (2.7.5):
|
||||
- FMDB/standard (= 2.7.5)
|
||||
- FMDB/standard (2.7.5)
|
||||
- MJExtension (3.4.1)
|
||||
- path_provider (0.0.1):
|
||||
- Flutter
|
||||
- qrcode_reader (0.0.1):
|
||||
- Flutter
|
||||
- Reachability (3.2)
|
||||
- RtsSDK (2.5.0)
|
||||
- sqflite (0.0.2):
|
||||
- Flutter
|
||||
- FMDB (>= 2.7.5)
|
||||
- Toast (4.0.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- AliPlayerSDK_iOS_ARTC (= 5.5.6.0)
|
||||
- connectivity (from `.symlinks/plugins/connectivity/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_aliplayer (from `.symlinks/plugins/flutter_aliplayer/ios`)
|
||||
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
||||
- qrcode_reader (from `.symlinks/plugins/qrcode_reader/ios`)
|
||||
- RtsSDK (= 2.5.0)
|
||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- AliPlayerSDK_iOS
|
||||
- AliPlayerSDK_iOS_ARTC
|
||||
- FMDB
|
||||
- MJExtension
|
||||
- Reachability
|
||||
- RtsSDK
|
||||
- Toast
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
connectivity:
|
||||
:path: ".symlinks/plugins/connectivity/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_aliplayer:
|
||||
:path: ".symlinks/plugins/flutter_aliplayer/ios"
|
||||
fluttertoast:
|
||||
:path: ".symlinks/plugins/fluttertoast/ios"
|
||||
path_provider:
|
||||
:path: ".symlinks/plugins/path_provider/ios"
|
||||
qrcode_reader:
|
||||
:path: ".symlinks/plugins/qrcode_reader/ios"
|
||||
sqflite:
|
||||
:path: ".symlinks/plugins/sqflite/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
AliPlayerSDK_iOS: fa379587f1f6b9c7dc588f8328ad64f1f550b826
|
||||
AliPlayerSDK_iOS_ARTC: a5a56b7ba715e686d7817b64551be50a956205a7
|
||||
connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467
|
||||
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
||||
flutter_aliplayer: cf3da3d18dffe2ac1b0cef462f9dfec027a0d53c
|
||||
fluttertoast: 6122fa75143e992b1d3470f61000f591a798cc58
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
MJExtension: 21c5f6f8c4d5d8844b7ae8fbae08fed0b501f961
|
||||
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
||||
qrcode_reader: 09b34d43b4c08fe5b63a6e56c96789bcea7b9148
|
||||
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
|
||||
RtsSDK: b972ffcc8d8e5d9aefb6c82e08037a98b5922a3f
|
||||
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
||||
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
||||
|
||||
PODFILE CHECKSUM: 85a4650c8affccc8dad46acd9ce21e3296173297
|
||||
|
||||
COCOAPODS: 1.11.3
|
|
@ -0,0 +1,595 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 51;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
6571D52028E6B6BF00429F3B /* Info-Release.plist in Resources */ = {isa = PBXBuildFile; fileRef = 6571D51E28E6B6BF00429F3B /* Info-Release.plist */; };
|
||||
6571D52128E6B6BF00429F3B /* Info-Debug.plist in Resources */ = {isa = PBXBuildFile; fileRef = 6571D51F28E6B6BF00429F3B /* Info-Debug.plist */; };
|
||||
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
|
||||
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
99EA63BEFF74B6B7ADAEBDEF /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ADF6B0FDBA1DDA4F867CEC70 /* libPods-Runner.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
);
|
||||
name = "Embed Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
1F108589C7D0BF5C34A3C248 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
3A5AC6D31F5A7A1030FC3BF8 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
6571D51E28E6B6BF00429F3B /* Info-Release.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-Release.plist"; sourceTree = "<group>"; };
|
||||
6571D51F28E6B6BF00429F3B /* Info-Debug.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-Debug.plist"; sourceTree = "<group>"; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
9CD611CF24CE643A5E0C0B24 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
ADF6B0FDBA1DDA4F867CEC70 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
99EA63BEFF74B6B7ADAEBDEF /* libPods-Runner.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
14A66337B48CBC17939BBF46 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
ADF6B0FDBA1DDA4F867CEC70 /* libPods-Runner.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */,
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */,
|
||||
);
|
||||
name = Flutter;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146E51CF9000F007C117D = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9740EEB11CF90186004384FC /* Flutter */,
|
||||
97C146F01CF9000F007C117D /* Runner */,
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
AEE6E7F56B8AA316830948A5 /* Pods */,
|
||||
14A66337B48CBC17939BBF46 /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146EF1CF9000F007C117D /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97C146EE1CF9000F007C117D /* Runner.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146F01CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
|
||||
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
||||
6571D51F28E6B6BF00429F3B /* Info-Debug.plist */,
|
||||
6571D51E28E6B6BF00429F3B /* Info-Release.plist */,
|
||||
97C146F11CF9000F007C117D /* Supporting Files */,
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
|
||||
);
|
||||
path = Runner;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146F11CF9000F007C117D /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97C146F21CF9000F007C117D /* main.m */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
AEE6E7F56B8AA316830948A5 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9CD611CF24CE643A5E0C0B24 /* Pods-Runner.debug.xcconfig */,
|
||||
3A5AC6D31F5A7A1030FC3BF8 /* Pods-Runner.release.xcconfig */,
|
||||
1F108589C7D0BF5C34A3C248 /* Pods-Runner.profile.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
97C146ED1CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
D771FE9912B17E23AC9C6248 /* [CP] Check Pods Manifest.lock */,
|
||||
9740EEB61CF901F6004384FC /* Run Script */,
|
||||
97C146EA1CF9000F007C117D /* Sources */,
|
||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||
97C146EC1CF9000F007C117D /* Resources */,
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
B4F2CBFBCA64E3A3BF0BC4D0 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Runner;
|
||||
productName = Runner;
|
||||
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
97C146E61CF9000F007C117D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1020;
|
||||
ORGANIZATIONNAME = "";
|
||||
TargetAttributes = {
|
||||
97C146ED1CF9000F007C117D = {
|
||||
CreatedOnToolsVersion = 7.3.1;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
|
||||
compatibilityVersion = "Xcode 9.3";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 97C146E51CF9000F007C117D;
|
||||
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
97C146ED1CF9000F007C117D /* Runner */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
97C146EC1CF9000F007C117D /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
|
||||
6571D52028E6B6BF00429F3B /* Info-Release.plist in Resources */,
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
||||
6571D52128E6B6BF00429F3B /* Info-Debug.plist in Resources */,
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Thin Binary";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
|
||||
};
|
||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Run Script";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
||||
};
|
||||
B4F2CBFBCA64E3A3BF0BC4D0 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
D771FE9912B17E23AC9C6248 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
97C146EA1CF9000F007C117D /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
|
||||
97C146F31CF9000F007C117D /* main.m in Sources */,
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
97C146FB1CF9000F007C117D /* Base */,
|
||||
);
|
||||
name = Main.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
97C147001CF9000F007C117D /* Base */,
|
||||
);
|
||||
name = LaunchScreen.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
249021D3217E4FDB00AE95B9 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SUPPORTED_PLATFORMS = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Profile;
|
||||
};
|
||||
249021D4217E4FDB00AE95B9 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = A2YNUJF7T7;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = K6329CYD7G;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.aliyun.fplayerDemo;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = AliLive_iOS_development;
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = aliyun_dev;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Profile;
|
||||
};
|
||||
97C147031CF9000F007C117D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
97C147041CF9000F007C117D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SUPPORTED_PLATFORMS = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
97C147061CF9000F007C117D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = A2YNUJF7T7;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = K6329CYD7G;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.aliyun.fplayerDemo;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = AliLive_iOS_development;
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = aliyun_dev;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
97C147071CF9000F007C117D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = A2YNUJF7T7;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = K6329CYD7G;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.aliyun.fplayerDemo;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = AliLive_iOS_development;
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = aliyun_dev;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
97C147031CF9000F007C117D /* Debug */,
|
||||
97C147041CF9000F007C117D /* Release */,
|
||||
249021D3217E4FDB00AE95B9 /* Profile */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
97C147061CF9000F007C117D /* Debug */,
|
||||
97C147071CF9000F007C117D /* Release */,
|
||||
249021D4217E4FDB00AE95B9 /* Profile */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 97C146E61CF9000F007C117D /* Project object */;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1020"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Profile"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,6 @@
|
|||
#import <Flutter/Flutter.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : FlutterAppDelegate
|
||||
|
||||
@end
|
|
@ -0,0 +1,13 @@
|
|||
#import "AppDelegate.h"
|
||||
#import "GeneratedPluginRegistrant.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
[GeneratedPluginRegistrant registerWithRegistry:self];
|
||||
// Override point for customization after application launch.
|
||||
return [super application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,122 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "83.5x83.5",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "Icon-App-1024x1024@1x.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 564 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.5 KiB |
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 68 B |
After Width: | Height: | Size: 68 B |
After Width: | Height: | Size: 68 B |
|
@ -0,0 +1,5 @@
|
|||
# Launch Screen Assets
|
||||
|
||||
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
|
||||
|
||||
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="LaunchImage" width="168" height="185"/>
|
||||
</resources>
|
||||
</document>
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Flutter View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>flutter_aliplayer_example</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>请求使用摄像头</string>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>audio</string>
|
||||
</array>
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIRequiresFullScreen</key>
|
||||
<true/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>NSLocalNetworkUsageDescription</key>
|
||||
<string>Allow Flutter tools on your computer to connect and debug your application.This prompt will not appear on release builds.</string>
|
||||
<key>NSBonjourServices</key>
|
||||
<array>
|
||||
<string>_dartobservatory._tcp</string>
|
||||
</array>
|
||||
<key>io.flutter.embedded_views_preview</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,64 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>flutter_aliplayer_example</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>请求使用摄像头</string>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>audio</string>
|
||||
</array>
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIRequiresFullScreen</key>
|
||||
<true/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>io.flutter.embedded_views_preview</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,9 @@
|
|||
#import <Flutter/Flutter.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|