commit ea9ffa06ffc93d43dc9e4bc45b49826142c69ad1 Author: xuhuixiang Date: Fri Feb 6 14:55:21 2026 +0800 集成完直播后提交代码 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..564201e --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +*.so filter=lfs diff=lfs merge=lfs -text +*.a filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.yuv filter=lfs diff=lfs merge=lfs -text +*.pcm filter=lfs diff=lfs merge=lfs -text +*.aar filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1c4e6e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +*.iml +.gradle +/local.properties +*.idea/ +*.vscode/ +log/ +*.log +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +*.project +*.settings/ +*.classpath +AndroidThirdParty/ +out/ +AlivcLivePusher_Demo_Android/ +outZip/ +test.* \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f4a661c --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 MediaBox-Demos + +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. diff --git a/LiveApp/.gitignore b/LiveApp/.gitignore new file mode 100644 index 0000000..956c004 --- /dev/null +++ b/LiveApp/.gitignore @@ -0,0 +1,2 @@ +/build +/release \ No newline at end of file diff --git a/LiveApp/build.gradle b/LiveApp/build.gradle new file mode 100644 index 0000000..5366173 --- /dev/null +++ b/LiveApp/build.gradle @@ -0,0 +1,110 @@ +import java.text.SimpleDateFormat + +apply plugin: 'com.android.application' +apply from: './dependencies.gradle' + +ext.MTL_buildId = getEnvValue("MUPP_BUILD_ID", 'localbuild') +ext.MTL_buildTimestamp = new SimpleDateFormat("yyMMddHHmmss").format(new Date()) + +//@keria:cannot make method static +String getEnvValue(key, defValue) { + def val = System.getProperty(key) + if (null != val) { + return val + } + val = System.getenv(key) + if (null != val) { + return val + } + return defValue +} + +android { + lintOptions { + checkReleaseBuilds false + abortOnError false + } + signingConfigs { + release { + keyAlias 'key0' + keyPassword 'livepush' + storeFile file('livepush.jks') + storePassword 'livepush' + } + debug { + keyAlias 'key0' + keyPassword 'livepush' + storeFile file('livepush.jks') + storePassword 'livepush' + } + } + dexOptions { + javaMaxHeapSize "3g" + } + compileSdkVersion androidCompileSdkVersion + buildToolsVersion androidBuildToolsVersion + defaultConfig { + applicationId "com.alivc.live.pusher.demo" + minSdkVersion androidMinSdkVersion + targetSdkVersion androidTargetSdkVersion + versionCode 1 + versionName "1.0" + + javaCompileOptions { + annotationProcessorOptions { + arguments = [AROUTER_MODULE_NAME: 'live'] + } + } + } + buildTypes { + release { + debuggable false + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + signingConfig signingConfigs.release + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + packagingOptions { + exclude 'META-INF/NOTICE' + exclude 'META-INF/LICENSE' + exclude 'META-INF/notice.txt' + exclude 'META-INF/license.txt' +// 解决animoji和queen库so重复问题 + pickFirst '**/libc++_shared.so' + pickFirst '**/libMNN.so' + pickFirst '**/libMNN_CL.so' + pickFirst '**/libalivcffmpeg.so' + } + publishNonDefault true + lintOptions { + checkReleaseBuilds false + abortOnError false + disable 'MissingTranslation' + } + applicationVariants.all { variant -> + variant.outputs.all { output -> + outputFileName = "${project.name}-${sdk_type.split('_').last()}-${variant.buildType.name}-${MTL_buildId}.apk" + } + } + allprojects { + repositories { + flatDir { + dirs 'src/main/libs' + } + } + } + resourcePrefix "push_" +} + +dependencies { + implementation externalAndroidDesign + + // 手动集成:本地依赖SDK + // implementation fileTree(dir: 'src/main/libs', include: ['*.jar', '*.aar']) +} diff --git a/LiveApp/build_lib.gradle b/LiveApp/build_lib.gradle new file mode 100644 index 0000000..4a0811d --- /dev/null +++ b/LiveApp/build_lib.gradle @@ -0,0 +1,22 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion androidCompileSdkVersion + buildToolsVersion androidBuildToolsVersion + defaultConfig { + minSdkVersion androidMinSdkVersion + + javaCompileOptions { + annotationProcessorOptions { + arguments = [AROUTER_MODULE_NAME :'live' ] + } + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +apply from: './dependencies.gradle' \ No newline at end of file diff --git a/LiveApp/dependencies.gradle b/LiveApp/dependencies.gradle new file mode 100644 index 0000000..2e6380e --- /dev/null +++ b/LiveApp/dependencies.gradle @@ -0,0 +1,18 @@ +dependencies { + implementation fileTree(dir: 'libs', include: ['*.aar']) + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.1.0' + implementation externalAndroidMultiDex + implementation externalARouter + + implementation project(':LiveBasic:live_push') + implementation project(':LiveBasic:live_pull') + implementation project(':LiveBasic:live_pull_rts') + implementation project(':LiveBasic:live_screencap') + + implementation project(':LiveInteractive:live_pk') + implementation project(':LiveInteractive:live_interactive') + implementation project(':LiveInteractive:live_barestream') + + annotationProcessor externalARouterCompiler +} \ No newline at end of file diff --git a/LiveApp/livepush.jks b/LiveApp/livepush.jks new file mode 100644 index 0000000..bc9620d Binary files /dev/null and b/LiveApp/livepush.jks differ diff --git a/LiveApp/proguard-rules.pro b/LiveApp/proguard-rules.pro new file mode 100644 index 0000000..7cc6460 --- /dev/null +++ b/LiveApp/proguard-rules.pro @@ -0,0 +1,92 @@ +# This is a configuration file for ProGuard. +# http:#proguard.sourceforge.net/index.html#manual/usage.html + +# 指定代码的压缩级别 +-optimizationpasses 5 +#混淆时不使用大小写混合类名 +-dontusemixedcaseclassnames +#不跳过library中的非public的类 +-dontskipnonpubliclibraryclasses +#打印混淆的详细信息 +-verbose +#忽略警告 +-ignorewarnings +# Optimization is turned off by default. Dex does not like code run +# through the ProGuard optimize and preverify steps (and performs some +# of these optimizations on its own). +#不进行优化,建议使用此选项,理由见上 +-dontoptimize +#不进行预校验,预校验是作用在Java平台上的,Android平台上不需要这项功能,去掉之后还可以加快混淆速度 +-dontpreverify +# Note that if you want to enable optimization, you cannot just +# include optimization flags in your own project configuration file; +# instead you will need to point to the +# "proguard-android-optimize.txt" file instead of this one from your +# project.properties file. + +#保留注解参数 +-keepattributes *Annotation* +#保留Google原生服务需要的类 +-keep public class com.google.vending.licensing.ILicensingService +-keep public class com.android.vending.licensing.ILicensingService + +#2023-01-03最新混淆规则(直播SDK版本>=4.4.9,一体化SDK版本>=1.7.0) +#SDK内部已做混淆,外部全部keep即可。 +#混淆规则请见官网文档:https://help.aliyun.com/zh/live/developer-reference/integrate-push-sdk-for-android +-keep class org.webrtc.** { *; } +-keep class com.alivc.** { *; } +-keep class com.aliyun.** { *; } +-keep class com.cicada.** { *; } +#2023-01-03最新混淆规则(直播SDK版本>=4.4.9,一体化SDK版本>=1.7.0) + +-keep public class com.alibaba.android.arouter.routes.**{*;} +-keep public class com.alibaba.android.arouter.facade.**{*;} +-keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;} + +# 如果使用了 byType 的方式获取 Service,需添加下面规则,保护接口 +-keep interface * implements com.alibaba.android.arouter.facade.template.IProvider + +-keep class android.** { *;} + +# For native methods, see http:#proguard.sourceforge.net/manual/examples.html#native +#保留native方法的类名和方法名 +-keepclasseswithmembernames class * { + native ; +} + +# keep setters in Views so that animations can still work. +# see http:#proguard.sourceforge.net/manual/examples.html#beans +#保留自定义View,如"属性动画"中的set/get方法 +-keepclassmembers public class * extends android.view.View { + void set*(***); + *** get*(); +} + +# We want to keep methods in Activity that could be used in the XML attribute onClick +#保留Activity中参数是View的方法,如XML中配置android:onClick=”buttonClick”属性,Activity中调用的buttonClick(View view)方法 +-keepclassmembers class * extends android.app.Activity { + public void *(android.view.View); +} + +# For enumeration classes, see http:#proguard.sourceforge.net/manual/examples.html#enumerations +#保留混淆枚举中的values()和valueOf()方法 +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +#Parcelable实现类中的CREATOR字段是绝对不能改变的,包括大小写 +-keepclassmembers class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator CREATOR; +} + +#R文件中的所有记录资源id的静态字段 +-keepclassmembers class **.R$* { + public static ; +} + +# The support library contains references to newer platform versions. +# Dont warn about those in case this app is linking against an older +# platform version. We know about them, and they are safe. +#忽略support包因为版本兼容产生的警告 +-dontwarn android.support.** \ No newline at end of file diff --git a/LiveApp/src/main/AndroidManifest.xml b/LiveApp/src/main/AndroidManifest.xml new file mode 100644 index 0000000..f5b74ea --- /dev/null +++ b/LiveApp/src/main/AndroidManifest.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LiveApp/src/main/assets/.gitkeep b/LiveApp/src/main/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/LiveApp/src/main/assets/alivc_resource/441.pcm b/LiveApp/src/main/assets/alivc_resource/441.pcm new file mode 100644 index 0000000..c483e67 --- /dev/null +++ b/LiveApp/src/main/assets/alivc_resource/441.pcm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:986c8c9c783782fca860f9d25f113d215cff978bd301a7b944cbf6b4040de2a2 +size 2116762 diff --git a/LiveApp/src/main/assets/alivc_resource/BGM/Axol.mp3 b/LiveApp/src/main/assets/alivc_resource/BGM/Axol.mp3 new file mode 100644 index 0000000..0b90dfa Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/BGM/Axol.mp3 differ diff --git a/LiveApp/src/main/assets/alivc_resource/BGM/Pas de Deux 5s.mp3 b/LiveApp/src/main/assets/alivc_resource/BGM/Pas de Deux 5s.mp3 new file mode 100644 index 0000000..76e0825 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/BGM/Pas de Deux 5s.mp3 differ diff --git a/LiveApp/src/main/assets/alivc_resource/BGM/Pas de Deux.mp3 b/LiveApp/src/main/assets/alivc_resource/BGM/Pas de Deux.mp3 new file mode 100644 index 0000000..b395f1f Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/BGM/Pas de Deux.mp3 differ diff --git a/LiveApp/src/main/assets/alivc_resource/background_push.png b/LiveApp/src/main/assets/alivc_resource/background_push.png new file mode 100644 index 0000000..98bf544 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/background_push.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/background_push_land.png b/LiveApp/src/main/assets/alivc_resource/background_push_land.png new file mode 100644 index 0000000..427e308 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/background_push_land.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/poor_network.png b/LiveApp/src/main/assets/alivc_resource/poor_network.png new file mode 100644 index 0000000..79b7303 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/poor_network.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/poor_network_land.png b/LiveApp/src/main/assets/alivc_resource/poor_network_land.png new file mode 100644 index 0000000..9e154bb Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/poor_network_land.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/config.json b/LiveApp/src/main/assets/alivc_resource/qizi/config.json new file mode 100644 index 0000000..2f0dbcb --- /dev/null +++ b/LiveApp/src/main/assets/alivc_resource/qizi/config.json @@ -0,0 +1,97 @@ +{ + + "pid": 2, + "fid": 2, + "du": 2.04, + "type": 2, + "x": 320.0, + "y": 320.0, + "w": 350.0, + "h": 580.0, + "a": 0.0, + "fx": 0.0, + "fy": 0.0, + "fw": 0.0, + "fh": 0.0, + "n": "qizi", + "c": 68.0, + "kerneframe": 51, + + "pExtend": 1, + "extendSection":0, + "frameArry": [ + {"time":0,"pic":0}, + {"time":0.03,"pic":1}, + {"time":0.06,"pic":2}, + {"time":0.09,"pic":3}, + {"time":0.12,"pic":4}, + {"time":0.15,"pic":5}, + {"time":0.18,"pic":6}, + {"time":0.21,"pic":7}, + {"time":0.24,"pic":8}, + {"time":0.27,"pic":9}, + {"time":0.3,"pic":10}, + {"time":0.33,"pic":11}, + {"time":0.36,"pic":12}, + {"time":0.39,"pic":13}, + {"time":0.42,"pic":14}, + {"time":0.45,"pic":15}, + {"time":0.48,"pic":16}, + {"time":0.51,"pic":17}, + {"time":0.54,"pic":18}, + {"time":0.57,"pic":19}, + {"time":0.6,"pic":20}, + {"time":0.63,"pic":21}, + {"time":0.66,"pic":22}, + {"time":0.69,"pic":23}, + {"time":0.72,"pic":24}, + {"time":0.75,"pic":25}, + {"time":0.78,"pic":26}, + {"time":0.81,"pic":27}, + {"time":0.84,"pic":28}, + {"time":0.87,"pic":29}, + {"time":0.9,"pic":30}, + {"time":0.93,"pic":31}, + {"time":0.96,"pic":32}, + {"time":0.99,"pic":33}, + {"time":1.02,"pic":34}, + {"time":1.05,"pic":35}, + {"time":1.08,"pic":36}, + {"time":1.11,"pic":37}, + {"time":1.14,"pic":38}, + {"time":1.17,"pic":39}, + {"time":1.2,"pic":40}, + {"time":1.23,"pic":41}, + {"time":1.26,"pic":42}, + {"time":1.29,"pic":43}, + {"time":1.32,"pic":44}, + {"time":1.35,"pic":45}, + {"time":1.38,"pic":46}, + {"time":1.41,"pic":47}, + {"time":1.44,"pic":48}, + {"time":1.47,"pic":49}, + {"time":1.5,"pic":50}, + {"time":1.53,"pic":51}, + {"time":1.56,"pic":52}, + {"time":1.59,"pic":53}, + {"time":1.62,"pic":54}, + {"time":1.65,"pic":55}, + {"time":1.68,"pic":56}, + {"time":1.71,"pic":57}, + {"time":1.74,"pic":58}, + {"time":1.77,"pic":59}, + {"time":1.8,"pic":60}, + {"time":1.83,"pic":61}, + {"time":1.86,"pic":62}, + {"time":1.89,"pic":63}, + {"time":1.92,"pic":64}, + {"time":1.95,"pic":65}, + {"time":1.98,"pic":66}, + {"time":2.01,"pic":67} + ], + + "timeArry": [ + {"beginTime": 0.0,"endTime":2.04, "shrink":1, "minTime":1.02, "maxTime": 0.0} + ] + +} \ No newline at end of file diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi0.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi0.png new file mode 100644 index 0000000..64f3dbd Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi0.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi1.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi1.png new file mode 100644 index 0000000..8d16207 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi1.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi10.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi10.png new file mode 100644 index 0000000..63be8be Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi10.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi11.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi11.png new file mode 100644 index 0000000..63be8be Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi11.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi12.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi12.png new file mode 100644 index 0000000..d434358 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi12.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi13.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi13.png new file mode 100644 index 0000000..e537d79 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi13.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi14.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi14.png new file mode 100644 index 0000000..fe8cfe7 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi14.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi15.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi15.png new file mode 100644 index 0000000..a4d2f75 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi15.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi16.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi16.png new file mode 100644 index 0000000..a4d2f75 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi16.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi17.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi17.png new file mode 100644 index 0000000..c6131cf Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi17.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi18.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi18.png new file mode 100644 index 0000000..2d5272f Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi18.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi19.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi19.png new file mode 100644 index 0000000..014ce6a Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi19.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi2.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi2.png new file mode 100644 index 0000000..e1f926b Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi2.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi20.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi20.png new file mode 100644 index 0000000..8445821 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi20.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi21.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi21.png new file mode 100644 index 0000000..8445821 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi21.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi22.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi22.png new file mode 100644 index 0000000..d6bc2d3 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi22.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi23.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi23.png new file mode 100644 index 0000000..4815533 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi23.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi24.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi24.png new file mode 100644 index 0000000..73f6019 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi24.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi25.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi25.png new file mode 100644 index 0000000..5181326 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi25.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi26.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi26.png new file mode 100644 index 0000000..5181326 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi26.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi27.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi27.png new file mode 100644 index 0000000..193335f Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi27.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi28.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi28.png new file mode 100644 index 0000000..c117a45 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi28.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi29.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi29.png new file mode 100644 index 0000000..6d17194 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi29.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi3.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi3.png new file mode 100644 index 0000000..72afb27 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi3.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi30.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi30.png new file mode 100644 index 0000000..cc273fb Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi30.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi31.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi31.png new file mode 100644 index 0000000..cc273fb Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi31.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi32.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi32.png new file mode 100644 index 0000000..dff3e9a Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi32.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi33.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi33.png new file mode 100644 index 0000000..c78eae8 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi33.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi34.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi34.png new file mode 100644 index 0000000..1a17745 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi34.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi35.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi35.png new file mode 100644 index 0000000..f3eab62 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi35.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi36.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi36.png new file mode 100644 index 0000000..f3eab62 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi36.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi37.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi37.png new file mode 100644 index 0000000..0378160 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi37.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi38.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi38.png new file mode 100644 index 0000000..fa4c2de Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi38.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi39.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi39.png new file mode 100644 index 0000000..110ab0c Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi39.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi4.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi4.png new file mode 100644 index 0000000..eab2acf Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi4.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi40.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi40.png new file mode 100644 index 0000000..f7780b9 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi40.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi41.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi41.png new file mode 100644 index 0000000..f7780b9 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi41.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi42.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi42.png new file mode 100644 index 0000000..4c7cefa Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi42.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi43.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi43.png new file mode 100644 index 0000000..ea4eea5 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi43.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi44.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi44.png new file mode 100644 index 0000000..e4551b3 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi44.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi45.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi45.png new file mode 100644 index 0000000..424a2c5 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi45.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi46.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi46.png new file mode 100644 index 0000000..424a2c5 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi46.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi47.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi47.png new file mode 100644 index 0000000..6b51b2f Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi47.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi48.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi48.png new file mode 100644 index 0000000..5535bd8 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi48.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi49.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi49.png new file mode 100644 index 0000000..3a104ee Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi49.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi5.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi5.png new file mode 100644 index 0000000..658a37a Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi5.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi50.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi50.png new file mode 100644 index 0000000..d3646bd Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi50.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi51.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi51.png new file mode 100644 index 0000000..d3646bd Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi51.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi52.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi52.png new file mode 100644 index 0000000..425a763 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi52.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi53.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi53.png new file mode 100644 index 0000000..5ea13cb Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi53.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi54.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi54.png new file mode 100644 index 0000000..1239aaf Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi54.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi55.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi55.png new file mode 100644 index 0000000..44a4556 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi55.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi56.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi56.png new file mode 100644 index 0000000..44a4556 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi56.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi57.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi57.png new file mode 100644 index 0000000..56bb6c6 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi57.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi58.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi58.png new file mode 100644 index 0000000..72a88f6 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi58.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi59.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi59.png new file mode 100644 index 0000000..c76f3bf Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi59.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi6.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi6.png new file mode 100644 index 0000000..658a37a Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi6.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi60.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi60.png new file mode 100644 index 0000000..daa9f2b Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi60.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi61.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi61.png new file mode 100644 index 0000000..daa9f2b Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi61.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi62.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi62.png new file mode 100644 index 0000000..8a3bc16 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi62.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi63.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi63.png new file mode 100644 index 0000000..814572c Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi63.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi64.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi64.png new file mode 100644 index 0000000..f31c646 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi64.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi65.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi65.png new file mode 100644 index 0000000..f8ca4ea Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi65.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi66.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi66.png new file mode 100644 index 0000000..f8ca4ea Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi66.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi67.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi67.png new file mode 100644 index 0000000..e003e5e Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi67.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi7.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi7.png new file mode 100644 index 0000000..d806c55 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi7.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi8.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi8.png new file mode 100644 index 0000000..72647ef Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi8.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/qizi/qizi9.png b/LiveApp/src/main/assets/alivc_resource/qizi/qizi9.png new file mode 100644 index 0000000..2ec086d Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/qizi/qizi9.png differ diff --git a/LiveApp/src/main/assets/alivc_resource/sound_effect/sound_effect_man_smile.mp3 b/LiveApp/src/main/assets/alivc_resource/sound_effect/sound_effect_man_smile.mp3 new file mode 100644 index 0000000..1c634f6 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/sound_effect/sound_effect_man_smile.mp3 differ diff --git a/LiveApp/src/main/assets/alivc_resource/sound_effect/sound_effect_roar.mp3 b/LiveApp/src/main/assets/alivc_resource/sound_effect/sound_effect_roar.mp3 new file mode 100644 index 0000000..51184b9 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/sound_effect/sound_effect_roar.mp3 differ diff --git a/LiveApp/src/main/assets/alivc_resource/sound_effect/sound_effect_sinister_smile.mp3 b/LiveApp/src/main/assets/alivc_resource/sound_effect/sound_effect_sinister_smile.mp3 new file mode 100644 index 0000000..b9c962c Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/sound_effect/sound_effect_sinister_smile.mp3 differ diff --git a/LiveApp/src/main/assets/alivc_resource/watermark.png b/LiveApp/src/main/assets/alivc_resource/watermark.png new file mode 100644 index 0000000..81f1ee9 Binary files /dev/null and b/LiveApp/src/main/assets/alivc_resource/watermark.png differ diff --git a/LiveApp/src/main/java/com/alivc/live/pusher/demo/LiveApplication.java b/LiveApp/src/main/java/com/alivc/live/pusher/demo/LiveApplication.java new file mode 100644 index 0000000..8c049ab --- /dev/null +++ b/LiveApp/src/main/java/com/alivc/live/pusher/demo/LiveApplication.java @@ -0,0 +1,28 @@ +package com.alivc.live.pusher.demo; + +import android.app.Application; +import android.content.Context; +import android.content.IntentFilter; +import android.net.ConnectivityManager; + +import com.alibaba.android.arouter.launcher.ARouter; +import com.alivc.live.baselive_push.ui.LivePushActivity; +import com.alivc.live.commonutils.ContextUtils; + +public class LiveApplication extends Application { + @Override + protected void attachBaseContext(Context base) { + super.attachBaseContext(base); + } + + @Override + public void onCreate() { + super.onCreate(); + ContextUtils.setContext(this); + ARouter.init(this); + IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + registerReceiver(new LivePushActivity.ConnectivityChangedReceiver(), filter); + PushLaunchManager.launch4All(this); + } +} diff --git a/LiveApp/src/main/java/com/alivc/live/pusher/demo/MainActivity.java b/LiveApp/src/main/java/com/alivc/live/pusher/demo/MainActivity.java new file mode 100644 index 0000000..e024a52 --- /dev/null +++ b/LiveApp/src/main/java/com/alivc/live/pusher/demo/MainActivity.java @@ -0,0 +1,254 @@ +package com.alivc.live.pusher.demo; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Color; +import android.os.Build; +import android.os.Bundle; +import android.text.TextUtils; +import android.text.method.LinkMovementMethod; +import android.view.View; +import android.view.WindowManager; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.PermissionChecker; + +import com.alivc.live.annotations.AlivcLiveMode; +import com.alivc.live.barestream_interactive.InteractiveInputURLActivity; +import com.alivc.live.baselive_pull.ui.PlayerActivity; +import com.alivc.live.baselive_push.ui.PushConfigActivity; +import com.alivc.live.baselive_recording.ui.VideoRecordConfigActivity; +import com.alivc.live.commonbiz.SharedPreferenceUtils; +import com.alivc.live.commonbiz.backdoor.BackDoorActivity; +import com.alivc.live.commonbiz.test.PushDemoTestConstants; +import com.alivc.live.commonui.utils.StatusBarUtil; +import com.alivc.live.commonutils.ContextUtils; +import com.alivc.live.commonutils.FastClickUtil; +import com.alivc.live.interactive_common.InteractiveAppInfoActivity; +import com.alivc.live.interactive_common.InteractiveConstants; +import com.alivc.live.interactive_common.InteractiveInputActivity; +import com.alivc.live.pusher.AlivcLiveBase; + +public class MainActivity extends AppCompatActivity implements View.OnClickListener { + private LinearLayout mLivePushLayout; + private LinearLayout mLivePullCommonPullLayout; + private LinearLayout mLivePullRtcLayout; + private LinearLayout mLiveInteractLayout; + private LinearLayout mPKLiveInteractLayout; + private LinearLayout mInteractiveUrlLayout; + + private TextView mVersion;//推流sdk版本号 + private String mPushUrl; + private TextView mAliyunSDKPrivacy; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + StatusBarUtil.translucent(this, Color.TRANSPARENT); + + check(); + setContentView(R.layout.push_activity_main); + initView(); + if (!permissionCheck()) { + if (Build.VERSION.SDK_INT >= 23) { + ActivityCompat.requestPermissions(this, getPermissions(), PERMISSION_REQUEST_CODE); + } else { + showNoPermissionTip(getString(noPermissionTip[mNoPermissionIndex])); + finish(); + } + } + Intent intent = getIntent(); + mPushUrl = intent.getStringExtra("pushUrl"); + mPushUrl = "rtmp://stream.bab3live.com/live/channel_230"; + + } + + private void check() { + if (!this.isTaskRoot()) { // 当前类不是该Task的根部,那么之前启动 + Intent intent = getIntent(); + if (intent != null) { + String action = intent.getAction(); + if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && Intent.ACTION_MAIN.equals(action)) { // 当前类是从桌面启动的 + finish(); // finish掉该类,直接打开该Task中现存的Activity + } + } + } + } + + private void initView() { + mLivePushLayout = (LinearLayout) findViewById(R.id.push_enter_layout); + mLivePushLayout.setOnClickListener(this); + mLivePullCommonPullLayout = (LinearLayout) findViewById(R.id.pull_common_enter_layout); + mLivePullCommonPullLayout.setOnClickListener(this); + mLivePullRtcLayout = (LinearLayout) findViewById(R.id.pull_enter_layout); + mLivePullRtcLayout.setOnClickListener(this); + mLiveInteractLayout = (LinearLayout) findViewById(R.id.pull_interact_layout); + mInteractiveUrlLayout = (LinearLayout) findViewById(R.id.interactive_url_layout); + mPKLiveInteractLayout = (LinearLayout) findViewById(R.id.pull_pk_layout); + mLiveInteractLayout.setOnClickListener(this); + mPKLiveInteractLayout.setOnClickListener(this); + mInteractiveUrlLayout.setOnClickListener(this); + mVersion = (TextView) findViewById(R.id.push_version); + mVersion.setText(getString(R.string.version_desc) + AlivcLiveBase.getSDKVersion()); + mVersion.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + startActivity(new Intent(MainActivity.this, BackDoorActivity.class)); + return false; + } + }); + + mAliyunSDKPrivacy = findViewById(R.id.aliyun_sdk_privacy); + mAliyunSDKPrivacy.setMovementMethod(LinkMovementMethod.getInstance()); + + mLiveInteractLayout.setVisibility(AlivcLiveBase.isSupportLiveMode(AlivcLiveMode.AlivcLiveInteractiveMode) ? View.VISIBLE : View.GONE); + mPKLiveInteractLayout.setVisibility(AlivcLiveBase.isSupportLiveMode(AlivcLiveMode.AlivcLiveInteractiveMode) ? View.VISIBLE : View.GONE); + mInteractiveUrlLayout.setVisibility(AlivcLiveBase.isSupportLiveMode(AlivcLiveMode.AlivcLiveInteractiveMode) ? View.VISIBLE : View.GONE); + } + + private int mNoPermissionIndex = 0; + private final int PERMISSION_REQUEST_CODE = 1; + private final String[] permissionManifest = { + Manifest.permission.CAMERA, + Manifest.permission.BLUETOOTH, + Manifest.permission.RECORD_AUDIO, + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.INTERNET, + Manifest.permission.BLUETOOTH_CONNECT, + }; + + private final String[] permissionManifest33 = { + Manifest.permission.CAMERA, + Manifest.permission.BLUETOOTH, + Manifest.permission.RECORD_AUDIO, + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.READ_MEDIA_IMAGES, + Manifest.permission.READ_MEDIA_VIDEO, + Manifest.permission.READ_MEDIA_AUDIO, + Manifest.permission.INTERNET, + Manifest.permission.BLUETOOTH_CONNECT, + }; + + public String[] getPermissions() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { + return permissionManifest; + } + return permissionManifest33; + } + + + private final int[] noPermissionTip = { + R.string.no_camera_permission, + R.string.no_record_bluetooth_permission, + R.string.no_record_audio_permission, + R.string.no_read_phone_state_permission, + R.string.no_write_external_storage_permission, + R.string.no_read_external_storage_permission, + R.string.no_internet_permission, + R.string.no_record_bluetooth_permission, + }; + + @SuppressLint("WrongConstant") + private boolean permissionCheck() { + int permissionCheck = PackageManager.PERMISSION_GRANTED; + String permission; + for (int i = 0; i < getPermissions().length; i++) { + permission = getPermissions()[i]; + mNoPermissionIndex = i; + if (PermissionChecker.checkSelfPermission(this, permission) + != PackageManager.PERMISSION_GRANTED) { + permissionCheck = PackageManager.PERMISSION_DENIED; + } + } + if (permissionCheck != PackageManager.PERMISSION_GRANTED) { + return false; + } else { + return true; + } + } + + @Override + public void onClick(View v) { + Intent intent; + int id = v.getId(); + if (id == R.id.push_enter_layout) { + if (FastClickUtil.isProcessing()) { + return; + } + intent = new Intent(MainActivity.this, PushConfigActivity.class); + if (!TextUtils.isEmpty(mPushUrl)) { + intent.putExtra("pushUrl", mPushUrl); + } + startActivity(intent); + } else if (id == R.id.pull_common_enter_layout) { + intent = new Intent(MainActivity.this, VideoRecordConfigActivity.class); + if (!TextUtils.isEmpty(mPushUrl)) { + intent.putExtra("pushUrl", mPushUrl); + } + startActivity(intent); + } else if (id == R.id.pull_enter_layout) { + intent = new Intent(MainActivity.this, PlayerActivity.class); + startActivity(intent); + } else if (id == R.id.pull_interact_layout) { + gotoNextActivityWithScene(InteractiveConstants.SCENE_TYPE_INTERACTIVE_LIVE); + } else if (id == R.id.pull_pk_layout) { + gotoNextActivityWithScene(InteractiveConstants.SCENE_TYPE_PK_LIVE); + } else if (id == R.id.interactive_url_layout) { + intent = new Intent(MainActivity.this, InteractiveInputURLActivity.class); + startActivity(intent); + } + } + + private void gotoNextActivityWithScene(int scene) { + Intent intent; + if (checkInteractiveAPPInfoIfNeed()) { + intent = new Intent(MainActivity.this, InteractiveAppInfoActivity.class); + intent.putExtra(InteractiveConstants.DATA_TYPE_SCENE, scene); + } else { + intent = new Intent(MainActivity.this, InteractiveInputActivity.class); + intent.putExtra(InteractiveConstants.DATA_TYPE_SCENE, scene); + } + startActivity(intent); + } + + private void showNoPermissionTip(String tip) { + Toast.makeText(this, tip, Toast.LENGTH_LONG).show(); + } + + private boolean checkInteractiveAPPInfoIfNeed() { + Context context = ContextUtils.getApplicationContext(); + + // 如果sp里面appInfo都有,返回false,不需要填写 + if (!(TextUtils.isEmpty(SharedPreferenceUtils.getAppId(context)) + || TextUtils.isEmpty(SharedPreferenceUtils.getAppKey(context)) + || TextUtils.isEmpty(SharedPreferenceUtils.getPlayDomain(context)))) { + return false; + } + + // 如果开发调试用的appInfo都有,返回false,不需要填写 + String testAppID = PushDemoTestConstants.getTestInteractiveAppID(); + String testAppKey = PushDemoTestConstants.getTestInteractiveAppKey(); + String testPlayDomain = PushDemoTestConstants.getTestInteractivePlayDomain(); + if (!(PushDemoTestConstants.checkIsPlaceholder(testAppID) + || PushDemoTestConstants.checkIsPlaceholder(testAppKey) + || PushDemoTestConstants.checkIsPlaceholder(testPlayDomain))) { + // 将开发调试用的appInfo写入到sp里面 + SharedPreferenceUtils.setAppInfo(getApplicationContext(), testAppID, testAppKey, testPlayDomain); + return false; + } + + return true; + } + +} diff --git a/LiveApp/src/main/java/com/alivc/live/pusher/demo/PushLaunchManager.java b/LiveApp/src/main/java/com/alivc/live/pusher/demo/PushLaunchManager.java new file mode 100644 index 0000000..1ab2486 --- /dev/null +++ b/LiveApp/src/main/java/com/alivc/live/pusher/demo/PushLaunchManager.java @@ -0,0 +1,119 @@ +package com.alivc.live.pusher.demo; + +import android.content.Context; +import android.os.Environment; +import android.util.Log; + +import androidx.annotation.NonNull; + +import com.alivc.live.commonbiz.BuildConfig; +import com.alivc.live.commonutils.AssetUtil; +import com.alivc.live.commonutils.FileUtil; +import com.alivc.live.pusher.AlivcLiveBase; +import com.alivc.live.pusher.AlivcLiveBaseListener; +import com.alivc.live.pusher.AlivcLivePushConstants; +import com.alivc.live.pusher.AlivcLivePushLogLevel; + +import java.io.File; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Created by keria on 2022/10/12. + *

