feature/5.5.6.0 v5.5.6.0
詹力 2023-12-06 11:23:26 +08:00
commit 6a8df25f95
173 changed files with 19250 additions and 0 deletions

36
.gitignore vendored Normal file
View File

@ -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
.pubignore Normal file
View File

19
.vscode/launch.json vendored Normal file
View File

@ -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"
}
]
}

84
CHANGELOG.md Normal file
View File

@ -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

22
LICENSE Normal file
View File

@ -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.

404
README.md Normal file
View File

@ -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.51.01.52.0
fAliplayer.setRate(1.0);
//切换多码率,自动码率切换
///在prepare成功之后通过getMediaInfo可以获取到各个码流的信息即TrackInfo
fAliplayer.getMediaInfo().then((value) {
//value 为 mapvalue['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();
```

8
android/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures

52
android/build.gradle Normal file
View File

@ -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'
}

View File

@ -0,0 +1,4 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true

View File

@ -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

1
android/settings.gradle Normal file
View File

@ -0,0 +1 @@
rootProject.name = 'flutter_aliplayer'

View File

@ -0,0 +1,3 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.alibaba.fplayer.flutter_aliplayer">
</manifest>

View File

@ -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) {
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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) {
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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();
}
}

View File

@ -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;
}
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
});
}
}
}

View File

@ -0,0 +1,9 @@
package com.alibaba.fplayer.flutter_aliplayer.listener;
interface FlutterAliRenderViewListener {
void onCreated();
void onSizeChanged();
void onDestroy();
}

45
example/.gitignore vendored Normal file
View File

@ -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

10
example/.metadata Normal file
View File

@ -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

16
example/README.md Normal file
View File

@ -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.

11
example/android/.gitignore vendored Normal file
View File

@ -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

View File

@ -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 '../..'
}

View File

@ -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>

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -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>

View File

@ -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>

View File

@ -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
}

Binary file not shown.

View File

@ -0,0 +1,5 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
extra-gen-snapshot-options=--obfuscate

View File

@ -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

6
example/android/proguard-rules.pro vendored Normal file
View File

@ -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.**

View File

@ -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"

View File

@ -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

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

32
example/ios/.gitignore vendored Normal file
View File

@ -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

View File

@ -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>

View File

@ -0,0 +1,2 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@ -0,0 +1,2 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

51
example/ios/Podfile Normal file
View File

@ -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

89
example/ios/Podfile.lock Normal file
View File

@ -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

View File

@ -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 */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1,6 @@
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : FlutterAppDelegate
@end

View File

@ -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

View File

@ -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"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -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"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

View File

@ -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.

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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]));
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More