+ * 直播推流启动类 + * + * @see 阿里云视频直播官网 + *

+ * @see 推流SDK License文档 + * @see 直播连麦文档 + * @see 推流SDK文档 + */ +public class PushLaunchManager { + private static final String TAG = PushLaunchManager.class.getSimpleName(); + + private static final ExecutorService mWorkerThread = Executors.newSingleThreadExecutor(); + + private PushLaunchManager() { + } + + /** + * 启动所有任务 + * + * @param context android context + */ + public static void launch4All(@NonNull Context context) { + launch4LivePushDemo(context); + registerPushSDKLicense(); + launch4Log(context); + } + + /** + * Demo Asset加载等 + * + * @param context android context + */ + private static void launch4LivePushDemo(@NonNull Context context) { + mWorkerThread.execute(() -> { + String targetPath = FileUtil.getInternalFilesFolder(context.getApplicationContext()) + File.separator + "alivc_resource"; + AssetUtil.copyAssetToSdCard(context.getApplicationContext(), "alivc_resource", targetPath); + }); + } + + /** + * 推流SDK申请License + * + * @see 推流SDK License文档 + */ + private static void registerPushSDKLicense() { + AlivcLiveBase.setListener(new AlivcLiveBaseListener() { + @Override + public void onLicenceCheck(AlivcLivePushConstants.AlivcLiveLicenseCheckResultCode alivcLiveLicenseCheckResultCode, String s) { + Log.e(TAG, "onLicenceCheck: " + alivcLiveLicenseCheckResultCode + ", " + s); + } + }); + // 注册推流SDK + AlivcLiveBase.registerSDK(); + } + + /** + * 推流SDK日志配置 + *

+ * 在debug环境下,使用console日志;release环境下,使用file日志; + * + * @param context android context + * @note ADB pull file logs cmd: adb pull /sdcard/Android/data/com.alivc.live.pusher.demo/files/ ~/Downloads/live-logs + */ + private static void launch4Log(@NonNull Context context) { + AlivcLiveBase.setLogLevel(AlivcLivePushLogLevel.AlivcLivePushLogLevelInfo); + AlivcLiveBase.setConsoleEnabled(!BuildConfig.DEBUG); + + String logPath = getLogFilePath(context.getApplicationContext(), "alivc_live"); + // Log file size limit, total = kLogMaxFileSizeInKB * 5 (parts) + int maxPartFileSizeInKB = 100 * 1024 * 1024; // Limit to 100MB for each log part + + // Set up log directory path + AlivcLiveBase.setLogDirPath(logPath, maxPartFileSizeInKB); + } + + private static String getLogFilePath(@NonNull Context context, String dir) { + String logFilePath; + + // Check if the external storage is mounted + if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { + logFilePath = context.getExternalFilesDir(dir).getAbsolutePath(); + } else { + // Fallback to internal storage if external storage is not available + logFilePath = new File(context.getFilesDir(), dir).getAbsolutePath(); + } + + // Ensure the directory exists + File file = new File(logFilePath); + if (!file.exists() && !file.mkdirs()) { + Log.e(TAG, "Failed to create log directory: " + logFilePath); + } + + Log.d(TAG, "Log file path: " + logFilePath); + return logFilePath; + } +} diff --git a/LiveApp/src/main/java/com/alivc/live/pusher/demo/PushMainActivity.java b/LiveApp/src/main/java/com/alivc/live/pusher/demo/PushMainActivity.java new file mode 100644 index 0000000..4f83dec --- /dev/null +++ b/LiveApp/src/main/java/com/alivc/live/pusher/demo/PushMainActivity.java @@ -0,0 +1,217 @@ +package com.alivc.live.pusher.demo; + +import android.Manifest; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Build; +import android.text.TextUtils; + +import androidx.core.app.ActivityCompat; +import androidx.core.content.PermissionChecker; + +import com.alibaba.android.arouter.facade.annotation.Route; +import com.alivc.live.annotations.AlivcLiveMode; +import com.alivc.live.commonui.activity.AUILiveBaseListActivity; +import com.alivc.live.baselive_pull.ui.PlayerActivity; +import com.alivc.live.baselive_pull_rts.InputRtsUrlActivity; +import com.alivc.live.baselive_push.ui.PushConfigActivity; +import com.alivc.live.baselive_recording.ui.VideoRecordConfigActivity; +import com.alivc.live.commonbiz.SharedPreferenceUtils; +import com.alivc.live.commonbiz.test.PushDemoTestConstants; +import com.alivc.live.commonutils.ContextUtils; +import com.alivc.live.commonutils.FastClickUtil; +import com.alivc.live.commonutils.ToastUtils; +import com.alivc.live.interactive_common.InteractiveAppInfoActivity; +import com.alivc.live.interactive_common.InteractiveConstants; +import com.alivc.live.interactive_common.InteractiveInputActivity; +import com.alivc.live.pusher.AlivcLiveBase; + +import java.util.ArrayList; +import java.util.List; + +@Route(path = "/live/MainActivity") +public class PushMainActivity extends AUILiveBaseListActivity { + private static final int INDEX_CAMERA_PUSH = 0; + private static final int INDEX_SCREEN_PUSH = 1; + private static final int INDEX_LOCAL_VIDEO_PUSH = 2; + private static final int INDEX_PULL = 3; + private static final int INDEX_INTERACT_LIVE = 4; + private static final int INDEX_INTERACT_PK_LIVE = 5; + private static final int INDEX_RTS_PULL = 6; + private final int PERMISSION_REQUEST_CODE = 1; + private String[] permissionManifest; + private int mObPermissionsIndex = -1; + + @Override + public int getTitleResId() { + return R.string.push_title_name; + } + + @Override + public boolean showBackBtn() { + return true; + } + + @Override + public List createListData() { + List menu = new ArrayList<>(); + menu.add(new ListModel(INDEX_CAMERA_PUSH, R.drawable.ic_live_push, getResources().getString(R.string.push_enter_name_tv), getResources().getString(R.string.push_enter_name_desc))); + menu.add(new ListModel(INDEX_SCREEN_PUSH, R.drawable.ic_live_player_luping, getResources().getString(R.string.pull_common_enter_name_tv), getResources().getString(R.string.pull_common_enter_name_desc))); +// menu.add(new ListModel(INDEX_LOCAL_VIDEO_PUSH, R.drawable.ic_live_bendi, getResources().getString(R.string.push_local_video_name_tv), "本期忽略")); + menu.add(new ListModel(INDEX_PULL, R.drawable.ic_live_player_laliu, getResources().getString(R.string.pull_rtc_enter_name_tv), getResources().getString(R.string.pull_rtc_enter_name_desc))); + if (AlivcLiveBase.isSupportLiveMode(AlivcLiveMode.AlivcLiveInteractiveMode)) { + menu.add(new ListModel(INDEX_RTS_PULL, R.drawable.ic_live_player_laliu, getResources().getString(R.string.pull_rts_enter_name), "")); + menu.add(new ListModel(INDEX_INTERACT_LIVE, R.drawable.ic_live_interact, getResources().getString(R.string.interact_live), getResources().getString(R.string.interact_live))); + menu.add(new ListModel(INDEX_INTERACT_PK_LIVE, R.drawable.ic_pk_interact, getResources().getString(R.string.pk_live), getResources().getString(R.string.pk_live))); + } + return menu; + } + + @Override + public void onListItemClick(ListModel model) { + if (FastClickUtil.isProcessing()) { + return; + } + if (!permissionCheck()) { + if (mObPermissionsIndex >= 0) { + ToastUtils.show("请手动开启" + noPermissionTip[mObPermissionsIndex] + "权限"); + } + + if (Build.VERSION.SDK_INT >= 23) { + ActivityCompat.requestPermissions(this, permissionManifest, PERMISSION_REQUEST_CODE); + } + return; + } + + + switch (model.index) { + case INDEX_CAMERA_PUSH: + startActivity(new Intent(this, PushConfigActivity.class)); + + break; + case INDEX_SCREEN_PUSH: + startActivity(new Intent(this, VideoRecordConfigActivity.class)); + break; + case INDEX_LOCAL_VIDEO_PUSH: + //0615本期不做 + break; + case INDEX_PULL: + startActivity(new Intent(this, PlayerActivity.class)); + break; + case INDEX_INTERACT_LIVE: + gotoNextActivityWithScene(InteractiveConstants.SCENE_TYPE_INTERACTIVE_LIVE); + break; + case INDEX_INTERACT_PK_LIVE: + gotoNextActivityWithScene(InteractiveConstants.SCENE_TYPE_PK_LIVE); + break; + case INDEX_RTS_PULL: + startActivity(new Intent(this, InputRtsUrlActivity.class)); + break; + default: + break; + } + } + + private void gotoNextActivityWithScene(int scene) { + Intent intent; + if (checkInteractiveAPPInfoIfNeed()) { + intent = new Intent(PushMainActivity.this, InteractiveAppInfoActivity.class); + intent.putExtra(InteractiveConstants.DATA_TYPE_SCENE, scene); + } else { + intent = new Intent(PushMainActivity.this, InteractiveInputActivity.class); + intent.putExtra(InteractiveConstants.DATA_TYPE_SCENE, scene); + } + startActivity(intent); + } + + private final String[] permissionManifest23 = { + Manifest.permission.CAMERA, + Manifest.permission.RECORD_AUDIO, + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.BLUETOOTH, + }; + + + private final String[] permissionManifest31 = { + Manifest.permission.CAMERA, + Manifest.permission.RECORD_AUDIO, + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.BLUETOOTH_CONNECT, + }; + + private final String[] permissionManifest33 = { + Manifest.permission.CAMERA, + Manifest.permission.RECORD_AUDIO, + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.READ_MEDIA_IMAGES, + Manifest.permission.READ_MEDIA_VIDEO, + Manifest.permission.READ_MEDIA_AUDIO, + Manifest.permission.BLUETOOTH_CONNECT, + }; + + private final int[] noPermissionTip = { + R.string.no_camera_permission, + R.string.no_record_audio_permission, + R.string.no_read_phone_state_permission, + R.string.no_write_external_storage_permission, + R.string.no_read_external_storage_permission, + R.string.no_read_bluetooth_connect_permission + }; + + private boolean permissionCheck() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + permissionManifest = permissionManifest33; + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + permissionManifest = permissionManifest31; + } else { + permissionManifest = permissionManifest23; + } + int permissionCheck = PermissionChecker.PERMISSION_GRANTED; + String permission; + for (int i = 0; i < permissionManifest.length; i++) { + permission = permissionManifest[i]; + int state = PermissionChecker.checkSelfPermission(this, permission); + if (state == PermissionChecker.PERMISSION_DENIED) { + permissionCheck = PermissionChecker.PERMISSION_DENIED; + } else if (state == PermissionChecker.PERMISSION_DENIED_APP_OP) { + mObPermissionsIndex = i; + permissionCheck = PermissionChecker.PERMISSION_DENIED_APP_OP; + } + } + if (permissionCheck != PackageManager.PERMISSION_GRANTED) { + return false; + } else { + return true; + } + } + + private boolean checkInteractiveAPPInfoIfNeed() { + Context context = ContextUtils.getApplicationContext(); + + // 如果sp里面appInfo都有,返回false,不需要填写 + if (!(TextUtils.isEmpty(SharedPreferenceUtils.getAppId(context)) + || TextUtils.isEmpty(SharedPreferenceUtils.getAppKey(context)) + || TextUtils.isEmpty(SharedPreferenceUtils.getPlayDomain(context)))) { + return false; + } + + // 如果开发调试用的appInfo都有,返回false,不需要填写 + String testAppID = PushDemoTestConstants.getTestInteractiveAppID(); + String testAppKey = PushDemoTestConstants.getTestInteractiveAppKey(); + String testPlayDomain = PushDemoTestConstants.getTestInteractivePlayDomain(); + if (!(PushDemoTestConstants.checkIsPlaceholder(testAppID) + || PushDemoTestConstants.checkIsPlaceholder(testAppKey) + || PushDemoTestConstants.checkIsPlaceholder(testPlayDomain))) { + // 将开发调试用的appInfo写入到sp里面 + SharedPreferenceUtils.setAppInfo(getApplicationContext(), testAppID, testAppKey, testPlayDomain); + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/LiveApp/src/main/java/com/alivc/live/pusher/demo/SignatureUtils.java b/LiveApp/src/main/java/com/alivc/live/pusher/demo/SignatureUtils.java new file mode 100644 index 0000000..ce7e40e --- /dev/null +++ b/LiveApp/src/main/java/com/alivc/live/pusher/demo/SignatureUtils.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010-2017 Alibaba Group Holding Limited. + */ + +package com.alivc.live.pusher.demo; + +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.Signature; + +import java.security.MessageDigest; + +public class SignatureUtils { + + public static String getSingInfo(Context context) { + try { + PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES); + Signature[] signs = packageInfo.signatures; + Signature sign = signs[0]; + return hexdigest(sign.toByteArray()); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + private static final char[] hexDigits = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102}; + + public static String hexdigest(byte[] paramArrayOfByte) { + try { + MessageDigest localMessageDigest = MessageDigest.getInstance("MD5"); + localMessageDigest.update(paramArrayOfByte); + byte[] arrayOfByte = localMessageDigest.digest(); + char[] arrayOfChar = new char[32]; + int i = 0; + int j = 0; + while (true) { + if (i >= 16) { + return new String(arrayOfChar); + } + int k = arrayOfByte[i]; + int m = j + 1; + arrayOfChar[j] = hexDigits[(0xF & k >>> 4)]; + j = m + 1; + arrayOfChar[m] = hexDigits[(k & 0xF)]; + i++; + } + } catch (Exception localException) { + localException.printStackTrace(); + } + return null; + } +} diff --git a/LiveApp/src/main/libs/.gitkeep b/LiveApp/src/main/libs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/LiveApp/src/main/res/color/color_text_button.xml b/LiveApp/src/main/res/color/color_text_button.xml new file mode 100644 index 0000000..f9f254d --- /dev/null +++ b/LiveApp/src/main/res/color/color_text_button.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/drawable-xxhdpi/app_name.png b/LiveApp/src/main/res/drawable-xxhdpi/app_name.png new file mode 100644 index 0000000..fd75e57 Binary files /dev/null and b/LiveApp/src/main/res/drawable-xxhdpi/app_name.png differ diff --git a/LiveApp/src/main/res/drawable-xxhdpi/homepage_bg.jpg b/LiveApp/src/main/res/drawable-xxhdpi/homepage_bg.jpg new file mode 100644 index 0000000..05a7845 Binary files /dev/null and b/LiveApp/src/main/res/drawable-xxhdpi/homepage_bg.jpg differ diff --git a/LiveApp/src/main/res/drawable-xxhdpi/ic_av_action_bar_back.png b/LiveApp/src/main/res/drawable-xxhdpi/ic_av_action_bar_back.png new file mode 100644 index 0000000..2587c62 Binary files /dev/null and b/LiveApp/src/main/res/drawable-xxhdpi/ic_av_action_bar_back.png differ diff --git a/LiveApp/src/main/res/drawable-xxhdpi/ic_interaction.png b/LiveApp/src/main/res/drawable-xxhdpi/ic_interaction.png new file mode 100644 index 0000000..325f19b Binary files /dev/null and b/LiveApp/src/main/res/drawable-xxhdpi/ic_interaction.png differ diff --git a/LiveApp/src/main/res/drawable-xxhdpi/ic_live_interact.png b/LiveApp/src/main/res/drawable-xxhdpi/ic_live_interact.png new file mode 100644 index 0000000..886a7a7 Binary files /dev/null and b/LiveApp/src/main/res/drawable-xxhdpi/ic_live_interact.png differ diff --git a/LiveApp/src/main/res/drawable-xxhdpi/ic_live_player_laliu.png b/LiveApp/src/main/res/drawable-xxhdpi/ic_live_player_laliu.png new file mode 100644 index 0000000..2523449 Binary files /dev/null and b/LiveApp/src/main/res/drawable-xxhdpi/ic_live_player_laliu.png differ diff --git a/LiveApp/src/main/res/drawable-xxhdpi/ic_live_player_luping.png b/LiveApp/src/main/res/drawable-xxhdpi/ic_live_player_luping.png new file mode 100644 index 0000000..92d60a3 Binary files /dev/null and b/LiveApp/src/main/res/drawable-xxhdpi/ic_live_player_luping.png differ diff --git a/LiveApp/src/main/res/drawable-xxhdpi/ic_live_push.png b/LiveApp/src/main/res/drawable-xxhdpi/ic_live_push.png new file mode 100644 index 0000000..a22cc3c Binary files /dev/null and b/LiveApp/src/main/res/drawable-xxhdpi/ic_live_push.png differ diff --git a/LiveApp/src/main/res/drawable-xxhdpi/ic_pk.png b/LiveApp/src/main/res/drawable-xxhdpi/ic_pk.png new file mode 100644 index 0000000..5adc6bb Binary files /dev/null and b/LiveApp/src/main/res/drawable-xxhdpi/ic_pk.png differ diff --git a/LiveApp/src/main/res/drawable-xxhdpi/ic_pk_interact.png b/LiveApp/src/main/res/drawable-xxhdpi/ic_pk_interact.png new file mode 100644 index 0000000..9eb0fa8 Binary files /dev/null and b/LiveApp/src/main/res/drawable-xxhdpi/ic_pk_interact.png differ diff --git a/LiveApp/src/main/res/drawable-xxhdpi/player_image.png b/LiveApp/src/main/res/drawable-xxhdpi/player_image.png new file mode 100644 index 0000000..3a15046 Binary files /dev/null and b/LiveApp/src/main/res/drawable-xxhdpi/player_image.png differ diff --git a/LiveApp/src/main/res/drawable-xxhdpi/pull_test_image.png b/LiveApp/src/main/res/drawable-xxhdpi/pull_test_image.png new file mode 100644 index 0000000..fd04cc5 Binary files /dev/null and b/LiveApp/src/main/res/drawable-xxhdpi/pull_test_image.png differ diff --git a/LiveApp/src/main/res/drawable-xxhdpi/rtc_pull_image.png b/LiveApp/src/main/res/drawable-xxhdpi/rtc_pull_image.png new file mode 100644 index 0000000..43fd395 Binary files /dev/null and b/LiveApp/src/main/res/drawable-xxhdpi/rtc_pull_image.png differ diff --git a/LiveApp/src/main/res/drawable/bar_black_color.xml b/LiveApp/src/main/res/drawable/bar_black_color.xml new file mode 100644 index 0000000..68b1e68 --- /dev/null +++ b/LiveApp/src/main/res/drawable/bar_black_color.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/drawable/bar_blue_color.xml b/LiveApp/src/main/res/drawable/bar_blue_color.xml new file mode 100644 index 0000000..f1b477f --- /dev/null +++ b/LiveApp/src/main/res/drawable/bar_blue_color.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/drawable/bar_green_color.xml b/LiveApp/src/main/res/drawable/bar_green_color.xml new file mode 100644 index 0000000..51b34d2 --- /dev/null +++ b/LiveApp/src/main/res/drawable/bar_green_color.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/drawable/bar_red_color.xml b/LiveApp/src/main/res/drawable/bar_red_color.xml new file mode 100644 index 0000000..2b0e122 --- /dev/null +++ b/LiveApp/src/main/res/drawable/bar_red_color.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/drawable/bar_yellow_color.xml b/LiveApp/src/main/res/drawable/bar_yellow_color.xml new file mode 100644 index 0000000..a361460 --- /dev/null +++ b/LiveApp/src/main/res/drawable/bar_yellow_color.xml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/drawable/bg_model_shape.xml b/LiveApp/src/main/res/drawable/bg_model_shape.xml new file mode 100644 index 0000000..53f9e2f --- /dev/null +++ b/LiveApp/src/main/res/drawable/bg_model_shape.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/drawable/bg_oval.xml b/LiveApp/src/main/res/drawable/bg_oval.xml new file mode 100644 index 0000000..62ea829 --- /dev/null +++ b/LiveApp/src/main/res/drawable/bg_oval.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/drawable/flash_selector.xml b/LiveApp/src/main/res/drawable/flash_selector.xml new file mode 100644 index 0000000..6eee74f --- /dev/null +++ b/LiveApp/src/main/res/drawable/flash_selector.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/drawable/live_button_white.xml b/LiveApp/src/main/res/drawable/live_button_white.xml new file mode 100644 index 0000000..dce2881 --- /dev/null +++ b/LiveApp/src/main/res/drawable/live_button_white.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/drawable/shape_bg_btn_green.xml b/LiveApp/src/main/res/drawable/shape_bg_btn_green.xml new file mode 100644 index 0000000..53bfe37 --- /dev/null +++ b/LiveApp/src/main/res/drawable/shape_bg_btn_green.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/layout/push_activity_main.xml b/LiveApp/src/main/res/layout/push_activity_main.xml new file mode 100644 index 0000000..f9819ba --- /dev/null +++ b/LiveApp/src/main/res/layout/push_activity_main.xml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LiveApp/src/main/res/mipmap-hdpi/ic_launcher.png b/LiveApp/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..36ee2fc Binary files /dev/null and b/LiveApp/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/LiveApp/src/main/res/mipmap-mdpi/ic_launcher.png b/LiveApp/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..bfb22be Binary files /dev/null and b/LiveApp/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/LiveApp/src/main/res/mipmap-xhdpi/ic_launcher.png b/LiveApp/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..0e86a95 Binary files /dev/null and b/LiveApp/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/LiveApp/src/main/res/mipmap-xxhdpi/camera_flash_on.png b/LiveApp/src/main/res/mipmap-xxhdpi/camera_flash_on.png new file mode 100644 index 0000000..11430e0 Binary files /dev/null and b/LiveApp/src/main/res/mipmap-xxhdpi/camera_flash_on.png differ diff --git a/LiveApp/src/main/res/mipmap-xxhdpi/ic_launcher.png b/LiveApp/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..8ed4b76 Binary files /dev/null and b/LiveApp/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/LiveApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/LiveApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..5fee040 Binary files /dev/null and b/LiveApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/LiveApp/src/main/res/values-en/arrays.xml b/LiveApp/src/main/res/values-en/arrays.xml new file mode 100644 index 0000000..053f855 --- /dev/null +++ b/LiveApp/src/main/res/values-en/arrays.xml @@ -0,0 +1,52 @@ + + + + CPU usage: + Memory usage: + Video capture fps: + + Audio encoder bitrate: + Audio encoder fps: + Video render fps: + Video encoder model: + Video encoder bitrate: + Video encoder fps: + Total fps of video encoder: + Total time costs of video encoder: + Video encoder settings: + Audio output bitrate: + Video output bitrate: + Total Number of audio cache frames: + Total Number of video cache frames: + Video upload fps: + Audio upload fps: + PTS of current uploaded video frame: + PTS of current uploaded audio frame PTS: + PTS of the last video keyframe: + Final video frame in cache: + Final audio frame in cache: + Total size of data uploaded: + Total time costs of pushing + Total number of video frames sent: + Total number of viedo frames dropped: + The times of video frames dropped: + Total times of network disconnected: + Total times of network reconnected: + Video delay duration: + Audio delay duration: + Size of current frame uploaded + + + The max size of video frame in cache: + The max size of audio frame in cache: + The pts of last video frame which is waiting for sending: + The pts of last audio frame which is waiting for sending: + The pts difference of current frame: + The cache size of audio encoder: + The cache size of video encoder: + The cache size of render queue: + The average duration of per frame rendered: + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/values-en/ssdk_country_arrays.xml b/LiveApp/src/main/res/values-en/ssdk_country_arrays.xml new file mode 100644 index 0000000..0d2c4cc --- /dev/null +++ b/LiveApp/src/main/res/values-en/ssdk_country_arrays.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/values-en/ssdk_oks_strings.xml b/LiveApp/src/main/res/values-en/ssdk_oks_strings.xml new file mode 100644 index 0000000..3ea04e7 --- /dev/null +++ b/LiveApp/src/main/res/values-en/ssdk_oks_strings.xml @@ -0,0 +1,2 @@ + + diff --git a/LiveApp/src/main/res/values-en/ssdk_strings.xml b/LiveApp/src/main/res/values-en/ssdk_strings.xml new file mode 100644 index 0000000..b520f07 --- /dev/null +++ b/LiveApp/src/main/res/values-en/ssdk_strings.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/values-en/strings.xml b/LiveApp/src/main/res/values-en/strings.xml new file mode 100644 index 0000000..f6b8dab --- /dev/null +++ b/LiveApp/src/main/res/values-en/strings.xml @@ -0,0 +1,312 @@ + + 180P + 240P + 360P + 480P + 540P + 720P + 1080P + LC + HE-AAC + HEv2-AAC + AAC-LD + Music Mode + + AlivcLive + License declaration + © 2017 Copyright by Alibaba Cloud All rights reserved + Resolution + Target bitrate + 1200 + Min bitrate + 300 + Initial bitrate + Audio bitrate + 1000 + Captrue fps + 20 + Audio sampling rate + Audio profile + Sound track + Single track + Dual track + Video Encoder + H264 + H265 + B Frames + High quality priority + fluency priority + custom + Reconnection duration + Reconnection times + Orientation + Portrait + HomeLeft + HomeRight + Front camera + Preview mirror + Push mirror + Narrowband HD + DisplayMode + scaleToFill + aspectFit + aspectFill + Watermark + Watermark + Setting + Audio only + Video only + Default + Bitrate Control + Main Extern Stream + Pause Image + NetworkPoor Image + Variable Resolution + Auto focus + Beauty + Hardware encoder + Software encoder + Audio Hardware encoder + Asynchronous interface + Start pushing + Start preview + Stop preview + Pause + Resume + Stop pushing + More setting + Restart pushing + Slide right to view log chart + Slide left to view log + Share + DynamicAdd + DynamicRemove + Beauty on + Beauty off + Whitening + Smooth skin + Ruddy + CheekPink + SlimFace + ShortenFace + BigEye + Capture + Render + Encode + Push + Local log + Mic Volume + + Audio fps + Video fps + Bitrate + Video encode + Audio encode + + Buffer + Video render + Video encode + Video upload + Audio encode + Audio upload + + Start preview + Stop preview + Start pushing + Stop pushing + Pause + Resume + Gop + Push url + Pushing + + pusher log: + + Camera usage is not permitted, please open first + Bluetooth is not permitted to record, please open first + Audio is not permitted to record, please open first + Phone state is not permitted to read, please opend first + External storage is not permitted to write, please open first + External storage is not permitted to read, please open first + Bluetooth connect is not permitted to read, please open first + Internet is not permitted to push, please open first + + OK + Success + Failed + Reconnect + + Package lost + Connection lost + The network is unstable, please quit or try again + The network has recovered + Start reconnecting + Reconnection failed + Connection failed + Send Message + Reconnection succeed + Sending data timeout + Restart successfully + + BGM File open Failed + + System error: + SDK error: + Bitrate setting error + Please enter url + Min fps + + No Music + Pause + Resume + Stop + Start + Close Loop + Open Loop + Close Mute + Open Mute + Close Ears + Open Ears + Earphone Mode + Close Denoise + Audio Denoise + Audio Intelligent Denoise + Accompaniment + Voice + Internet music + //老 demo 资源 + + Screen tool + back + Privacy + Privacy Off + Camera + Camera Off + Mix + Mix Off + Mic + Mic Off + You can start other applications and start live... + The screen function has stopped. + Answer + Auth Time + Privacy Key + + Add dynamic failed, id= + + Screen Sharing + Connect Interact + Multi Connect Interact + H5 Compatible + Data Channel + Send Custom Message + External Audio Stream + External Video Stream + Push Dual Audio + Push Screen Share + Multi PK Interact + Camera Pushing + Interact Live + PK Interaction + Interact Setting + Stream Ingest for Video + Live Streaming + Enter the source URL. + Enter the ingest URL. + Confirm + To enable the system to automatically switch to the most suitable resolution, you must enable adaptive bitrate streaming. For more information, see the API reference. + Advanced Settings + You can adjust the video bitrate and frame rate only in custom mode. + Auto Reconnection + Enter + Mirroring + Camera Control + Retouching Switch + Ingest Standby Stream + Only Audio Or Video Stream + Url Auth Setting + Other Features + Stream Ingest Parameters + Ingesting... + Waiting for Stream Ingest... + Ingest To + Data Metrics + Network Detect + Music List + Statistics on Local Videos + Retouching is disabled. Enable retouching and then retry. + Retouching + Background Music + Flash + Camera + Snapshot + Cancel + Retry + Music Operations + Screenshot saved + The floating window permission is required. Obtain the floating window permission and try again. + Enable Later + Enable Now + Stream Ingest Features + /Times + Sent Frame Rate: + send Bitrate: + version:v + pushing_wating + Live + Push Mode + + Interaction Mode + waiting for download external video resources + + Sound Effect + Change Voice + Reverb + Off + Old_man + Baby_Boy + Baby_Girl + Robot + Daimo + KTV + Echo + + Off + Vocal1 + Vocal2 + BathRoom + SmallRoom(bright) + SmallRoom(Dark) + MediumRoom + LargeRoom + ChurchHall + + Alibaba Cloud\nMobile Streaming + This demo is used to demonstrate the major features of +AliLive SDK. + + + Rts Live Streaming + URL + Please enter RTS ultra-low delay playback address + The playback address can be generated by the address generator in the live video console + Start playing + Play + Stop + TraceID acquisition + Common Problem + Playback Failed + Please go to the live video console>Toolbox>Self service problem troubleshooting, and enter the URL to locate the problem of playback failure + Play stuck / high delay + step1 + Please go to Live Video Console>Stream Management>Stream Detection to analyze whether your current streaming network environment is good (whether the frame rate or timestamp is normal) + step2 + If your streaming network is good, please click [TraceID Acquisition] to obtain relevant information and submit a work order for help + Copy + Confirm + Close + The network connection is not successful, and the TraceID information is not currently available + If you encounter problems when experiencing Demo, please submit the following information to the after-sales service in the form of work order + Information copied + Demote + diff --git a/LiveApp/src/main/res/values-zh-rCN/arrays.xml b/LiveApp/src/main/res/values-zh-rCN/arrays.xml new file mode 100644 index 0000000..a0a45a8 --- /dev/null +++ b/LiveApp/src/main/res/values-zh-rCN/arrays.xml @@ -0,0 +1,51 @@ + + + + 当前CPU: + 当前Memory: + 视频采集帧率: + + 音频编码码率: + 音频编码帧率: + 视频渲染帧率: + 视频编码模式: + 视频编码码率: + 视频编码帧率: + 视频编码总帧数: + 视频编码总耗时: + 视频编码器设置参数: + 音频输出码率: + 视频输出码率: + 缓存音频帧总数: + 缓存视频帧总数: + 视频上传帧率: + 音频上传帧率: + 当前上传视频帧PTS: + 当前上传音频帧PTS: + 上一个视频关键帧PTS: + 缓冲区中最后一帧视频: + 缓冲区中最后一帧音频: + 数据上传总大小: + 视频推流总耗时: + 当前视频流已发送总帧数: + 视频丢帧总数: + 视频丢帧次数: + 总的断网次数: + 总的重连次数: + 视频延迟时长: + 音频延迟时长: + 当前上传帧大小: + + + 缓冲队列中曾经最大的视频帧size: + 缓冲队列中曾经最大的音频帧size: + 待发送队列中最后一个视频包的pts: + 待发送队列中最后一个音频包的pts: + 当前发送的音视频包pts diff: + 音频编码器队列中帧缓存数: + 视频编码器队列中帧缓存数: + 渲染队列中帧缓存数: + 每帧平均渲染时长: + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/values-zh-rCN/ssdk_coutry_arrays.xml b/LiveApp/src/main/res/values-zh-rCN/ssdk_coutry_arrays.xml new file mode 100644 index 0000000..0d2c4cc --- /dev/null +++ b/LiveApp/src/main/res/values-zh-rCN/ssdk_coutry_arrays.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/values-zh-rCN/ssdk_oks_strings.xml b/LiveApp/src/main/res/values-zh-rCN/ssdk_oks_strings.xml new file mode 100644 index 0000000..3ea04e7 --- /dev/null +++ b/LiveApp/src/main/res/values-zh-rCN/ssdk_oks_strings.xml @@ -0,0 +1,2 @@ + + diff --git a/LiveApp/src/main/res/values-zh-rCN/ssdk_strings.xml b/LiveApp/src/main/res/values-zh-rCN/ssdk_strings.xml new file mode 100644 index 0000000..a10bb3c --- /dev/null +++ b/LiveApp/src/main/res/values-zh-rCN/ssdk_strings.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/values-zh-rCN/strings.xml b/LiveApp/src/main/res/values-zh-rCN/strings.xml new file mode 100644 index 0000000..3135bea --- /dev/null +++ b/LiveApp/src/main/res/values-zh-rCN/strings.xml @@ -0,0 +1,94 @@ + + + 阿里云直播 + 版权信息 + 阿里云 copyright@2017,阿里巴巴集团 + 分辨率 + + Portrait + + 软编 + + 右滑查看log图表 + 左滑查看log + 分享 + 加贴纸 + 删贴纸 + 开启美颜 + 关闭美颜 + 美白 + 磨皮 + 红润 + 腮红 + 瘦脸 + 收下巴 + 大眼 + 采集 + 渲染 + 编码 + 推流 + + 麦克风音量 + + 各模块audio fps + 各模块video fps + 各模块bitrate + 视频编码 + 音频编码 + + 各模块buffer + 视频渲染 + 视频编码 + 视频上传 + 音频编码 + 音频上传 + + + + 推流地址 + 是否推流 + 窄带高清 + + + 推流参数log: + + 没有权限使用摄像头,请开启摄像头权限 + 没有权限使用蓝牙,请开启蓝牙权限 + 没有权限使用录音,请开启录音权限 + 没有读取用户数据的权限,请开启该权限 + 没有文件写权限,请开启该权限 + 没有文件读权限,请开启该权限 + 没有蓝牙连接权限,请开启该权限 + 没有网络权限,请开启该权限 + + 码率参数设置错误! + //老 demo 资源 + + 录屏工具 + 隐私关 + 摄像头关 + 答题 + + + 截图已保存 + /次 + 发送帧率: + 发送码率: + 版本为:v + 直播 + 录屏推流 + + 摄像头推流 + 手机屏幕采集,支持参数设置 + 手机摄像头/麦克风采集,支持参数设置、基础特效 + 本地视频推流 + + 纯音或纯视频流 + + 推流方向 + 美颜 + + 阿里云\n移动推流 + 本Demo为用于展示阿里云移动推流sdk主要功能 + + diff --git a/LiveApp/src/main/res/values/arrays.xml b/LiveApp/src/main/res/values/arrays.xml new file mode 100644 index 0000000..053f855 --- /dev/null +++ b/LiveApp/src/main/res/values/arrays.xml @@ -0,0 +1,52 @@ + + + + CPU usage: + Memory usage: + Video capture fps: + + Audio encoder bitrate: + Audio encoder fps: + Video render fps: + Video encoder model: + Video encoder bitrate: + Video encoder fps: + Total fps of video encoder: + Total time costs of video encoder: + Video encoder settings: + Audio output bitrate: + Video output bitrate: + Total Number of audio cache frames: + Total Number of video cache frames: + Video upload fps: + Audio upload fps: + PTS of current uploaded video frame: + PTS of current uploaded audio frame PTS: + PTS of the last video keyframe: + Final video frame in cache: + Final audio frame in cache: + Total size of data uploaded: + Total time costs of pushing + Total number of video frames sent: + Total number of viedo frames dropped: + The times of video frames dropped: + Total times of network disconnected: + Total times of network reconnected: + Video delay duration: + Audio delay duration: + Size of current frame uploaded + + + The max size of video frame in cache: + The max size of audio frame in cache: + The pts of last video frame which is waiting for sending: + The pts of last audio frame which is waiting for sending: + The pts difference of current frame: + The cache size of audio encoder: + The cache size of video encoder: + The cache size of render queue: + The average duration of per frame rendered: + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/values/attrs.xml b/LiveApp/src/main/res/values/attrs.xml new file mode 100644 index 0000000..81188fd --- /dev/null +++ b/LiveApp/src/main/res/values/attrs.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/values/ssdk_country_arrays.xml b/LiveApp/src/main/res/values/ssdk_country_arrays.xml new file mode 100644 index 0000000..0d2c4cc --- /dev/null +++ b/LiveApp/src/main/res/values/ssdk_country_arrays.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/values/ssdk_instapaper_strings.xml b/LiveApp/src/main/res/values/ssdk_instapaper_strings.xml new file mode 100644 index 0000000..dd15f89 --- /dev/null +++ b/LiveApp/src/main/res/values/ssdk_instapaper_strings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/values/ssdk_oks_color_drawables.xml b/LiveApp/src/main/res/values/ssdk_oks_color_drawables.xml new file mode 100644 index 0000000..3ea04e7 --- /dev/null +++ b/LiveApp/src/main/res/values/ssdk_oks_color_drawables.xml @@ -0,0 +1,2 @@ + + diff --git a/LiveApp/src/main/res/values/ssdk_oks_strings.xml b/LiveApp/src/main/res/values/ssdk_oks_strings.xml new file mode 100644 index 0000000..3ea04e7 --- /dev/null +++ b/LiveApp/src/main/res/values/ssdk_oks_strings.xml @@ -0,0 +1,2 @@ + + diff --git a/LiveApp/src/main/res/values/ssdk_strings.xml b/LiveApp/src/main/res/values/ssdk_strings.xml new file mode 100644 index 0000000..79fadec --- /dev/null +++ b/LiveApp/src/main/res/values/ssdk_strings.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/LiveApp/src/main/res/values/strings.xml b/LiveApp/src/main/res/values/strings.xml new file mode 100644 index 0000000..27db35a --- /dev/null +++ b/LiveApp/src/main/res/values/strings.xml @@ -0,0 +1,86 @@ + + + AlivcLive + License declaration + © 2017 Copyright by Alibaba Cloud All rights reserved + + Software encode + Slide right to view log chart + Slide left to view log + Share + DynamicAdd + DynamicRemove + Beauty on + Beauty off + Whitening + Smooth skin + Ruddy + CheekPink + SlimFace + ShortenFace + BigEye + Capture + Render + Encode + Push + Mic Volume + + Audio fps + Video fps + Bitrate + Video encode + Audio encode + + Buffer + Video render + Video encode + Video upload + Audio encode + Audio upload + + + Push url + + pusher log: + + Camera usage is not permitted, please open first + Bluetooth is not permitted to record, please open first + Audio is not permitted to record, please open first + Phone state is not permitted to read, please opend first + External storage is not permitted to write, please open first + External storage is not permitted to read, please open first + Bluetooth connect is not permitted to read, please open first + Internet is not permitted to push, please open first + + Bitrate setting error + + Close Denoise + //老 demo 资源 + + Screen tool + Privacy Off + Camera Off + + Answer + + Stream Ingest for Screen Recording + Streams are collected from your screen. You can configure the parameters. + Stream Ingest for Camera + Streams are collected from your cameras and microphone. You can configure the parameters and basic effects. + Stream Ingest for Video + Only Audio Or Video Stream + Pushing + Retouching + Screenshot saved + /Times + Sent Frame Rate + send Bitrate + version:v + Live + + 阿里云\n移动推流 + 本Demo为用于展示阿里云移动推流sdk主要功能 + + 阿里云视频服务隐私权政策 + + diff --git a/LiveApp/src/main/res/values/styles.xml b/LiveApp/src/main/res/values/styles.xml new file mode 100644 index 0000000..5430eb3 --- /dev/null +++ b/LiveApp/src/main/res/values/styles.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/LiveBasic/live_pull/.gitignore b/LiveBasic/live_pull/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/LiveBasic/live_pull/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/LiveBasic/live_pull/build.gradle b/LiveBasic/live_pull/build.gradle new file mode 100644 index 0000000..98e4eb7 --- /dev/null +++ b/LiveBasic/live_pull/build.gradle @@ -0,0 +1,46 @@ +plugins { + id 'com.android.library' +} + +android { + compileSdkVersion androidCompileSdkVersion + buildToolsVersion androidBuildToolsVersion + + defaultConfig { + minSdkVersion androidMinSdkVersion + targetSdkVersion androidTargetSdkVersion + versionCode 1 + versionName "1.0" + + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation externalAndroidDesign + + implementation externalSimpleZXing + + implementation externalRtsSDK + // Add a downgraded version of the player sdk for the live project single build. + if ("true".equalsIgnoreCase(allInOne)) { + api externalPlayerFull + api externalARTC + } else { + api externalPlayerFullDowngrade + api externalARTCDowngrade + } + + implementation project(':LiveCommon:live_commonbiz') +} \ No newline at end of file diff --git a/LiveBasic/live_pull/consumer-rules.pro b/LiveBasic/live_pull/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/LiveBasic/live_pull/src/main/AndroidManifest.xml b/LiveBasic/live_pull/src/main/AndroidManifest.xml new file mode 100644 index 0000000..eb5d044 --- /dev/null +++ b/LiveBasic/live_pull/src/main/AndroidManifest.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/adapter/PlayButtonListAdapter.java b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/adapter/PlayButtonListAdapter.java new file mode 100644 index 0000000..0f13825 --- /dev/null +++ b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/adapter/PlayButtonListAdapter.java @@ -0,0 +1,132 @@ +package com.alivc.live.baselive_pull.adapter; + +import android.annotation.SuppressLint; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.recyclerview.widget.RecyclerView; + +import com.alivc.live.baselive_pull.R; +import com.alivc.live.baselive_pull.bean.Constants; +import com.alivc.live.baselive_pull.listener.ButtonClickListener; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class PlayButtonListAdapter extends RecyclerView.Adapter { + private ButtonClickListener clickListener; + private boolean isItemHide = false; + public void setClickListener(ButtonClickListener clickListener) { + this.clickListener = clickListener; + mButtonEnableMap = new HashMap<>(); + } + + private List mListDatas = new ArrayList<>(); + private Map mButtonEnableMap; + public void setData(List data){ + + if(data == null){ + return; + } + mListDatas.clear(); + mListDatas.addAll(data); + notifyDataSetChanged(); + } + public List getData(){ + return mListDatas; + } + public void hideItems(boolean isItemHide){ + this.isItemHide = isItemHide; + notifyDataSetChanged(); + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.live_recycle_button_item_view, parent, false); + ButtonHolder buttonHolder = new ButtonHolder(view); + return buttonHolder; + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, @SuppressLint("RecyclerView") final int position) { +// position 从 0开始 + ButtonHolder viewHolder= (ButtonHolder) holder; + viewHolder.textView.setText(mListDatas.get(position)); + viewHolder.imageView.setImageResource(Constants.getLive_img_soure().get(mListDatas.get(position))); + viewHolder.imageView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if(clickListener!=null){ + clickListener.onButtonClick(mListDatas.get(position),position); + } + } + }); + boolean enable = true; + if (mButtonEnableMap.containsKey(mListDatas.get(position))){ + enable = mButtonEnableMap.get(mListDatas.get(position)); + } + if(!enable){ + if("开始推流".equalsIgnoreCase(mListDatas.get(position))){ + viewHolder.imageView.setImageResource(R.drawable.live_push_gray); + } + if("数据指标".equalsIgnoreCase(mListDatas.get(position))){ + viewHolder.imageView.setImageResource(R.drawable.live_data_gray); + } + if("麦克风".equalsIgnoreCase(mListDatas.get(position))){ + viewHolder.imageView.setImageResource(R.drawable.live_microphone_gray); + } + if("调节参数".equalsIgnoreCase(mListDatas.get(position))){ + viewHolder.imageView.setImageResource(R.drawable.live_adjust_gray); + } + }else { + if("开始推流".equalsIgnoreCase(mListDatas.get(position))){ + viewHolder.imageView.setImageResource(R.drawable.live_push); + } + if("麦克风".equalsIgnoreCase(mListDatas.get(position))){ + viewHolder.imageView.setImageResource(R.drawable.live_microphone); + } + if("数据指标".equalsIgnoreCase(mListDatas.get(position))){ + viewHolder.imageView.setImageResource(R.drawable.live_data); + } + } + viewHolder.imageView.setEnabled(enable); + //针对数据指标做特殊处理 + if("数据指标".equalsIgnoreCase(mListDatas.get(position))){ + viewHolder.imageView.setEnabled(true); + } + } + @Override + public int getItemCount() { + return mListDatas.size(); + } + + private class ButtonHolder extends RecyclerView.ViewHolder { + private TextView textView; + private ImageView imageView; + public ButtonHolder(View itemView) { + super(itemView); + textView = itemView.findViewById(R.id.tv_anchor_text); + imageView=itemView.findViewById(R.id.iv_anchor); + } + } + + public void setButtonEnable(String buttonName,boolean enable){ + mButtonEnableMap.put(buttonName,enable); + int position = -1; + for (int i = 0; i < mListDatas.size(); i++) { + if (mListDatas.get(i).equals(buttonName)){ + position = i; + } + } + if (position>=0){ + notifyItemChanged(position); + } + } +} + + diff --git a/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/bean/Constants.java b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/bean/Constants.java new file mode 100644 index 0000000..7e6b42e --- /dev/null +++ b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/bean/Constants.java @@ -0,0 +1,65 @@ +package com.alivc.live.baselive_pull.bean; + +import com.alivc.live.baselive_pull.R; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class Constants { + private static List live_push_button; + private static List live_pull_button; + private static List live_play_button; + + private static HashMap live_img_soure; + + public static HashMap getLive_img_soure() { + return live_img_soure; + } + static { + /** + * push页面的按钮 + * */ + live_push_button = new ArrayList<>(); + live_img_soure=new HashMap<>(); + live_img_soure.put("开始推流", R.drawable.live_push); + live_img_soure.put("美颜", R.drawable.live_beauty); + live_img_soure.put("音效",R.drawable.live_sound); + live_img_soure.put("摄像头",R.drawable.live_carmer); + live_img_soure.put("静音",R.drawable.mute_btn); + live_img_soure.put("调节参数",R.drawable.live_adjust_parm); + live_img_soure.put("数据指标",R.drawable.live_data); + live_push_button.add("开始推流"); + live_push_button.add("美颜"); + live_push_button.add("音效"); + live_push_button.add("静音"); + live_push_button.add("摄像头"); + live_push_button.add("调节参数"); + live_push_button.add("数据指标"); + + /** + * pull页面按钮 + */ + live_pull_button = new ArrayList<>(); + live_pull_button.add("暂停观看"); + live_pull_button.add("静音"); + live_pull_button.add("听筒切换"); + live_img_soure.put("暂停观看",R.drawable.finish_play); + live_img_soure.put("听筒切换",R.drawable.telephone_change); + + /** + * play页面按钮 + */ + live_play_button = new ArrayList<>(); + live_play_button.add("暂停观看"); + } + public static List getPushActivityButtonList(){ + return live_push_button; + } + public static List getPullActivityButtonList(){ + return live_pull_button; + } + public static List getPlayActivityButtonList(){ + return live_play_button; + } +} diff --git a/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/bean/rmsbean/RMSCanvas.java b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/bean/rmsbean/RMSCanvas.java new file mode 100644 index 0000000..f07e225 --- /dev/null +++ b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/bean/rmsbean/RMSCanvas.java @@ -0,0 +1,44 @@ +package com.alivc.live.baselive_pull.bean.rmsbean; + +/** + * Auto-generated: 2024-08-06 14:42:42 + */ +public class RMSCanvas { + + private int w; + private int h; + private int bgnd; + + public void setW(int w) { + this.w = w; + } + + public int getW() { + return w; + } + + public void setH(int h) { + this.h = h; + } + + public int getH() { + return h; + } + + public void setBgnd(int bgnd) { + this.bgnd = bgnd; + } + + public int getBgnd() { + return bgnd; + } + + @Override + public String toString() { + return "Canvas{" + + "w=" + w + + ", h=" + h + + ", bgnd=" + bgnd + + '}'; + } +} \ No newline at end of file diff --git a/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/bean/rmsbean/RMSPeriodicBean.java b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/bean/rmsbean/RMSPeriodicBean.java new file mode 100644 index 0000000..7f2dddd --- /dev/null +++ b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/bean/rmsbean/RMSPeriodicBean.java @@ -0,0 +1,66 @@ +package com.alivc.live.baselive_pull.bean.rmsbean; + +import java.util.List; + +/** + * Auto-generated: 2024-08-06 14:42:42 + */ +public class RMSPeriodicBean { + + private RMSCanvas canvas; + private List stream; + private String source; + private String ver; + private long ts; + + public void setCanvas(RMSCanvas canvas) { + this.canvas = canvas; + } + + public RMSCanvas getCanvas() { + return canvas; + } + + public void setStream(List stream) { + this.stream = stream; + } + + public List getStream() { + return stream; + } + + public void setSource(String source) { + this.source = source; + } + + public String getSource() { + return source; + } + + public void setVer(String ver) { + this.ver = ver; + } + + public String getVer() { + return ver; + } + + public void setTs(long ts) { + this.ts = ts; + } + + public long getTs() { + return ts; + } + + @Override + public String toString() { + return "JsonRootBean{" + + "canvas=" + canvas + + ", stream=" + stream + + ", source='" + source + '\'' + + ", ver='" + ver + '\'' + + ", ts=" + ts + + '}'; + } +} \ No newline at end of file diff --git a/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/bean/rmsbean/RMSStream.java b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/bean/rmsbean/RMSStream.java new file mode 100644 index 0000000..b1f5045 --- /dev/null +++ b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/bean/rmsbean/RMSStream.java @@ -0,0 +1,154 @@ +package com.alivc.live.baselive_pull.bean.rmsbean; + +/** + * Auto-generated: 2024-08-06 14:42:42 + */ +public class RMSStream { + + private String uid; + private int paneid; + private int zorder; + private int x; + private int y; + private int w; + private int h; + private int type; + private int status; + private int cameraDisabled; + private int muted; + private int vol; + private int vad; + private int netQuality; + + public void setUid(String uid) { + this.uid = uid; + } + + public String getUid() { + return uid; + } + + public void setPaneid(int paneid) { + this.paneid = paneid; + } + + public int getPaneid() { + return paneid; + } + + public void setZorder(int zorder) { + this.zorder = zorder; + } + + public int getZorder() { + return zorder; + } + + public void setX(int x) { + this.x = x; + } + + public int getX() { + return x; + } + + public void setY(int y) { + this.y = y; + } + + public int getY() { + return y; + } + + public void setW(int w) { + this.w = w; + } + + public int getW() { + return w; + } + + public void setH(int h) { + this.h = h; + } + + public int getH() { + return h; + } + + public void setType(int type) { + this.type = type; + } + + public int getType() { + return type; + } + + public void setStatus(int status) { + this.status = status; + } + + public int getStatus() { + return status; + } + + public void setCameraDisabled(int cameraDisabled) { + this.cameraDisabled = cameraDisabled; + } + + public int getCameraDisabled() { + return cameraDisabled; + } + + public void setMuted(int muted) { + this.muted = muted; + } + + public int getMuted() { + return muted; + } + + public void setVol(int vol) { + this.vol = vol; + } + + public int getVol() { + return vol; + } + + public void setVad(int vad) { + this.vad = vad; + } + + public int getVad() { + return vad; + } + + public void setNetQuality(int netQuality) { + this.netQuality = netQuality; + } + + public int getNetQuality() { + return netQuality; + } + + @Override + public String toString() { + return "Stream{" + + "uid='" + uid + '\'' + + ", paneid=" + paneid + + ", zorder=" + zorder + + ", x=" + x + + ", y=" + y + + ", w=" + w + + ", h=" + h + + ", type=" + type + + ", status=" + status + + ", cameraDisabled=" + cameraDisabled + + ", muted=" + muted + + ", vol=" + vol + + ", vad=" + vad + + ", netQuality=" + netQuality + + '}'; + } +} \ No newline at end of file diff --git a/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/listener/ButtonClickListener.java b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/listener/ButtonClickListener.java new file mode 100644 index 0000000..d66cb9d --- /dev/null +++ b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/listener/ButtonClickListener.java @@ -0,0 +1,5 @@ +package com.alivc.live.baselive_pull.listener; + +public interface ButtonClickListener { + void onButtonClick(String message, int position); +} diff --git a/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/ui/PlayerActivity.java b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/ui/PlayerActivity.java new file mode 100644 index 0000000..9ceacd9 --- /dev/null +++ b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/ui/PlayerActivity.java @@ -0,0 +1,379 @@ +package com.alivc.live.baselive_pull.ui; + +import android.content.DialogInterface; +import android.content.Intent; +import android.content.res.Configuration; +import android.graphics.Color; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.content.ContextCompat; + +import com.acker.simplezxing.activity.CaptureActivity; +import com.alivc.live.baselive_pull.R; +import com.alivc.live.baselive_pull.bean.Constants; +import com.alivc.live.baselive_pull.listener.ButtonClickListener; +import com.alivc.live.baselive_pull.ui.widget.PlayButtonListView; +import com.alivc.live.commonbiz.BuildConfig; +import com.alivc.live.commonbiz.test.PushDemoTestConstants; +import com.alivc.live.commonui.dialog.CommonDialog; +import com.alivc.live.commonui.messageview.AutoScrollMessagesView; +import com.alivc.live.commonui.utils.StatusBarUtil; +import com.alivc.live.commonutils.TextFormatUtil; +import com.alivc.live.commonutils.ToastUtils; +import com.aliyun.player.AliPlayer; +import com.aliyun.player.AliPlayerFactory; +import com.aliyun.player.IPlayer; +import com.aliyun.player.bean.ErrorInfo; +import com.aliyun.player.nativeclass.PlayerConfig; +import com.aliyun.player.source.UrlSource; +import com.cicada.player.utils.Logger; + +import java.util.ArrayList; +import java.util.List; + +/** + * 直播拉流界面 + */ +public class PlayerActivity extends AppCompatActivity implements SurfaceHolder.Callback, ButtonClickListener { + private static final String TAG = "PlayerActivity"; + + private PlayButtonListView mButtonListView; + private SurfaceView mSurfaceView; + private String mPullUrl = ""; + private AliPlayer mAliPlayer; + private EditText mPullUrlET;//拉流地址 + private Button mPullStartBtn;//开始拉流btn + private Button mScanBtn;//扫码 + private boolean isStopPullFlag = false;//是否点击过停止播放 + private boolean isPulling = false; + private StringBuilder mSeiStringBuilder = new StringBuilder(); + private CommonDialog mDialog; + private AutoScrollMessagesView mSeiMessageView; + + static { + try { + if (BuildConfig.MTL_BUILD_FOR_AIO) { + System.loadLibrary("all_in_one"); + } else { + System.loadLibrary("RtsSDK"); + } + } catch (Throwable ignore) { + } + } + + private View mPageVg; + private ImageView mBackBtn; + private View mInputRl; + private TextView mTitleTv; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + StatusBarUtil.translucent(this, Color.TRANSPARENT); + + setContentView(R.layout.activity_player); + initPlayer(); + initView(); + + String initUrl = PushDemoTestConstants.getTestPullUrl(); + if (!initUrl.isEmpty()) { + mPullUrlET.setText(initUrl); + mPullUrl = initUrl; + } + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { +// 当前屏幕为横屏 + } else { +// 当前屏幕为竖屏 + } + } + + private void initPlayer() { + Logger.getInstance(this).enableConsoleLog(true); + Logger.getInstance(this).setLogLevel(Logger.LogLevel.AF_LOG_LEVEL_TRACE); + mAliPlayer = AliPlayerFactory.createAliPlayer(this.getApplicationContext()); + mAliPlayer.setAutoPlay(true); + mAliPlayer.setOnRenderingStartListener(new IPlayer.OnRenderingStartListener() { + @Override + public void onRenderingStart() { + setViewState(true); + } + }); + + mAliPlayer.setOnErrorListener(new IPlayer.OnErrorListener() { + @Override + public void onError(ErrorInfo errorInfo) { + if (mAliPlayer != null) { + mAliPlayer.reload(); + } + if (mDialog == null || !mDialog.isShowing()) { + mDialog = new CommonDialog(PlayerActivity.this); + mDialog.setDialogTitle("Error"); + mDialog.setDialogContent(errorInfo.getMsg()); + mDialog.setConfirmButton(TextFormatUtil.getTextFormat(PlayerActivity.this, R.string.pull_cancel), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + mDialog.setCancelButton(TextFormatUtil.getTextFormat(PlayerActivity.this, R.string.pull_restart), new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + if (mAliPlayer == null) { + initPlayer(); + mSurfaceView = new SurfaceView(PlayerActivity.this); + mSurfaceView.getHolder().addCallback(PlayerActivity.this); + } + UrlSource source = new UrlSource(); + String url = mPullUrlET.getText().toString(); + if (TextUtils.isEmpty(url)) { + return; + } + source.setUri(url); + if (mAliPlayer != null) { + PlayerConfig cfg = mAliPlayer.getConfig(); + if (url.startsWith("artc://")) { + cfg.mMaxDelayTime = 1000; + cfg.mHighBufferDuration = 10; + cfg.mStartBufferDuration = 10; + } + mAliPlayer.setConfig(cfg); + mAliPlayer.setDataSource(source); + mAliPlayer.prepare(); + } + } + }); + mDialog.show(); + } + } + }); + + // TODO keria: Remove the SEI function of the player first, as it will cause bytecode conflicts between the player SDK and the push SDK. +// mAliPlayer.setOnSeiDataListener((payload, uuid, data) -> { +// String msg = new String(data, StandardCharsets.UTF_8); +// String str = "[cdn]: [" + payload + "], " + msg; +// mSeiMessageView.appendMessage(str); +// Log.i(TAG, str); +// +// if (payload == 5) { +// // implementation externalGSON +// Gson gson = new Gson(); +// RMSPeriodicBean rmsPeriodicBean = null; +// try { +// // The sei message may end with \0, if we want to parse the json, we need to trim the string +// rmsPeriodicBean = gson.fromJson(msg.trim(), RMSPeriodicBean.class); +// } catch (Exception e) { +// e.printStackTrace(); +// } finally { +// Log.i(TAG, "rms periodic bean: " + rmsPeriodicBean); +// } +// } +// }); + } + + private void initView() { + mSurfaceView = (SurfaceView) findViewById(R.id.surface_view); + mPageVg = findViewById(R.id.page_bg); + mInputRl = findViewById(R.id.input_rl); + mTitleTv = findViewById(R.id.title); + mButtonListView = (PlayButtonListView) findViewById(R.id.live_buttonlistview); + mSeiMessageView = findViewById(R.id.sei_receive_view); + List data = new ArrayList<>(); + data.addAll(Constants.getPlayActivityButtonList()); + mButtonListView.setData(data); + mButtonListView.setClickListener(this); + mButtonListView.setVisibility(View.GONE); + mSurfaceView.getHolder().addCallback(this); + mScanBtn = (Button) findViewById(R.id.player_scan_image); + mScanBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + startCaptureActivityForResult(); + } + }); + mBackBtn = findViewById(R.id.pull_common_btn_close); + mBackBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mPageVg.getVisibility() == View.GONE) { + onButtonClick("暂停播放", 0); + } else { + finish(); + } + } + }); + mPullUrlET = (EditText) findViewById(R.id.pull_common_push_url); + mPullStartBtn = (Button) findViewById(R.id.pull_common_start_btn); + mPullStartBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + isPulling = true; + startPull(mPullUrlET.getText().toString()); + } + }); + } + + @Override + public void surfaceCreated(SurfaceHolder holder) { + if (mAliPlayer != null) { + mAliPlayer.setSurface(holder.getSurface()); + } + + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + if (mAliPlayer != null) { + mAliPlayer.surfaceChanged(); + } + + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + if (mAliPlayer != null) { + mAliPlayer.setSurface(null); + } + + } + + private void stopPull() { + stopPlay(); + } + + private void startPull(String url) { + if (TextUtils.isEmpty(url)) { + ToastUtils.show(getBaseContext().getResources().getString(R.string.live_pull_addr_error)); + } else { + ToastUtils.show("pulling..."); + startPlay(); + } + } + + private void startCaptureActivityForResult() { + Intent intent = new Intent(PlayerActivity.this, CaptureActivity.class); + startActivityForResult(intent, CaptureActivity.REQ_CODE); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + switch (requestCode) { + case CaptureActivity.REQ_CODE: + switch (resultCode) { + case RESULT_OK: + String pullUrl = data.getStringExtra(CaptureActivity.EXTRA_SCAN_RESULT); + mPullUrlET.setText(pullUrl); + break; + case RESULT_CANCELED: + break; + default: + break; + } + default: + break; + } + } + + public void startPlay() { + isPulling = true; + mSurfaceView.setVisibility(View.VISIBLE); + if (TextUtils.isEmpty(mPullUrl) && TextUtils.isEmpty(mPullUrlET.getText().toString())) { + Toast.makeText(this, "拉流地址为空", Toast.LENGTH_SHORT).show(); + return; + } + if (!TextUtils.isEmpty(mPullUrlET.getText().toString())) { + mPullUrl = mPullUrlET.getText().toString(); + } + UrlSource source = new UrlSource(); + String pullUrl = mPullUrlET.getText().toString(); + source.setUri(pullUrl); + if (mAliPlayer != null) { + PlayerConfig cfg = mAliPlayer.getConfig(); + cfg.mEnableSEI = true; + if (pullUrl.startsWith("artc://")) { + cfg.mMaxDelayTime = 1000; + cfg.mHighBufferDuration = 10; + cfg.mStartBufferDuration = 10; + } + mAliPlayer.setConfig(cfg); + mAliPlayer.setDataSource(source); + mAliPlayer.prepare(); + } + mButtonListView.setVisibility(View.VISIBLE); + } + + /** + * 停止播放 + */ + public void stopPlay() { + if (mAliPlayer != null) { + mAliPlayer.stop(); + } + } + + @Override + protected void onDestroy() { + if (mAliPlayer != null) { + stopPlay(); + mAliPlayer.setSurface(null); + mAliPlayer.release(); + mAliPlayer = null; + } + mSeiStringBuilder.delete(0, mSeiStringBuilder.length()); + super.onDestroy(); + } + + @Override + public void onButtonClick(String message, int position) { + switch (position) { + case 0: + if (isPulling) { + stopPull(); + isPulling = false; + setViewState(false); + } else { + startPull(mPullUrlET.getText().toString()); + isPulling = true; + } + break; + default: + break; + } + } + + private void setViewState(boolean isPlaying) { + if (isPlaying) { + mPageVg.setVisibility(View.GONE); + mButtonListView.setVisibility(View.VISIBLE); + mInputRl.setVisibility(View.GONE); + mTitleTv.setTextColor(Color.WHITE); + mBackBtn.setImageResource(R.drawable.ic_av_live_actionbar_close); + } else { + mPageVg.setVisibility(View.VISIBLE); + mButtonListView.setVisibility(View.GONE); + mInputRl.setVisibility(View.VISIBLE); + mTitleTv.setTextColor(ContextCompat.getColor(this, R.color.border_infrared)); + mBackBtn.setImageResource(R.drawable.ic_av_live_action_bar_black_back); + } + } +} diff --git a/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/ui/widget/MaxHeightLayout.java b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/ui/widget/MaxHeightLayout.java new file mode 100644 index 0000000..6801afc --- /dev/null +++ b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/ui/widget/MaxHeightLayout.java @@ -0,0 +1,71 @@ +package com.alivc.live.baselive_pull.ui.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.widget.LinearLayout; + +import androidx.annotation.Nullable; + +import com.alivc.live.baselive_pull.R; +import com.alivc.live.commonutils.DensityUtil; + +/** + * 设置最大高度的Layout + */ +public class MaxHeightLayout extends LinearLayout { + + private float mMaxRatio = 0.75f; + private float mMaxHeight; + private float mMinHeight; + + public MaxHeightLayout(Context context) { + super(context); + init(); + } + + public MaxHeightLayout(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + initAtts(context, attrs); + init(); + } + + public MaxHeightLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initAtts(context, attrs); + init(); + } + + private void initAtts(Context context, AttributeSet attrs){ + TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.mMaxRatio); + if (attributes != null) { + mMaxRatio = attributes.getFloat(R.styleable.mMaxRatio_linear_max_ratio, 0.75f); + attributes.recycle(); + } + } + + private void init() { + mMaxHeight = mMaxRatio * DensityUtil.getDisplayMetrics(getContext()).heightPixels; + mMinHeight = DensityUtil.dip2px(getContext(), 125); + mMaxHeight = mMaxHeight < mMinHeight ? mMinHeight : mMaxHeight; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int heightMode = MeasureSpec.getMode(heightMeasureSpec); + int heightSize = MeasureSpec.getSize(heightMeasureSpec); + if (heightMode == MeasureSpec.EXACTLY) { + heightSize = heightSize <= mMaxHeight ? heightSize : (int) mMaxHeight; + } + + if (heightMode == MeasureSpec.UNSPECIFIED) { + heightSize = heightSize <= mMaxHeight ? heightSize : (int) mMaxHeight; + } + + if (heightMode == MeasureSpec.AT_MOST) { + heightSize = heightSize <= mMaxHeight ? heightSize : (int) mMaxHeight; + } + int maxHeightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode); + super.onMeasure(widthMeasureSpec, maxHeightMeasureSpec); + } +} diff --git a/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/ui/widget/PlayButtonListView.java b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/ui/widget/PlayButtonListView.java new file mode 100644 index 0000000..fbc725c --- /dev/null +++ b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/ui/widget/PlayButtonListView.java @@ -0,0 +1,105 @@ +package com.alivc.live.baselive_pull.ui.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.FrameLayout; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.alivc.live.baselive_pull.R; +import com.alivc.live.baselive_pull.adapter.PlayButtonListAdapter; +import com.alivc.live.baselive_pull.listener.ButtonClickListener; + +import java.util.List; + +/** + * 底部按钮 + * + * @author xlx + */ +public class PlayButtonListView extends FrameLayout { + private RecyclerView mRecyclerView; + private PlayButtonListAdapter mButtonListAdapter; + private ButtonClickListener clickListener; + private boolean isItemsHide = false; + + public void setClickListener(ButtonClickListener clickListener) { + this.clickListener = clickListener; + } + + + public PlayButtonListView(@NonNull Context context) { + this(context, null); + } + + public PlayButtonListView(@NonNull Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public PlayButtonListView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initView(context); + } + + public void setData(List data) { + mButtonListAdapter.setData(data); + } + + public void hideItems(boolean isItemHide) { + this.isItemsHide = isItemHide; + mButtonListAdapter.hideItems(isItemHide); + if (isItemHide) { + this.setVisibility(INVISIBLE); + } else { + this.setVisibility(VISIBLE); + } + } + + public boolean isItemsHide() { + return isItemsHide; + } + + private void initView(Context context) { + View view = LayoutInflater.from(context).inflate(R.layout.live_button_list, this, true); + initRecyclerView(view); + } + + private void initRecyclerView(View view) { + mRecyclerView = view.findViewById(R.id.live_button_recycle); + mButtonListAdapter = new PlayButtonListAdapter(); + LinearLayoutManager manager = new LinearLayoutManager(PlayButtonListView.this.getContext()); + manager.setOrientation(LinearLayoutManager.HORIZONTAL); + mRecyclerView.setLayoutManager(manager); + mRecyclerView.setAdapter(mButtonListAdapter); + mRecyclerView.addItemDecoration(new SpaceItemDecortation(dip2px(getContext(), 28), getContext())); + mRecyclerView.setItemAnimator(null); + mRecyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER); + mButtonListAdapter.setClickListener(new ButtonClickListener() { + @Override + public void onButtonClick(String message, int position) { + if (clickListener != null) { + clickListener.onButtonClick(message, position); + } + } + }); + } + + /** + * 将dip或dp值转换为px值,保证尺寸大小不变 + * + * @param dipValue + * @param dipValue DisplayMetrics类中属性density + * @return + */ + private static int dip2px(Context context, float dipValue) { + if (context == null || context.getResources() == null) + return 1; + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (dipValue * scale + 0.5f); + } +} diff --git a/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/ui/widget/SpaceItemDecortation.java b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/ui/widget/SpaceItemDecortation.java new file mode 100644 index 0000000..f203d0a --- /dev/null +++ b/LiveBasic/live_pull/src/main/java/com/alivc/live/baselive_pull/ui/widget/SpaceItemDecortation.java @@ -0,0 +1,41 @@ +package com.alivc.live.baselive_pull.ui.widget; + +import android.content.Context; +import android.graphics.Rect; +import android.view.View; + +import androidx.recyclerview.widget.RecyclerView; + +class SpaceItemDecortation extends RecyclerView.ItemDecoration { + private int space;//声明间距 //使用构造函数定义间距 + private Context mContext; + + public SpaceItemDecortation(int space, Context context) { + this.space = space; + this.mContext = context; + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + //获得当前item的位置 + int position = parent.getChildAdapterPosition(view); + if (position == 0) { + outRect.left = dip2px(mContext, 28); + } + outRect.right = this.space; + } + + /** + * 将dip或dp值转换为px值,保证尺寸大小不变 + * + * @param dipValue + * @param dipValue DisplayMetrics类中属性density + * @return + */ + private static int dip2px(Context context, float dipValue) { + if (context == null || context.getResources() == null) + return 1; + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (dipValue * scale + 0.5f); + } +} diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/colour_bg.webp b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/colour_bg.webp new file mode 100644 index 0000000..f4d1203 Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/colour_bg.webp differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/finish_play.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/finish_play.png new file mode 100644 index 0000000..b8c1f4d Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/finish_play.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/ic_av_live_action_bar_black_back.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/ic_av_live_action_bar_black_back.png new file mode 100644 index 0000000..f8130ad Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/ic_av_live_action_bar_black_back.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/ic_av_live_actionbar_close.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/ic_av_live_actionbar_close.png new file mode 100644 index 0000000..432ee80 Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/ic_av_live_actionbar_close.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_adjust_gray.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_adjust_gray.png new file mode 100644 index 0000000..1c05932 Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_adjust_gray.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_adjust_parm.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_adjust_parm.png new file mode 100644 index 0000000..ff7b686 Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_adjust_parm.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_beauty.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_beauty.png new file mode 100644 index 0000000..5c37cc5 Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_beauty.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_carmer.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_carmer.png new file mode 100644 index 0000000..708eceb Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_carmer.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_data.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_data.png new file mode 100644 index 0000000..26d8fbe Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_data.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_data_gray.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_data_gray.png new file mode 100644 index 0000000..c35566a Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_data_gray.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_microphone.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_microphone.png new file mode 100644 index 0000000..0e7ccea Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_microphone.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_microphone_gray.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_microphone_gray.png new file mode 100644 index 0000000..bc832e1 Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_microphone_gray.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_push.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_push.png new file mode 100644 index 0000000..8af5ea8 Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_push.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_push_gray.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_push_gray.png new file mode 100644 index 0000000..f35cf00 Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_push_gray.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_sound.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_sound.png new file mode 100644 index 0000000..092d673 Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/live_sound.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/mute_btn.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/mute_btn.png new file mode 100644 index 0000000..addf81e Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/mute_btn.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/telephone_change.png b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/telephone_change.png new file mode 100644 index 0000000..641ee72 Binary files /dev/null and b/LiveBasic/live_pull/src/main/res/drawable-xxhdpi/telephone_change.png differ diff --git a/LiveBasic/live_pull/src/main/res/drawable/shape_bg_btn_green.xml b/LiveBasic/live_pull/src/main/res/drawable/shape_bg_btn_green.xml new file mode 100644 index 0000000..53bfe37 --- /dev/null +++ b/LiveBasic/live_pull/src/main/res/drawable/shape_bg_btn_green.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/LiveBasic/live_pull/src/main/res/drawable/shape_bg_search.xml b/LiveBasic/live_pull/src/main/res/drawable/shape_bg_search.xml new file mode 100644 index 0000000..cac8f43 --- /dev/null +++ b/LiveBasic/live_pull/src/main/res/drawable/shape_bg_search.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/LiveBasic/live_pull/src/main/res/layout/activity_player.xml b/LiveBasic/live_pull/src/main/res/layout/activity_player.xml new file mode 100644 index 0000000..5cc6644 --- /dev/null +++ b/LiveBasic/live_pull/src/main/res/layout/activity_player.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + +