[
  {
    "path": ".gitignore",
    "content": "*.iml\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n#\n\n*.iml.gradle/\nlocal.properties/\n.idea\n.DS_Store\n/build\n/captures\n\n### Android\ntemplate\n\n# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# Intellij\n.idea/\nworkspace.xml\n\n# Keystore files\n*.jks"
  },
  {
    "path": "README.md",
    "content": "# 重要提醒\nanyRTC 对该版本已经不再维护。[前往新版本](https://github.com/anyRTC/ArAndroidSDK).\n\n**新版本功能如下：**\n- 频道管理\n- 音频管理\n- 视频管理\n- 音频文件播放及混音\n- 音效文件播放管理\n- CDN推流\n- 本地推流CDN组件\n- 本地播放器组件\n- 跨频道流媒体转发\n- 直播导入在线媒体流\n- 视频双流模式\n- 音频自采集自渲染\n- 视频自采集自渲染\n- 耳返功能\n- 。。。\n\n**公司网址： [www.anyrtc.io](https://www.anyrtc.io)**\n\n### anyRTC-RTMPC-Android SDK for Android\n### 简介\n基于RTMP和RTC混合引擎的在线视频连麦互动直播\n\nAndroid 直播（网络自适应码率RTMP publisher）、点播播放器（播放器经过专业优化，可实现秒开RTMP Player）、基于RTMP和RTC混合引擎的视频连麦互动（最多支持4人同时互动）\n\n### 优势\n- 商业级开源代码，高效稳定 超小内存占有率，移动直播针对性极致优化，代码冗余率极低 \n- iOS,Web,PC全平台适配，硬件编解码可保证99%的可用性\n- 接口极简，推流：2个 拉流：2个\n- 底层库C++核心库代码风格采用：Google code style\n- 极简内核，无需再去深扒复杂的FFMpeg代码\n- OpenH264软件编码，FFMpeg软件解码，FAAC/FAAD软件编解码，适配不同系统的硬件编解码统统包含\n- 支持SRS、Nginx-RTMP等标准RTMP服务;同时支持各大CDN厂商的接入\n\n\n\n\n### app体验\n\n##### [点击下载](http://download.anyrtc.io/xuye)\n\n### SDK集成\n# > 方式一[ ![Download](https://api.bintray.com/packages/dyncanyrtc/ar_dev/rtmpc/images/download.svg) ](https://bintray.com/dyncanyrtc/ar_dev/rtmpc/_latestVersion)\n\n添加Jcenter仓库 Gradle依赖：\n\n```\ndependencies {\n  compile 'org.ar:rtmpc_hybrid:3.1.1'\n}\n```\n\n或者 Maven\n```\n<dependency>\n  <groupId>org.ar</groupId>\n  <artifactId>rtmpc_hybrid</artifactId>\n  <version>3.1.1</version>\n  <type>pom</type>\n</dependency>\n```\n\n\n##### 编译环境\n\nAndroidStudio\n\n##### 运行环境\n\nAndroid API 16+\n真机运行\n\n### 如何使用\n\n##### 注册开发者信息\n\n>如果您还未注册anyRTC开发者账号，请登录[anyRTC官网](http://www.anyrtc.io)注册及获取更多的帮助。\n\n##### 替换开发者账号\n在[anyRTC官网](http://www.anyrtc.io)获取了应用ID，应用Token后，替换DEMO中\n**DeveloperInfo**类中的信息即可。推拉流地址需用自己的\n\n### 操作步骤\n\n1. 演示需要两部以及两部以上的手机，装上该demo.\n2. 一部手机创建直播间，另外两部手机在主页，下拉刷新当前直播列表，点击列表进入直播间。\n3. 游客端点击链接按钮，进行连麦。\n\n### 完整文档\nSDK集成，API介绍，详见官方完整文档：[点击查看](https://docs.anyrtc.io/v1/RTMPC/android.html)\n\n### iOS 版 互动连麦\n\n[AR-RTMPC-iOS](https://github.com/AnyRTC/anyRTC-RTMPC-iOS)\n\n\n### 支持的系统平台\n**Android** 4.0及以上\n\n### 支持的CPU架构\n**Android** arm64-v8a  armeabi armeabi-v7a\n\n\n### 注意事项\n1. RTMPC SDK所有回调均在子线程中，所以在回调中操作UI等，应切换主线程。\n2. 注意安卓6.0+动态权限处理。\n3. 常见错误代码请参考[错误码查询](https://www.anyrtc.io/resoure)\n\n\n### 技术支持 \n- anyRTC官方网址：[https://www.anyrtc.io](https://www.anyrtc.io/resoure)\n- QQ技术咨询群：554714720\n- 联系电话:021-65650071-816\n- Email:hi@dync.cc\n\n### 关于直播\n\n本公司有一整套完整直播解决方案。本公司开发者平台www.anyrtc.io。除了基于RTMP协议的直播系统外，我公司还有基于WebRTC的时时交互直播系统、P2P呼叫系统、会议系统等。快捷集成SDK，便可让你的应用拥有时时通话功能。欢迎您的来电~\n\n### License\n\n- RTMPCEngine is available under the MIT license. See the LICENSE file for more info.\n\n\n\n\n\n   \n\n\n\n \n"
  },
  {
    "path": "app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 28\n    buildToolsVersion '27.0.3'\n    defaultConfig {\n        applicationId \"org.ar.rtmpc\"\n        minSdkVersion 16\n        targetSdkVersion 28\n        versionCode 1\n        versionName \"3.0.0\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    repositories {\n        flatDir {\n            dirs 'libs'\n        }\n    }\n}\ndependencies {\n    compile fileTree(include: ['*.jar'], dir: 'libs')\n    compile 'com.android.support:appcompat-v7:28.0.0'\n    compile 'com.android.support:recyclerview-v7:28.0.0'\n    compile 'com.android.support:cardview-v7:28.0.0'\n    compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.22'\n    compile 'com.gyf.barlibrary:barlibrary:2.3.0'\n    compile 'com.yanzhenjie.permission:support:2.0.1'\n    compile 'com.jaredrummler:material-spinner:1.1.0'\n    compile 'com.android.support:design:28.0.0'\n    compile 'com.orhanobut:logger:1.15'\n    compile 'com.yanzhenjie.nohttp:okhttp:1.1.11'\n    compile 'org.ar:rtmpc_hybrid:3.1.0'\n    compile 'com.loopj.android:android-async-http:1.4.9'\n}\n"
  },
  {
    "path": "app/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Fri Mar 15 15:28:49 CST 2019\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.4-all.zip\n"
  },
  {
    "path": "app/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "app/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windows variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in D:\\Android\\android-sdk-windows/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n-keepattributes InnerClasses\n-dontoptimize\n-optimizationpasses 7\n-dontusemixedcaseclassnames\n-dontskipnonpubliclibraryclasses\n-dontpreverify\n-verbose\n-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*\n\n\n-keep public class * extends android.app.Activity\n-keep public class * extends android.app.Application\n-keep public class * extends android.app.Service\n-keep public class * extends android.content.BroadcastReceiver\n-keep public class * extends android.content.ContentProvider\n-keep public class * extends android.app.backup.BackupAgentHelper\n-keep public class * extends android.preference.Preference\n-keep public class com.android.vending.licensing.ILicensingService\n\n\n-keepclasseswithmembernames class * {\n    native <methods>;\n}\n\n-keepclasseswithmembers class * {\n    public <init>(android.content.Context, android.util.AttributeSet);\n}\n\n-keepclasseswithmembers class * {\n    public <init>(android.content.Context, android.util.AttributeSet, int);\n}\n\n-keepclassmembers class * extends android.app.Activity {\n    public void *(android.view.View);\n}\n\n-keep public class * extends android.view.View {\n    public <init>(android.content.Context);\n    public <init>(android.content.Context, android.util.AttributeSet);\n    public <init>(android.content.Context, android.util.AttributeSet, int);\n    public void set*(...);\n}\n\n-keepclassmembers enum * {\n    public static **[] values();\n    public static ** valueOf(java.lang.String);\n}\n\n-keep class * implements android.os.Parcelable {\n    public static final android.os.Parcelable$Creator *;\n}\n\n-keepnames class * implements java.io.Serializable\n\n-keepclassmembers class * implements java.io.Serializable {\n    static final long serialVersionUID;\n    private static final java.io.ObjectStreamField[] serialPersistentFields;\n    !static !transient <fields>;\n    private void writeObject(java.io.ObjectOutputStream);\n    private void readObject(java.io.ObjectInputStream);\n    java.lang.Object writeReplace();\n    java.lang.Object readResolve();\n}\n\n-keepattributes *Annotation*\n-keepattributes Exceptions,InnerClasses,Signature\n-keepattributes SourceFile,LineNumberTable\n\n-keep class **.R$* { *; }\n-dontwarn android.support.v4.**\n-keep class android.support.v4.** { *; }\n-keep interface android.support.v4.** { *; }\n-keep public class * extends android.support.v4.**\n-keep public class * extends android.app.Fragment\n\n-keep class org.anyrtc.model.** { *; }\n\n\n#anyrtc\n-dontwarn org.anyrtc.rtmpc_hybrid.**\n-keep class org.anyrtc.rtmpc_hybrid.**{*;}\n-dontwarn org.webrtc.**\n-keep class org.webrtc.**{*;}\n\n\n -keep class com.gyf.barlibrary.* {*;}\n\n  #Andprermission\n -keepclassmembers class ** {\n     @com.yanzhenjie.permission.PermissionYes <methods>;\n }\n -keepclassmembers class ** {\n     @com.yanzhenjie.permission.PermissionNo <methods>;\n }\n #BaseAdapter\n -keep class com.chad.library.adapter.** {\n    *;\n }"
  },
  {
    "path": "app/src/androidTest/java/org/ar/rtmpc/ApplicationTest.java",
    "content": "package org.ar.rtmpc;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a href=\"http://d.android.com/tools/testing/testing_android.html\">Testing Fundamentals</a>\n */\npublic class ApplicationTest extends ApplicationTestCase<Application> {\n    public ApplicationTest() {\n        super(Application.class);\n    }\n}"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"org.ar.rtmpc\">\n\n    <uses-feature android:name=\"android.hardware.camera\" />\n    <uses-feature android:name=\"android.hardware.camera.autofocus\" />\n    <uses-feature android:name=\"android.hardware.camera.flash\" />\n    <uses-feature\n        android:glEsVersion=\"0x00020000\"\n        android:required=\"true\" />\n\n    <uses-permission android:name=\"android.permission.CAMERA\" />\n    <uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\" />\n    <uses-permission android:name=\"android.permission.RECORD_AUDIO\" />\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n    <uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\" />\n\n\n    <application\n        android:name=\"org.ar.ARApplication\"\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity\n            android:name=\"org.ar.hoster.HosterActivity\"\n            android:configChanges=\"orientation|keyboardHidden|screenSize\"\n            android:windowSoftInputMode=\"adjustPan\" />\n        <activity\n            android:name=\"org.ar.guest.GuestActivity\"\n            android:configChanges=\"orientation|keyboardHidden|screenSize\"\n            android:windowSoftInputMode=\"adjustPan\" />\n        <activity\n            android:name=\"org.ar.guest.AudioGuestActivity\"\n            android:configChanges=\"orientation|keyboardHidden|screenSize\"\n            android:windowSoftInputMode=\"adjustPan\" />\n        <activity\n            android:name=\"org.ar.hoster.AudioHosterActivity\"\n            android:configChanges=\"orientation|keyboardHidden|screenSize\"\n            android:windowSoftInputMode=\"adjustPan\" />\n        <activity\n            android:name=\"org.ar.guest.LiveListActivity\"\n            android:screenOrientation=\"portrait\" />\n        <activity android:name=\"org.ar.SplashActivity\"\n            android:theme=\"@style/SplashTheme\"\n            android:screenOrientation=\"portrait\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "app/src/main/java/org/ar/ARApplication.java",
    "content": "package org.ar;\n\nimport android.app.Application;\n\nimport com.yanzhenjie.nohttp.InitializationConfig;\nimport com.yanzhenjie.nohttp.NoHttp;\n\nimport org.ar.utils.NameUtils;\nimport org.ar.rtmpc_hybrid.ARRtmpcEngine;\n\n/**\n * Created by Skyline on 2016/8/3.\n */\npublic class ARApplication extends Application {\n\n    public static ARApplication mARApplication;\n    private static String NickName=\"\";\n    public static String LIVE_ID=(int)((Math.random()*9+1)*100000)+\"\";//直播间ID\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        mARApplication =this;\n        NickName= NameUtils.getNickName();\n        ARRtmpcEngine.Inst().initEngine(getApplicationContext(), DeveloperInfo.APPID, DeveloperInfo.APPTOKEN);\n\n\n        InitializationConfig  config = InitializationConfig.newBuilder(this)\n                .connectionTimeout(15*1000)\n                .readTimeout(15*1000)\n                .retry(1).build();\n        NoHttp.initialize(config);\n    }\n    public  static Application App(){\n        return mARApplication;\n    }\n\n    public static String getNickName(){\n        return NickName;\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/BaseActivity.java",
    "content": "package org.ar;\n\nimport android.app.ProgressDialog;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.v7.app.AppCompatActivity;\n\nimport com.gyf.barlibrary.ImmersionBar;\n\n/**\n * Created by Skyline on 2016/5/24.\n */\npublic abstract class BaseActivity extends AppCompatActivity {\n    protected ImmersionBar mImmersionBar;\n    ProgressDialog pd;\n    @Override\n    protected void onSaveInstanceState(Bundle outState) {\n        super.onSaveInstanceState(outState);\n    }\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        this.setContentView(this.getLayoutId());\n        mImmersionBar = ImmersionBar.with(this);\n        mImmersionBar.statusBarDarkFont(true,0.2f).init();\n        this.initView(savedInstanceState);\n    }\n    private void ProgressDialog(Context ctx) {\n        pd = new ProgressDialog(ctx);\n        pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);\n        pd.setCancelable(true);\n        pd.setCanceledOnTouchOutside(false);\n        pd.show();\n    }\n    public void showProgressDialog() {\n        if (pd == null) {\n            ProgressDialog(this);\n        }\n        pd.setMessage(\"正在加载...\");\n        pd.show();\n    }\n\n    public void hiddenProgressDialog() {\n        if (pd != null && pd.isShowing()) {\n            pd.cancel();\n        }\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n        if (mImmersionBar != null)\n            mImmersionBar.destroy();\n    }\n\n\n    @Override\n    public void setContentView(int layoutResID) {\n        super.setContentView(layoutResID);\n    }\n\n\n    public void startAnimActivity(Class<?> cls) {\n        startActivity(new Intent(this, cls));\n    }\n\n    public void finishAnimActivity() {\n        finish();\n    }\n\n    public void startAnimActivity(Class<?> cls, Bundle bundle) {\n        Intent intent = new Intent(this, cls);\n        intent.putExtras(bundle);\n        startActivity(intent);\n    }\n\n    public abstract int getLayoutId();\n\n    public abstract void initView(Bundle savedInstanceState);\n\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/DeveloperInfo.java",
    "content": "package org.ar;\n\n\n\npublic class DeveloperInfo {\n\n\n\n\n    public final static String APPID = \"\";\n\n    public final static String APPTOKEN = \"\";\n\n    public final static String PULL_URL = \"\";\n\n    public final static String PUSH_URL= \"\";\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/SplashActivity.java",
    "content": "package org.ar;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.os.Bundle;\n\nimport org.ar.guest.LiveListActivity;\n\npublic class SplashActivity extends Activity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        startActivity(new Intent(this,LiveListActivity.class));\n        finish();\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/adapter/AudioLineAdapter.java",
    "content": "package org.ar.adapter;\n\nimport android.view.View;\nimport android.widget.TextView;\n\nimport com.chad.library.adapter.base.BaseQuickAdapter;\nimport com.chad.library.adapter.base.BaseViewHolder;\n\nimport org.ar.rtmpc.R;\nimport org.ar.model.LineBean;\n\n/**\n * Created by liuxiaozhong on 2017-09-25.\n */\n\npublic class AudioLineAdapter extends BaseQuickAdapter<LineBean,BaseViewHolder> {\n    boolean isHost;\n    public AudioLineAdapter(boolean isHost) {\n        super(R.layout.item_audio_line);\n        this.isHost=isHost;\n    }\n\n    @Override\n    protected void convert(BaseViewHolder helper, LineBean item) {\n        TextView hangup=helper.getView(R.id.tv_hangup);\n        helper.setText(R.id.tv_name,item.name);\n        helper.addOnClickListener(R.id.tv_hangup);\n        if (isHost){\n            hangup.setVisibility(View.VISIBLE);\n        }else {\n            if (item.isSelf){\n                hangup.setVisibility(View.VISIBLE);\n            }else {\n                hangup.setVisibility(View.INVISIBLE);\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/adapter/LiveLineAdapter.java",
    "content": "package org.ar.adapter;\n\nimport android.widget.TextView;\n\nimport com.chad.library.adapter.base.BaseQuickAdapter;\nimport com.chad.library.adapter.base.BaseViewHolder;\n\nimport org.ar.rtmpc.R;\nimport org.ar.model.LineBean;\n\n/**\n * Created by liuxiaozhong on 2017/9/24.\n */\n\npublic class LiveLineAdapter extends BaseQuickAdapter<LineBean,BaseViewHolder> {\n    public LiveLineAdapter() {\n        super(R.layout.item_line);\n    }\n\n    @Override\n    protected void convert(BaseViewHolder helper, LineBean item) {\n        TextView tv_name=helper.getView(R.id.tv_name);\n        tv_name.setText(item.name+\"申请连麦\");\n        helper.addOnClickListener(R.id.tv_agree);\n        helper.addOnClickListener(R.id.tv_refuse);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/adapter/LiveListAdapter.java",
    "content": "package org.ar.adapter;\n\nimport android.graphics.drawable.Drawable;\nimport android.widget.TextView;\n\nimport com.chad.library.adapter.base.BaseQuickAdapter;\nimport com.chad.library.adapter.base.BaseViewHolder;\n\nimport org.ar.rtmpc.R;\nimport org.ar.model.LiveBean;\n\n\n/**\n * Created by liuxiaozhong on 2017-09-14.\n */\n\npublic class LiveListAdapter extends BaseQuickAdapter<LiveBean,BaseViewHolder> {\n\n    public LiveListAdapter() {\n        super(R.layout.item_live);\n    }\n\n    @Override\n    protected void convert(BaseViewHolder helper, LiveBean item) {\n        helper.setText(R.id.tv_name,item.getmLiveTopic());\n        helper.setText(R.id.tv_num,item.getmMemberNum()+\"\");\n        TextView tvLiveType = helper.getView(R.id.tv_live_type);\n\n        Drawable imgVideo = helper.itemView.getContext().getResources().getDrawable(\n                R.drawable.img_video);\n        Drawable imgAdudio = helper.itemView.getContext().getResources().getDrawable(\n                R.drawable.img_audio);\n        if(item.isAudioLive==1) {\n            tvLiveType.setCompoundDrawablesWithIntrinsicBounds(imgAdudio,\n                    null, null, null);\n            tvLiveType.setText(\"音频直播\");\n        } else {\n            tvLiveType.setCompoundDrawablesWithIntrinsicBounds(imgVideo,\n                    null, null, null);\n            tvLiveType.setText(\"视频\");\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/adapter/LiveMessageAdapter.java",
    "content": "package org.ar.adapter;\n\nimport android.graphics.Color;\n\nimport com.chad.library.adapter.base.BaseQuickAdapter;\nimport com.chad.library.adapter.base.BaseViewHolder;\n\nimport org.ar.model.MessageBean;\n\n/**\n * Created by liuxiaozhong on 2017-09-22.\n */\n\npublic class LiveMessageAdapter extends BaseQuickAdapter<MessageBean, BaseViewHolder> {\n    public LiveMessageAdapter() {\n        super(android.R.layout.simple_list_item_1);\n    }\n\n    @Override\n    protected void convert(BaseViewHolder helper, MessageBean item) {\n        helper.setTextColor(android.R.id.text1, item.type==1 ? Color.parseColor(\"#ffffff\") : Color.parseColor(\"#666666\"));\n        helper.setText(android.R.id.text1, item.name+\":\"+item.content);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/adapter/LogAdapter.java",
    "content": "package org.ar.adapter;\n\nimport android.graphics.Color;\nimport android.widget.TextView;\n\nimport com.chad.library.adapter.base.BaseQuickAdapter;\nimport com.chad.library.adapter.base.BaseViewHolder;\n\n/**\n * Created by liuxiaozhong on 2019/3/12.\n */\npublic class LogAdapter extends BaseQuickAdapter<String,BaseViewHolder> {\n    public LogAdapter() {\n        super(android.R.layout.simple_list_item_1);\n    }\n\n    @Override\n    protected void convert(BaseViewHolder helper, String item) {\n        TextView textView=helper.getView(android.R.id.text1);\n        textView.setTextColor(Color.parseColor(\"#666666\"));\n        helper.setText(android.R.id.text1,item);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/guest/AudioGuestActivity.java",
    "content": "package org.ar.guest;\n\nimport android.content.DialogInterface;\nimport android.graphics.drawable.AnimationDrawable;\nimport android.media.AudioManager;\nimport android.os.Bundle;\nimport android.support.v4.app.DialogFragment;\nimport android.support.v7.app.AlertDialog;\nimport android.support.v7.widget.LinearLayoutManager;\nimport android.support.v7.widget.RecyclerView;\nimport android.util.Log;\nimport android.view.KeyEvent;\nimport android.view.View;\nimport android.view.WindowManager;\nimport android.widget.ImageView;\nimport android.widget.RelativeLayout;\nimport android.widget.TextView;\nimport android.widget.Toast;\n\nimport com.chad.library.adapter.base.BaseQuickAdapter;\n\nimport org.ar.BaseActivity;\nimport org.ar.ARApplication;\nimport org.ar.adapter.AudioLineAdapter;\nimport org.ar.adapter.LiveMessageAdapter;\nimport org.ar.adapter.LogAdapter;\nimport org.ar.common.utils.ARAudioManager;\nimport org.ar.model.LineBean;\nimport org.ar.model.MessageBean;\nimport org.ar.utils.ARUtils;\nimport org.ar.utils.ToastUtil;\nimport org.ar.widgets.KeyboardDialogFragment;\nimport org.ar.common.enums.ARVideoCommon;\nimport org.ar.rtmpc_hybrid.ARRtmpcEngine;\nimport org.ar.rtmpc_hybrid.ARRtmpcGuestEvent;\nimport org.ar.rtmpc_hybrid.ARRtmpcGuestKit;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport java.util.Set;\n\n/**\n * 音频游客界面\n */\npublic class AudioGuestActivity extends BaseActivity implements BaseQuickAdapter.OnItemChildClickListener {\n    TextView tvTitle;\n    RecyclerView rvMsgList,rvLog;\n    TextView tvApplyLine;\n    View viewSpace;\n    TextView tvMemberNum;\n    RecyclerView rvLineList;\n    TextView tvRtmpOk;\n    TextView tvRtmpStatus;\n    TextView tvRtcOk;\n    TextView tvHostName;\n    ImageView ivLineAnim;\n    RelativeLayout rl_log_layout;\n    private ARRtmpcGuestKit mGuestKit;\n    private ARAudioManager mRtmpAudioManager = null;\n    private LiveMessageAdapter mAdapter;\n    private LogAdapter logAdapter;\n    private boolean isApplyLine = false;//是否在连麦、申请连麦\n    private boolean isLinling = false;\n    private AnimationDrawable hostAnimation;\n    private AudioLineAdapter audioLineAdapter;\n    private String liveId = \"\";\n    private String userID=\"guest\"+(int)((Math.random()*9+1)*100000)+\"\";\n\n    @Override\n    public boolean onKeyDown(int keyCode, KeyEvent event) {\n        if (keyCode == KeyEvent.KEYCODE_BACK) {\n            if (isApplyLine) {\n                ShowExitDialog();\n                return false;\n            }\n        }\n        return super.onKeyDown(keyCode, event);\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n        /**\n         * 销毁rtmp播放器\n         */\n        if (mGuestKit != null) {\n            mGuestKit.clean();\n            mGuestKit = null;\n        }\n        if (mRtmpAudioManager != null) {\n            mRtmpAudioManager.stop();\n            mRtmpAudioManager = null;\n        }\n\n    }\n\n\n    @Override\n    public int getLayoutId() {\n        return org.ar.rtmpc.R.layout.activity_audio_guest;\n    }\n\n    @Override\n    public void initView(Bundle savedInstanceState) {\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); //保持屏幕常亮\n        viewSpace = findViewById(org.ar.rtmpc.R.id.view_space);\n        mImmersionBar.titleBar(viewSpace).init();\n        tvTitle = findViewById(org.ar.rtmpc.R.id.tv_title);\n        rl_log_layout=findViewById(org.ar.rtmpc.R.id.rl_log_layout);\n        rvLog=findViewById(org.ar.rtmpc.R.id.rv_log);\n        rvMsgList = findViewById(org.ar.rtmpc.R.id.rv_msg_list);\n        tvApplyLine = findViewById(org.ar.rtmpc.R.id.tv_apply_line);\n        tvMemberNum = findViewById(org.ar.rtmpc.R.id.tv_member_num);\n        rvLineList = findViewById(org.ar.rtmpc.R.id.rv_line_list);\n        tvRtmpOk = findViewById(org.ar.rtmpc.R.id.tv_rtmp_ok);\n        tvRtmpStatus = findViewById(org.ar.rtmpc.R.id.tv_rtmp_status);\n        tvRtcOk = findViewById(org.ar.rtmpc.R.id.tv_rtc_ok);\n        tvHostName = findViewById(org.ar.rtmpc.R.id.tv_host_name);\n        ivLineAnim = findViewById(org.ar.rtmpc.R.id.iv_line_anim);\n        hostAnimation = (AnimationDrawable) ivLineAnim.getBackground();\n        rvMsgList.setLayoutManager(new LinearLayoutManager(this));\n        mAdapter = new LiveMessageAdapter();\n        audioLineAdapter = new AudioLineAdapter(false);\n        audioLineAdapter.setOnItemChildClickListener(this);\n        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);\n        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);\n        rvLineList.setLayoutManager(linearLayoutManager);\n        rvLineList.setAdapter(audioLineAdapter);\n        rvLineList.setItemAnimator(null);\n        rvMsgList.setAdapter(mAdapter);\n        logAdapter = new LogAdapter();\n        rvLog.setLayoutManager(new LinearLayoutManager(this));\n        logAdapter.bindToRecyclerView(rvLog);\n        String pullUrl = getIntent().getStringExtra(\"pullURL\");\n        String hostName=getIntent().getStringExtra(\"hostName\");\n        tvHostName.setText(hostName);\n        liveId = getIntent().getStringExtra(\"liveId\");\n        tvTitle.setText(\"房间ID：\" + liveId);\n        mRtmpAudioManager = ARAudioManager.create(this);\n        mRtmpAudioManager.start(new ARAudioManager.AudioManagerEvents() {\n            @Override\n            public void onAudioDeviceChanged(ARAudioManager.AudioDevice audioDevice, Set<ARAudioManager.AudioDevice> set) {\n\n            }\n        });\n        ARRtmpcEngine.Inst().getGuestOption().setMediaType(ARVideoCommon.ARMediaType.Audio);\n        mGuestKit = new ARRtmpcGuestKit(mGuestListener);\n        mGuestKit.startRtmpPlay(pullUrl, 0);\n        mGuestKit.joinRTCLine(\"\", liveId, userID, getUserData());\n    }\n\n    public String getUserData() {\n        JSONObject user = new JSONObject();\n        try {\n            user.put(\"isHost\", 0);\n            user.put(\"userId\", userID);\n            user.put(\"nickName\", ARApplication.getNickName());\n            user.put(\"headUrl\", \"www.baidu.com\");\n\n        } catch (JSONException e) {\n            e.printStackTrace();\n        }\n        return user.toString();\n    }\n\n    private void onAudioManagerChangedState() {\n        // TODO(henrika): disable video if\n        // AppRTCAudioManager.AudioDevice.EARPIECE\n        // is active.\n        setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);\n    }\n\n    private void ShowExitDialog() {\n        AlertDialog.Builder build = new AlertDialog.Builder(this);\n        build.setTitle(org.ar.rtmpc.R.string.str_exit);\n        build.setMessage(org.ar.rtmpc.R.string.str_line_hangup);\n        build.setPositiveButton(org.ar.rtmpc.R.string.str_ok, new DialogInterface.OnClickListener() {\n\n            @Override\n            public void onClick(DialogInterface dialog, int which) {\n                // TODO Auto-generated method stub\n                mGuestKit.hangupRTCLine();\n                isApplyLine = false;\n                isLinling = false;\n                finishAnimActivity();\n            }\n        });\n        build.setNegativeButton(org.ar.rtmpc.R.string.str_cancel, new DialogInterface.OnClickListener() {\n\n            @Override\n            public void onClick(DialogInterface dialog, int which) {\n                // TODO Auto-generated method stub\n\n            }\n        });\n\n        build.show();\n    }\n\n\n    /**\n     * 更新列表\n     *\n     * @param chatMessageBean\n     */\n    private void addChatMessageList(MessageBean chatMessageBean) {\n        // 150 条 修改；\n\n        if (chatMessageBean == null) {\n            return;\n        }\n\n        if (mAdapter.getData().size() < 150) {\n            mAdapter.addData(chatMessageBean);\n        } else {\n            mAdapter.remove(0);\n            mAdapter.addData(chatMessageBean);\n        }\n        rvMsgList.smoothScrollToPosition(mAdapter.getData().size() - 1);\n    }\n    public void printLog(String log){\n        Log.d(\"RTMPC\", log);\n        logAdapter.addData(log);\n    }\n\n    /**\n     * 观看直播回调信息接口\n     */\n    private ARRtmpcGuestEvent mGuestListener = new ARRtmpcGuestEvent() {\n\n        /**\n         * rtmp 连接成功 视频即将播放；视频播放前的操作可以在此接口中进行操作\n         */\n        @Override\n        public void onRtmpPlayerOk() {\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpPlayerOk\");\n                    if (tvRtmpOk != null) {\n                        tvRtmpOk.setText(\"Rtmp连接成功\");\n                    }\n                }\n            });\n        }\n\n        /**\n         * rtmp 开始播放 视频开始播放\n         */\n        @Override\n        public void onRtmpPlayerStart() {\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpPlayerStart\");\n                }\n            });\n        }\n\n        /**\n         * rtmp 当前播放状态\n         * @param cacheTime 当前缓存时间\n         * @param curBitrate 当前播放器码流\n         */\n        @Override\n        public void onRtmpPlayerStatus(final int cacheTime, final int curBitrate) {\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpPlayerStatus cacheTime:\" + cacheTime + \" curBitrate:\" + curBitrate);\n                    if (tvRtmpStatus != null) {\n                        tvRtmpStatus.setText(\"当前缓存时间：\" + cacheTime + \" ms\" + \"\\n当前码流：\" + curBitrate / 10024 / 8 + \"kb/s\");\n                    }\n                }\n            });\n        }\n\n        /**\n         * rtmp 播放缓冲区时长\n         * @param nPercent 缓冲时间\n         */\n        @Override\n        public void onRtmpPlayerLoading(final int nPercent) {\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpPlayerCache  nPercent:\" + nPercent);\n                }\n            });\n        }\n\n        /**\n         * rtmp 播放器关闭\n         * @param nCode\n         */\n        @Override\n        public void onRtmpPlayerClosed(final int nCode) {\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpPlayerClosed  nCode:\" + nCode);\n                }\n            });\n        }\n\n\n        /**\n         * 游客RTC 状态回调\n         * @param nCode 回调响应码：0：正常；101：主播未开启直播；\n         */\n        @Override\n        public void onRTCJoinLineResult(final int nCode, String s) {\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCJoinLineResult  nCode:\" + nCode);\n                    if (nCode == 0) {\n                        if (tvRtcOk != null) {\n                            tvRtcOk.setText(org.ar.rtmpc.R.string.str_rtc_connect_success);\n                        }\n                    } else if (nCode == 101) {\n                        Toast.makeText(AudioGuestActivity.this, org.ar.rtmpc.R.string.str_hoster_not_live, Toast.LENGTH_LONG).show();\n                        if (tvRtcOk != null) {\n                            tvRtcOk.setText(org.ar.rtmpc.R.string.str_rtc_connect_success);\n                        }\n                    } else {\n                        if (tvRtcOk != null) {\n                            tvRtcOk.setText(ARUtils.getErrString(nCode));\n                        }\n                    }\n                }\n            });\n        }\n\n        /**\n         * 游客申请连线结果\n         * @param nCode 0：申请连线成功；-1：主播拒绝连线\n         */\n        @Override\n        public void onRTCApplyLineResult(final int nCode) {\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCApplyLineResult  nCode:\" + nCode);\n                    if (nCode == 0) {\n                        isApplyLine = true;\n                        tvApplyLine.setText(\"挂断\");\n                        audioLineAdapter.addData(0, new LineBean(\"self\", \"自己\", true));\n                        isLinling = true;\n                        tvApplyLine.setBackgroundResource(org.ar.rtmpc.R.drawable.shape_room_hang_up_line);\n                    } else if (nCode == 601) {\n                        Toast.makeText(AudioGuestActivity.this, org.ar.rtmpc.R.string.str_hoster_refused, Toast.LENGTH_LONG).show();\n                        isApplyLine = false;\n                        isLinling = false;\n                        tvApplyLine.setText(\"连麦\");\n                        tvApplyLine.setBackgroundResource(org.ar.rtmpc.R.drawable.shape_room_apply_line);\n                    }\n                }\n            });\n        }\n\n        /**\n         * 挂断连线回调\n         */\n        @Override\n        public void onRTCHangupLine() {\n            //主播连线断开\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCHangupLine \");\n                    mGuestKit.hangupRTCLine();\n                    audioLineAdapter.remove(0);\n                    tvApplyLine.setText(org.ar.rtmpc.R.string.str_connect_hoster);\n                    tvApplyLine.setBackgroundResource(org.ar.rtmpc.R.drawable.shape_room_apply_line);\n                    isApplyLine = false;\n                    isLinling = false;\n                }\n            });\n        }\n\n\n        @Override\n        public void onRTCOpenRemoteVideoRender(String s, String s1, String s2, String s3) {\n\n        }\n\n        @Override\n        public void onRTCCloseRemoteVideoRender(String s, String s1, String s2) {\n\n        }\n\n        @Override\n        public void onRTCOpenRemoteAudioLine(final String strLivePeerId, final String strUserId, final String strUserData) {\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCOpenAudioLine strLivePeerId:\" + strLivePeerId + \"strUserId:\" + strUserId + \" strUserData:\" + strUserData);\n                    try {\n                        JSONObject jsonObject = new JSONObject(strUserData);\n                        if (strLivePeerId.equals(\"RTMPC_Line_Hoster\")) {\n//                            audioLineAdapter.addData(new LineBean(strLivePeerId, jsonObject.getString(\"nickName\"), true));\n                        } else {\n                            audioLineAdapter.addData(new LineBean(strLivePeerId, jsonObject.getString(\"nickName\"), false));\n                        }\n                    } catch (JSONException e) {\n                        e.printStackTrace();\n                    }\n\n                }\n            });\n        }\n\n        @Override\n        public void onRTCCloseRemoteAudioLine(final String strLivePeerId, final String strUserId) {\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCCloseAudioLine strLivePeerId:\" + strLivePeerId + \"strUserId:\" + strUserId);\n                    int index = 9;\n                    for (int i = 0; i < audioLineAdapter.getData().size(); i++) {\n                        if (audioLineAdapter.getItem(i).peerId.equals(strLivePeerId)) {\n                            index = i;\n                        }\n                    }\n                    if (index != 9 && index <= audioLineAdapter.getData().size()) {\n                        audioLineAdapter.remove(index);\n                    }\n                }\n            });\n        }\n\n        @Override\n        public void onRTCLocalAudioActive(int i) {\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    Log.d(\"RTMPC\", \"onRTCLocalAudioActive\");\n                }\n            });\n        }\n\n        @Override\n        public void onRTCHosterAudioActive(int i) {\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    Log.d(\"RTMPC\", \"onRTCHosterAudioActive\");\n                }\n            });\n        }\n\n\n        @Override\n        public void onRTCRemoteAudioActive(final String strLivePeerId, final String strUserId, final int nTime) {\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCAudioActive strLivePeerId:\" + strLivePeerId + \"strUserId:\" + strUserId + \" nTime:\" + nTime);\n                    if (strLivePeerId.equals(\"RTMPC_Hoster\")) {//主播\n                        ivLineAnim.setVisibility(View.VISIBLE);\n                        hostAnimation.start();\n                    } else {\n                        for (int i = 0; i < audioLineAdapter.getData().size(); i++) {\n                            if (strLivePeerId.equals(audioLineAdapter.getData().get(i).peerId)) {\n                                audioLineAdapter.getItem(i).setStartAnim(true);\n                                audioLineAdapter.notifyItemChanged(i);\n                            }\n                        }\n                    }\n                }\n            });\n        }\n\n        @Override\n        public void onRTCRemoteAVStatus(final String s, boolean b, boolean b1) {\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCRemoteAVStatus  peerID:\" + s);\n                }\n            });\n        }\n\n        /**\n         * 主播已离开回调\n         * @param nCode\n         */\n        @Override\n        public void onRTCLineLeave(final int nCode, String s) {\n            //主播关闭直播\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCLineLeave nCode:\" + nCode);\n                    if (mGuestKit != null) {\n                        mGuestKit.stopRtmpPlay();\n                    }\n                    finishAnimActivity();\n                    ToastUtil.show(\"主播已离开\");\n                }\n            });\n        }\n\n\n        /**\n         * 消息回调\n         * @param strCustomID 消息的发送者id\n         * @param strCustomName 消息的发送者昵称\n         * @param strCustomHeader 消息的发送者头像url\n         * @param strMessage 消息内容\n         */\n        @Override\n        public void onRTCUserMessage(final int nType, final String strCustomID, final String strCustomName, final String strCustomHeader, final String strMessage) {\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCUserMessage nType:\" + nType + \"strCustomID:\" + strCustomID + \"strCustomName:\" + strCustomName + \"strCustomHeader:\" + strCustomHeader + \"strMessage:\" + strMessage);\n                    addChatMessageList(new MessageBean(MessageBean.AUDIO, strCustomName, strMessage));\n                }\n            });\n        }\n\n        /**\n         * 观看直播的总人数回调\n         * @param totalMembers 观看直播的总人数\n         */\n        @Override\n        public void onRTCMemberNotify(final String strServerId, final String strRoomId, final int totalMembers) {\n            AudioGuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCMemberNotify strServerId:\" + strServerId + \"strRoomId:\" + strRoomId + \"totalMembers:\" + totalMembers);\n                    tvMemberNum.setText(\"在线观看人数\" + totalMembers + \"\");\n                }\n            });\n        }\n\n\n    };\n\n    public void onClick(View view) {\n        switch (view.getId()) {\n            case org.ar.rtmpc.R.id.btn_close:\n                if (isLinling) {\n                    ShowExitDialog();\n                } else {\n                    finishAnimActivity();\n                }\n                break;\n            case org.ar.rtmpc.R.id.iv_message:\n                showChatLayout();\n                break;\n            case org.ar.rtmpc.R.id.tv_apply_line:\n                if (isApplyLine) {\n                    if (mGuestKit != null) {\n                        mGuestKit.hangupRTCLine();\n                        if (isLinling){\n                            audioLineAdapter.remove(0);\n                        }\n                        tvApplyLine.setText(\"连麦\");\n                        tvApplyLine.setBackgroundResource(org.ar.rtmpc.R.drawable.shape_room_apply_line);\n                        isApplyLine = false;\n                        isLinling = false;\n                    }\n                } else {\n                    if (mGuestKit != null) {\n                        mGuestKit.applyRTCLine();\n                        tvApplyLine.setText(\"挂断\");\n                        tvApplyLine.setBackgroundResource(org.ar.rtmpc.R.drawable.shape_room_hang_up_line);\n                        isApplyLine = true;\n                        isLinling = false;\n                    }\n                }\n                break;\n            case org.ar.rtmpc.R.id.btn_log:\n                rl_log_layout.setVisibility(View.VISIBLE);\n                break;\n            case org.ar.rtmpc.R.id.ibtn_close_log:\n                rl_log_layout.setVisibility(View.GONE);\n                break;\n        }\n    }\n\n    private void showChatLayout() {\n        KeyboardDialogFragment keyboardDialogFragment = new KeyboardDialogFragment();\n        keyboardDialogFragment.show(getSupportFragmentManager(), \"KeyboardDialogFragment\");\n        keyboardDialogFragment.setEdittextListener(new KeyboardDialogFragment.EdittextListener() {\n            @Override\n            public void setTextStr(String text) {\n                addChatMessageList(new MessageBean(MessageBean.AUDIO, ARApplication.getNickName(), text));\n                mGuestKit.sendMessage(0, ARApplication.getNickName(), \"\", text);\n            }\n\n            @Override\n            public void dismiss(DialogFragment dialogFragment) {\n            }\n        });\n    }\n\n\n    @Override\n    public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {\n        switch (view.getId()) {\n            case org.ar.rtmpc.R.id.tv_hangup:\n                if (mGuestKit != null) {\n\n                    mGuestKit.hangupRTCLine();\n                    tvApplyLine.setBackgroundResource(org.ar.rtmpc.R.drawable.shape_room_apply_line);\n                    tvApplyLine.setText(\"连麦\");\n                    audioLineAdapter.remove(0);\n                    isApplyLine = false;\n                    isLinling = false;\n                }\n                break;\n        }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/guest/GuestActivity.java",
    "content": "package org.ar.guest;\n\nimport android.annotation.SuppressLint;\nimport android.content.DialogInterface;\nimport android.media.AudioManager;\nimport android.os.Bundle;\nimport android.support.v4.app.DialogFragment;\nimport android.support.v7.app.AlertDialog;\nimport android.support.v7.widget.LinearLayoutManager;\nimport android.support.v7.widget.RecyclerView;\nimport android.util.Log;\nimport android.view.Gravity;\nimport android.view.KeyEvent;\nimport android.view.View;\nimport android.view.WindowManager;\nimport android.widget.ImageButton;\nimport android.widget.LinearLayout;\nimport android.widget.RelativeLayout;\nimport android.widget.TextView;\nimport android.widget.Toast;\n\nimport org.ar.BaseActivity;\nimport org.ar.ARApplication;\nimport org.ar.adapter.LiveMessageAdapter;\nimport org.ar.adapter.LogAdapter;\nimport org.ar.common.utils.ARAudioManager;\nimport org.ar.model.MessageBean;\nimport org.ar.rtmpc.R;\nimport org.ar.utils.ARUtils;\nimport org.ar.utils.ToastUtil;\nimport org.ar.widgets.ARVideoView;\nimport org.ar.widgets.KeyboardDialogFragment;\nimport org.ar.common.enums.ARVideoCommon;\nimport org.ar.rtmpc_hybrid.ARRtmpcEngine;\nimport org.ar.rtmpc_hybrid.ARRtmpcGuestEvent;\nimport org.ar.rtmpc_hybrid.ARRtmpcGuestKit;\nimport org.json.JSONException;\nimport org.json.JSONObject;\nimport org.webrtc.VideoRenderer;\n\nimport java.util.Set;\n\n/**\n * 视频游客页面\n */\npublic class GuestActivity extends BaseActivity {\n    RelativeLayout rlRtmpcVideos,rl_log_layout;\n    TextView tvTitle;\n    TextView tvRtmpOk;\n    TextView tvRtmpStatus;\n    TextView tvRtcOk;\n    RecyclerView rvMsgList,rvLog;\n    TextView tvApplyLine;\n    View viewSpace;\n    TextView tvMemberNum;\n    ImageButton ibtnCamera;\n    private ARRtmpcGuestKit mGuestKit;\n    private ARVideoView mVideoView;\n    private ARAudioManager mRtmpAudioManager = null;\n    private LiveMessageAdapter mAdapter;\n    private LogAdapter logAdapter;\n    private boolean isApplyLine = false;//是否申请连麦\n    private boolean isLining = false;//是否正在连麦\n    private String liveId = \"\";\n    private String userId=\"guest\"+(int)((Math.random()*9+1)*100000)+\"\";\n    @Override\n    public boolean onKeyDown(int keyCode, KeyEvent event) {\n        if (keyCode == KeyEvent.KEYCODE_BACK) {\n            if (isApplyLine) {\n                ShowExitDialog();\n                return false;\n            }\n        }\n        return super.onKeyDown(keyCode, event);\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n        if (mRtmpAudioManager != null) {\n            mRtmpAudioManager.stop();\n            mRtmpAudioManager = null;\n\n        }\n\n        /**\n         * 销毁rtmp播放器\n         */\n        if (mGuestKit != null) {\n            mGuestKit.clean();\n            mVideoView.removeLocalVideoRender();\n            mGuestKit = null;\n        }\n    }\n\n    @Override\n    public int getLayoutId() {\n        return org.ar.rtmpc.R.layout.activity_guest;\n    }\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); //保持屏幕常亮\n        super.onCreate(savedInstanceState);\n    }\n\n\n    @Override\n    public void initView(Bundle savedInstanceState) {\n        viewSpace=findViewById(org.ar.rtmpc.R.id.view_space);\n        mImmersionBar.titleBar(viewSpace).init();\n        ibtnCamera=findViewById(org.ar.rtmpc.R.id.btn_camare);\n        rlRtmpcVideos=findViewById(org.ar.rtmpc.R.id.rl_rtmpc_videos);\n        rl_log_layout=findViewById(org.ar.rtmpc.R.id.rl_log_layout);\n        rvLog=findViewById(org.ar.rtmpc.R.id.rv_log);\n        tvTitle=findViewById(org.ar.rtmpc.R.id.tv_title);\n        tvRtmpOk=findViewById(org.ar.rtmpc.R.id.tv_rtmp_ok);\n        tvRtmpStatus=findViewById(org.ar.rtmpc.R.id.tv_rtmp_status);\n        tvRtcOk=findViewById(org.ar.rtmpc.R.id.tv_rtc_ok);\n        rvMsgList=findViewById(org.ar.rtmpc.R.id.rv_msg_list);\n        tvApplyLine=findViewById(org.ar.rtmpc.R.id.tv_apply_line);\n        tvMemberNum=findViewById(org.ar.rtmpc.R.id.tv_member_num);\n\n        logAdapter = new LogAdapter();\n        rvLog.setLayoutManager(new LinearLayoutManager(this));\n        logAdapter.bindToRecyclerView(rvLog);\n        rvMsgList.setLayoutManager(new LinearLayoutManager(this));\n        mAdapter = new LiveMessageAdapter();\n        rvMsgList.setAdapter(mAdapter);\n        ARRtmpcEngine.Inst().getGuestOption().setDefaultFrontCamera(true);\n        ARRtmpcEngine.Inst().getGuestOption().setMediaType(ARVideoCommon.ARMediaType.Video);\n        String pullUrl = getIntent().getStringExtra(\"pullURL\");\n        liveId = getIntent().getStringExtra(\"liveId\");\n        tvTitle.setText(\"房间ID:\" +liveId);\n        mVideoView = new ARVideoView( rlRtmpcVideos, ARRtmpcEngine.Inst().egl(), this,false, false);\n        mVideoView.setVideoViewLayout(false, Gravity.RIGHT, LinearLayout.VERTICAL);\n        mVideoView.setVideoLayoutOnclickEvent(new ARVideoView.VideoLayoutOnclickEvent() {\n            @Override\n            public void onCloseVideoRender(View view, String strPeerId) {\n                /**\n                 * 挂断连线\n                 */\n                mGuestKit.hangupRTCLine();\n                mVideoView.removeRemoteRender(\"LocalCameraRender\");\n                tvApplyLine.setText(org.ar.rtmpc.R.string.str_connect_hoster);\n                tvApplyLine.setBackgroundResource(org.ar.rtmpc.R.drawable.shape_room_apply_line);\n                isApplyLine = false;\n                isLining=false;\n            }\n        });\n        mRtmpAudioManager = ARAudioManager.create(this);\n        mRtmpAudioManager.start(new ARAudioManager.AudioManagerEvents() {\n            @Override\n            public void onAudioDeviceChanged(ARAudioManager.AudioDevice audioDevice, Set<ARAudioManager.AudioDevice> set) {\n\n            }\n        });\n        ARRtmpcEngine.Inst().getGuestOption().setMediaType(ARVideoCommon.ARMediaType.Video);\n        mGuestKit = new ARRtmpcGuestKit(mGuestListener);\n        mGuestKit.setAudioActiveCheck(true);\n        VideoRenderer render = mVideoView.openLocalVideoRender();\n        mGuestKit.startRtmpPlay(pullUrl, render.GetRenderPointer());\n        mGuestKit.joinRTCLine(\"\", liveId, userId, getUserData());\n    }\n\n\n    public String getUserData() {\n        JSONObject user = new JSONObject();\n        try {\n            user.put(\"isHost\", 0);\n            user.put(\"userId\", userId);\n            user.put(\"nickName\", ARApplication.getNickName());\n            user.put(\"headUrl\", \"www.baidu.com\");\n        } catch (JSONException e) {\n            e.printStackTrace();\n        }\n        return user.toString();\n    }\n\n    private void onAudioManagerChangedState() {\n        // TODO(henrika): disable video if\n        // AppRTCAudioManager.AudioDevice.EARPIECE\n        // is active.\n        setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);\n    }\n\n    private void ShowExitDialog() {\n        AlertDialog.Builder build = new AlertDialog.Builder(this);\n        build.setTitle(org.ar.rtmpc.R.string.str_exit);\n        build.setMessage(org.ar.rtmpc.R.string.str_line_hangup);\n        build.setPositiveButton(org.ar.rtmpc.R.string.str_ok, new DialogInterface.OnClickListener() {\n\n            @Override\n            public void onClick(DialogInterface dialog, int which) {\n                // TODO Auto-generated method stub\n                mGuestKit.hangupRTCLine();\n                mVideoView.removeRemoteRender(\"LocalCameraRender\");\n                finishAnimActivity();\n            }\n        });\n        build.setNegativeButton(org.ar.rtmpc.R.string.str_cancel, new DialogInterface.OnClickListener() {\n\n            @Override\n            public void onClick(DialogInterface dialog, int which) {\n                // TODO Auto-generated method stub\n\n            }\n        });\n\n        build.show();\n    }\n\n\n    /**\n     * 更新列表\n     *\n     * @param chatMessageBean\n     */\n    private void addChatMessageList(MessageBean chatMessageBean) {\n        // 150 条 修改；\n\n        if (chatMessageBean == null) {\n            return;\n        }\n\n        if (mAdapter.getData().size() < 150) {\n            mAdapter.addData(chatMessageBean);\n        } else {\n            mAdapter.remove(0);\n            mAdapter.addData(chatMessageBean);\n        }\n        rvMsgList.smoothScrollToPosition(mAdapter.getData().size() - 1);\n    }\n\n    public void printLog(String log){\n        Log.d(\"RTMPC\", log);\n        logAdapter.addData(log);\n    }\n\n    /**\n     * 观看直播回调信息接口\n     */\n    private ARRtmpcGuestEvent mGuestListener = new ARRtmpcGuestEvent() {\n\n        /**\n         * rtmp 连接成功 视频即将播放；视频播放前的操作可以在此接口中进行操作\n         */\n        @Override\n        public void onRtmpPlayerOk() {\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpPlayerOk\");\n                    if (tvRtmpOk != null) {\n                        tvRtmpOk.setText(\"Rtmp连接成功\");\n                    }\n                }\n            });\n        }\n\n        /**\n         * rtmp 开始播放 视频开始播放\n         */\n        @Override\n        public void onRtmpPlayerStart() {\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpPlayerStart\");\n                }\n            });\n        }\n\n        /**\n         * rtmp 当前播放状态\n         * @param cacheTime 当前缓存时间\n         * @param curBitrate 当前播放器码流\n         */\n        @Override\n        public void onRtmpPlayerStatus(final int cacheTime, final int curBitrate) {\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpPlayerStatus cacheTime:\" + cacheTime + \" curBitrate:\" + curBitrate);\n                    if (tvRtmpStatus != null) {\n                        tvRtmpStatus.setText(\"当前缓存时间：\" + cacheTime + \" ms\" + \"\\n当前码流：\" + curBitrate / 10024 / 8 + \"kb/s\");\n                    }\n\n                }\n            });\n        }\n\n        /**\n         * rtmp 播放缓冲区时长\n         * @param nPercent 缓冲时间\n         */\n        @Override\n        public void onRtmpPlayerLoading(final int nPercent) {\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpPlayerCache  nPercent:\" + nPercent);\n                }\n            });\n        }\n\n        /**\n         * rtmp 播放器关闭\n         * @param nCode\n         */\n        @Override\n        public void onRtmpPlayerClosed(final int nCode) {\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpPlayerClosed  nCode:\" + nCode);\n                }\n            });\n        }\n\n\n        /**\n         * 游客RTC 状态回调\n         * @param nCode 回调响应码：0：正常；101：主播未开启直播；\n         */\n        @Override\n        public void onRTCJoinLineResult(final int nCode, String s) {\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCJoinLineResult  nCode:\" + nCode);\n                    if (tvRtcOk != null) {\n                        if (nCode == 0) {\n                            tvRtcOk.setText(org.ar.rtmpc.R.string.str_rtc_connect_success);\n                        } else if (nCode == 101) {\n                            Toast.makeText(GuestActivity.this, org.ar.rtmpc.R.string.str_hoster_not_live, Toast.LENGTH_LONG).show();\n                            tvRtcOk.setText(org.ar.rtmpc.R.string.str_rtc_connect_success);\n                        } else {\n                            tvRtcOk.setText(ARUtils.getErrString(nCode));\n                        }\n                    }\n                }\n            });\n        }\n\n        /**\n         * 游客申请连线回调\n         */\n        @Override\n        public void onRTCApplyLineResult(final int nCode) {\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @SuppressLint(\"MissingPermission\")\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCApplyLineResult  nCode:\" + nCode);\n                    if (nCode == 0) {\n                        ibtnCamera.setVisibility(View.VISIBLE);\n                        isApplyLine = true;\n                        isLining = true;\n                        tvApplyLine.setText(\"挂断\");\n                        tvApplyLine.setBackgroundResource(org.ar.rtmpc.R.drawable.shape_room_hang_up_line);\n                        VideoRenderer render = mVideoView.openRemoteVideoRender(\"LocalCameraRender\");\n                        mGuestKit.setLocalVideoCapturer(render.GetRenderPointer());\n                    } else if (nCode == 601) {\n                        Toast.makeText(GuestActivity.this, org.ar.rtmpc.R.string.str_hoster_refused, Toast.LENGTH_LONG).show();\n                        isApplyLine = false;\n                        ibtnCamera.setVisibility(View.GONE);\n                        tvApplyLine.setText(\"连麦\");\n                        tvApplyLine.setBackgroundResource(org.ar.rtmpc.R.drawable.shape_room_apply_line);\n                    }\n                }\n            });\n        }\n\n\n        /**\n         * 挂断连线回调\n         */\n        @Override\n        public void onRTCHangupLine() {\n            //主播连线断开\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCHangupLine \");\n                    mGuestKit.hangupRTCLine();\n                    ibtnCamera.setVisibility(View.GONE);\n                    mVideoView.removeRemoteRender(\"LocalCameraRender\");\n                    tvApplyLine.setText(org.ar.rtmpc.R.string.str_connect_hoster);\n                    tvApplyLine.setBackgroundResource(org.ar.rtmpc.R.drawable.shape_room_apply_line);\n                    isApplyLine = false;\n                    isLining = false;\n                }\n            });\n        }\n\n\n        @Override\n        public void onRTCOpenRemoteVideoRender(final String strLivePeerId, final String strPublishId, final String strUserId, final String strUserData) {\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCOpenVideoRenderLeave strLivePeerId:\" + strLivePeerId + \"strUserId:\" + strUserId + \" strUserData:\" + strUserData);\n                    final VideoRenderer render = mVideoView.openRemoteVideoRender(strLivePeerId);\n                    mGuestKit.setRTCRemoteVideoRender(strPublishId, render.GetRenderPointer());\n                }\n            });\n        }\n\n        @Override\n        public void onRTCCloseRemoteVideoRender(final String strLivePeerId, final String strPublishId, final String strUserId) {\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    Log.d(\"RTMPC\", \"onRTCCloseVideoRender strLivePeerId:\" + strLivePeerId + \"strUserId:\" + strUserId);\n                    if (mGuestKit != null && mVideoView != null ) {\n                        mGuestKit.setRTCRemoteVideoRender(strPublishId, 0);\n                        mVideoView.removeRemoteRender(strLivePeerId);\n                    }\n                }\n            });\n        }\n\n        @Override\n        public void onRTCOpenRemoteAudioLine(String s, String s1, String s2) {\n\n        }\n\n        @Override\n        public void onRTCCloseRemoteAudioLine(String s, String s1) {\n\n        }\n\n        @Override\n        public void onRTCLocalAudioActive(int i) {\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    Log.d(\"RTMPC\", \"onRTCLocalAudioActive  \");\n                }\n            });\n        }\n\n        @Override\n        public void onRTCHosterAudioActive(int i) {\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    Log.d(\"RTMPC\", \"onRTCHosterAudioActive  \");\n                }\n            });\n        }\n\n\n        @Override\n        public void onRTCRemoteAudioActive(final String s, String s1, int i) {\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCRemoteAudioActive  peerID:\" + s);\n                }\n            });\n        }\n\n        @Override\n        public void onRTCRemoteAVStatus(final String s, boolean b, boolean b1) {\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCRemoteAVStatus  peerID:\" + s);\n                }\n            });\n        }\n\n        /**\n         * 主播已离开回调\n\n         */\n        @Override\n        public void onRTCLineLeave(final int nCode, String s) {\n            //主播关闭直播\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCLineLeave nCode:\" + nCode);\n                    if (mGuestKit != null) {\n                        mGuestKit.stopRtmpPlay();\n                    }\n                    if (nCode == 0) {\n                        ToastUtil.show(\"主播已离开\");\n                    } else if (nCode == 100) {\n                        ToastUtil.show(\"网络已断开\");\n                    }\n                    finishAnimActivity();\n                }\n            });\n        }\n\n        /**\n         * 连线接通后回调\n         * @param strLivePeerId\n         */\n\n\n        /**\n         * 连线关闭后图像回调\n         * @param strLivePeerId\n         */\n\n\n        /**\n         * 消息回调\n         * @param strCustomID 消息的发送者id\n         * @param strCustomName 消息的发送者昵称\n         * @param strCustomHeader 消息的发送者头像url\n         * @param strMessage 消息内容\n         */\n        @Override\n        public void onRTCUserMessage(final int nType, final String strCustomID, final String strCustomName, final String strCustomHeader, final String strMessage) {\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCUserMessage nType:\" + nType + \"strCustomID:\" + strCustomID + \"strCustomName:\" + strCustomName + \"strCustomHeader:\" + strCustomHeader + \"strMessage:\" + strMessage);\n                    addChatMessageList(new MessageBean(MessageBean.VIDEO, strCustomName, strMessage));\n                }\n            });\n        }\n\n        /**\n         * 观看直播的总人数回调\n         * @param totalMembers 观看直播的总人数\n         */\n        @Override\n        public void onRTCMemberNotify(final String strServerId, final String strRoomId, final int totalMembers) {\n            GuestActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCMemberNotify strServerId:\" + strServerId + \"strRoomId:\" + strRoomId + \"totalMembers:\" + totalMembers);\n                    if (tvMemberNum != null) {\n                        tvMemberNum.setText(\"在线人数\" + totalMembers + \"\");\n                    }\n\n\n                }\n            });\n        }\n\n    };\n\n    public void onClick(View view) {\n        switch (view.getId()) {\n            case org.ar.rtmpc.R.id.btn_close:\n                if (isLining) {\n                    ShowExitDialog();\n                } else {\n                    finishAnimActivity();\n                }\n                break;\n            case org.ar.rtmpc.R.id.iv_message:\n                showChatLayout();\n                break;\n            case org.ar.rtmpc.R.id.tv_apply_line:\n                if (isApplyLine) {\n                    if (mGuestKit != null) {\n                        mGuestKit.hangupRTCLine();\n                        tvApplyLine.setText(\"连麦\");\n                        ibtnCamera.setVisibility(View.GONE);\n                        tvApplyLine.setBackgroundResource(org.ar.rtmpc.R.drawable.shape_room_apply_line);\n                        mVideoView.removeRemoteRender(\"LocalCameraRender\");\n                        isApplyLine = false;\n                    }\n                } else {\n                    if (mGuestKit != null) {\n                        mGuestKit.applyRTCLine();\n                        tvApplyLine.setText(\"挂断\");\n                        tvApplyLine.setBackgroundResource(org.ar.rtmpc.R.drawable.shape_room_hang_up_line);\n                        isApplyLine = true;\n                    }\n                }\n                break;\n            case org.ar.rtmpc.R.id.btn_log:\n                rl_log_layout.setVisibility(View.VISIBLE);\n                break;\n            case org.ar.rtmpc.R.id.ibtn_close_log:\n                rl_log_layout.setVisibility(View.GONE);\n                break;\n            case R.id.btn_camare:\n                mGuestKit.switchCamera();\n                break;\n        }\n    }\n\n    private void showChatLayout() {\n        KeyboardDialogFragment keyboardDialogFragment = new KeyboardDialogFragment();\n        keyboardDialogFragment.show(getSupportFragmentManager(), \"KeyboardDialogFragment\");\n        keyboardDialogFragment.setEdittextListener(new KeyboardDialogFragment.EdittextListener() {\n            @Override\n            public void setTextStr(String text) {\n                addChatMessageList(new MessageBean(MessageBean.VIDEO, ARApplication.getNickName(), text));\n                mGuestKit.sendMessage(0, ARApplication.getNickName(), \"\", text);\n            }\n\n            @Override\n            public void dismiss(DialogFragment dialogFragment) {\n            }\n        });\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/guest/LiveListActivity.java",
    "content": "package org.ar.guest;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.v4.widget.SwipeRefreshLayout;\nimport android.support.v7.widget.LinearLayoutManager;\nimport android.support.v7.widget.RecyclerView;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.view.KeyEvent;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.TextView;\n\nimport com.chad.library.adapter.base.BaseQuickAdapter;\nimport com.yanzhenjie.nohttp.NoHttp;\nimport com.yanzhenjie.nohttp.RequestMethod;\nimport com.yanzhenjie.nohttp.rest.Response;\nimport com.yanzhenjie.nohttp.rest.SimpleResponseListener;\nimport com.yanzhenjie.nohttp.rest.StringRequest;\nimport com.yanzhenjie.permission.AndPermission;\nimport com.yanzhenjie.permission.runtime.Permission;\n\nimport org.ar.BaseActivity;\nimport org.ar.ARApplication;\nimport org.ar.adapter.LiveListAdapter;\nimport org.ar.hoster.AudioHosterActivity;\nimport org.ar.hoster.HosterActivity;\nimport org.ar.rtmpc.BuildConfig;\nimport org.ar.model.LiveBean;\nimport org.ar.DeveloperInfo;\nimport org.ar.utils.MD5;\nimport org.ar.utils.PermissionsCheckUtil;\nimport org.ar.utils.ToastUtil;\nimport org.ar.rtmpc_hybrid.ARRtmpcHttpKit;\nimport org.json.JSONArray;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class LiveListActivity extends BaseActivity implements SwipeRefreshLayout.OnRefreshListener, BaseQuickAdapter.OnItemClickListener, View.OnClickListener {\n\n\n    RecyclerView rvList;\n    SwipeRefreshLayout swipeRefresh;\n    LiveListAdapter mAdapter;\n    private List<LiveBean> live_list = new ArrayList<>();\n    Button btn_video, btn_audio;\n    TextView tvVersion;\n    @Override\n    public int getLayoutId() {\n        return org.ar.rtmpc.R.layout.activity_live_list;\n    }\n\n    @Override\n    public void initView(Bundle savedInstanceState) {\n\n        tvVersion=findViewById(org.ar.rtmpc.R.id.tv_version);\n        tvVersion.setText(\"v \"+ BuildConfig.VERSION_NAME);\n        btn_video = findViewById(org.ar.rtmpc.R.id.btn_video);\n        btn_audio =  findViewById(org.ar.rtmpc.R.id.btn_audio);\n        btn_video.setOnClickListener(this);\n        btn_audio.setOnClickListener(this);\n        rvList =  findViewById(org.ar.rtmpc.R.id.rv_list);\n        swipeRefresh = findViewById(org.ar.rtmpc.R.id.swipe_refresh);\n        mAdapter = new LiveListAdapter();\n        mAdapter.setOnItemClickListener(this);\n        mAdapter.setEmptyView(getEmptyView());\n        swipeRefresh.setOnRefreshListener(this);\n        rvList.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false));\n        rvList.setAdapter(mAdapter);\n\n        AndPermission.with(this).runtime().permission(Permission.RECORD_AUDIO,Permission.CAMERA).start();\n    }\n\n    @Override\n    protected void onResume() {\n        super.onResume();\n        getLiveList();\n    }\n\n    public View getEmptyView(){\n        View view=View.inflate(this, org.ar.rtmpc.R.layout.empty_act_data,null);\n        TextView tvReGet= (TextView) view.findViewById(org.ar.rtmpc.R.id.tv_reget);\n        tvReGet.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                getLiveList();\n            }\n        });\n        return view;\n    }\n    @Override\n    public void onRefresh() {\n        getLiveList();\n    }\n\n\n    @Override\n    public void onItemClick(BaseQuickAdapter adapter, View view, final int position) {\n        if (AndPermission.hasPermissions(LiveListActivity.this,Permission.CAMERA,Permission.RECORD_AUDIO)){\n                Intent intent = new Intent(LiveListActivity.this, mAdapter.getItem(position).getIsAudioLive()==1 ? AudioGuestActivity.class : GuestActivity.class);\n                intent.putExtra(\"pullURL\", mAdapter.getItem(position).getmRtmpPullUrl());\n                intent.putExtra(\"liveId\",mAdapter.getItem(position).getmAnyrtcId());\n                intent.putExtra(\"hostName\",mAdapter.getItem(position).getmHostName());\n                startActivity(intent);\n        }else {\n            PermissionsCheckUtil.showMissingPermissionDialog(LiveListActivity.this, \"请先开启录音和相机权限\");\n        }\n    }\n\n    private void getLiveList() {\n        ARRtmpcHttpKit.getAuthLivingList(this, new ARRtmpcHttpKit.RTMPCHttpCallback() {\n            @Override\n            public void OnRTMPCHttpOK(String s) {\n                if (swipeRefresh != null) {\n                    swipeRefresh.setRefreshing(false);\n                }\n                if (TextUtils.isEmpty(s)) {\n                    return;\n                }\n                try {\n                    live_list.clear();\n                    JSONObject jsonObject = new JSONObject(s);\n                    if (jsonObject.has(\"LiveList\")) {\n                        JSONArray liveList = jsonObject.getJSONArray(\"LiveList\");\n                        JSONArray member = jsonObject.getJSONArray(\"LiveMembers\");\n                        for (int i = 0; i < liveList.length(); i++) {\n                            JSONObject itemJson = new JSONObject(liveList.getString(i));\n                            LiveBean bean = new LiveBean();\n                            bean.setmRtmpPullUrl(itemJson.getString(\"rtmpUrl\"));\n                            bean.setmHlsUrl(itemJson.getString(\"hlsUrl\"));\n                            bean.setmLiveTopic(itemJson.getString(\"liveTopic\"));\n                            bean.setIsAudioLive(itemJson.getInt(\"isAudioLive\"));\n                            bean.setmAnyrtcId(itemJson.getString(\"anyrtcId\"));\n                            bean.setmHostName(itemJson.getString(\"hosterName\"));\n                            if (i <= member.length()) {\n                                bean.setmMemberNum(member.get(i).toString());\n                            }\n                            live_list.add(bean);\n                        }\n                        mAdapter.setNewData(live_list);\n                    }\n                } catch (JSONException e) {\n                    e.printStackTrace();\n                }\n\n\n            }\n\n            @Override\n            public void OnRTMPCHttpFailed(int i) {\n                ToastUtil.show(\"获取列表失败\");\n                if (swipeRefresh != null) {\n                    swipeRefresh.setRefreshing(false);\n                }\n            }\n        });\n    }\n\n\n    @Override\n    public void onClick(View view) {\n        switch (view.getId()) {\n            case org.ar.rtmpc.R.id.btn_audio:\n                if (AndPermission.hasPermissions(LiveListActivity.this,Permission.CAMERA,Permission.RECORD_AUDIO)){\n                        Intent intent = new Intent(LiveListActivity.this,  AudioHosterActivity.class);\n                        intent.putExtra(\"pushURL\", DeveloperInfo.PUSH_URL);\n                        intent.putExtra(\"pullURL\", DeveloperInfo.PULL_URL);\n                        startActivity(intent);\n                }else {\n                    PermissionsCheckUtil.showMissingPermissionDialog(LiveListActivity.this, \"请先开启录音和相机权限\");\n                }\n\n                break;\n            case org.ar.rtmpc.R.id.btn_video:\n                if (AndPermission.hasPermissions(LiveListActivity.this,Permission.CAMERA,Permission.RECORD_AUDIO)){\n                        Intent intent = new Intent(LiveListActivity.this,  HosterActivity.class);\n                        intent.putExtra(\"pushURL\", DeveloperInfo.PUSH_URL);\n                        intent.putExtra(\"pullURL\", DeveloperInfo.PULL_URL);\n                        startActivity(intent);\n                }else {\n                    PermissionsCheckUtil.showMissingPermissionDialog(LiveListActivity.this, \"请先开启录音和相机权限\");\n                }\n                break;\n        }\n    }\n\n\n    @Override\n    public boolean onKeyDown(int keyCode, KeyEvent event) {\n        if (keyCode == KeyEvent.KEYCODE_BACK) {\n            System.exit(0);\n            finishAnimActivity();\n            return true;\n        }\n        return super.onKeyDown(keyCode, event);\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/hoster/AudioHosterActivity.java",
    "content": "package org.ar.hoster;\n\nimport android.content.DialogInterface;\nimport android.media.AudioManager;\nimport android.os.Bundle;\nimport android.support.v4.app.DialogFragment;\nimport android.support.v7.app.AlertDialog;\nimport android.support.v7.widget.LinearLayoutManager;\nimport android.support.v7.widget.RecyclerView;\nimport android.util.Log;\nimport android.view.Gravity;\nimport android.view.KeyEvent;\nimport android.view.View;\nimport android.view.WindowManager;\nimport android.widget.ImageButton;\nimport android.widget.RelativeLayout;\nimport android.widget.TextView;\n\nimport com.chad.library.adapter.base.BaseQuickAdapter;\n\nimport org.ar.BaseActivity;\nimport org.ar.ARApplication;\nimport org.ar.adapter.AudioLineAdapter;\nimport org.ar.adapter.LiveMessageAdapter;\nimport org.ar.adapter.LogAdapter;\nimport org.ar.common.utils.ARAudioManager;\nimport org.ar.rtmpc.R;\nimport org.ar.model.LineBean;\nimport org.ar.model.MessageBean;\nimport org.ar.utils.ARUtils;\nimport org.ar.utils.DisplayUtils;\nimport org.ar.utils.ToastUtil;\nimport org.ar.widgets.CustomDialog;\nimport org.ar.widgets.KeyboardDialogFragment;\nimport org.ar.common.enums.ARVideoCommon;\nimport org.ar.rtmpc_hybrid.ARRtmpcEngine;\nimport org.ar.rtmpc_hybrid.ARRtmpcHosterEvent;\nimport org.ar.rtmpc_hybrid.ARRtmpcHosterKit;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * 音频主播页面\n */\npublic class AudioHosterActivity extends BaseActivity implements BaseQuickAdapter.OnItemChildClickListener {\n\n    TextView tvTitle, tvRtmpOk, tvRtmpStatus, tvRtcOk, tvMemberNum, tv_host_name;\n    RecyclerView rvMsgList;\n    View viewSpace;\n    ImageButton tvLineList;\n    RecyclerView rvLineList,rvLog;\n    RelativeLayout rl_log_layout;\n    private LogAdapter logAdapter;\n    private AudioLineAdapter audioLineAdapter;\n    private ARRtmpcHosterKit mHosterKit;\n    private ARAudioManager mRtmpAudioManager = null;\n    private LiveMessageAdapter mAdapter;\n    private String nickname;\n    private CustomDialog line_dialog;\n    private LineFragment lineFragment;\n    private boolean isShowLineList = false;\n    HosterActivity.LineListener lineListener;\n    private String pushURL = \"\",pullURL=\"\", liveId = ARApplication.LIVE_ID,userId=\"host\"+(int)((Math.random()*9+1)*100000)+\"\";\n    private List<String> applyLineList=new ArrayList<>();//申请连麦的人  这个用于判断小红点显示隐藏\n\n    @Override\n    protected void onResume() {\n        super.onResume();\n    }\n\n    @Override\n    protected void onPause() {\n        super.onPause();\n    }\n\n    @Override\n    public boolean onKeyDown(int keyCode, KeyEvent event) {\n        if (keyCode == KeyEvent.KEYCODE_BACK) {\n            ShowExitDialog();\n        }\n        return false;\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n        if (mHosterKit != null) {\n            mHosterKit.clean();\n            mHosterKit = null;\n        }\n\n        // Close RTMPAudioManager\n        if (mRtmpAudioManager != null) {\n            mRtmpAudioManager.stop();\n            mRtmpAudioManager = null;\n\n        }\n\n\n    }\n\n    @Override\n    public int getLayoutId() {\n        return R.layout.activity_audio_hoster;\n    }\n\n    @Override\n    public void initView(Bundle savedInstanceState) {\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n        tvTitle = findViewById(R.id.tv_title);\n        rl_log_layout=findViewById(R.id.rl_log_layout);\n        rvLog=findViewById(R.id.rv_log);\n        tvRtmpOk = findViewById(R.id.tv_rtmp_ok);\n        tvRtmpStatus = findViewById(R.id.tv_rtmp_status);\n        tvRtcOk = findViewById(R.id.tv_rtc_ok);\n        rvMsgList = findViewById(R.id.rv_msg_list);\n        viewSpace = findViewById(R.id.view_space);\n        mImmersionBar.titleBar(viewSpace).init();\n        tvMemberNum = findViewById(R.id.tv_member_num);\n        tvLineList = findViewById(R.id.tv_line_list);\n        rvLineList = findViewById(R.id.rv_line_list);\n        tv_host_name = findViewById(R.id.tv_host_name);\n        initLineFragment();\n        logAdapter = new LogAdapter();\n        rvLog.setLayoutManager(new LinearLayoutManager(this));\n        logAdapter.bindToRecyclerView(rvLog);\n        mAdapter = new LiveMessageAdapter();\n        audioLineAdapter = new AudioLineAdapter(true);\n        audioLineAdapter.setOnItemChildClickListener(this);\n        rvLineList.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));\n        rvLineList.setAdapter(audioLineAdapter);\n        rvMsgList.setLayoutManager(new LinearLayoutManager(this));\n        rvMsgList.setAdapter(mAdapter);\n        pushURL = getIntent().getStringExtra(\"pushURL\");\n        pullURL=getIntent().getStringExtra(\"pullURL\");\n        tvTitle.setText(\"房间ID：\" + liveId);\n        nickname = ARApplication.getNickName();\n        tv_host_name.setText(nickname);\n        mRtmpAudioManager = ARAudioManager.create(this);\n        mRtmpAudioManager.start(new ARAudioManager.AudioManagerEvents() {\n            @Override\n            public void onAudioDeviceChanged(ARAudioManager.AudioDevice audioDevice, Set<ARAudioManager.AudioDevice> set) {\n\n            }\n        });\n        ARRtmpcEngine.Inst().getHosterOption().setMediaType(ARVideoCommon.ARMediaType.Audio);\n        mHosterKit = new ARRtmpcHosterKit(mHosterListener);\n        mHosterKit.startPushRtmpStream(pushURL);\n        mHosterKit.createRTCLine(\"\", liveId, \"host\", getUserData(), getLiveInfo(pullURL, pullURL));\n    }\n\n    public String getLiveInfo(String pullUrl, String hlsUrl) {\n        JSONObject liveInfo = new JSONObject();\n\n        try {\n            liveInfo.put(\"hosterId\", userId);\n            liveInfo.put(\"rtmpUrl\", pullUrl);\n            liveInfo.put(\"hlsUrl\", hlsUrl);\n            liveInfo.put(\"liveTopic\", liveId);\n            liveInfo.put(\"anyrtcId\", liveId);\n            liveInfo.put(\"isAudioLive\", 1);\n            liveInfo.put(\"hosterName\", nickname);\n        } catch (JSONException e) {\n            e.printStackTrace();\n        }\n        return liveInfo.toString();\n    }\n\n    public String getUserData() {\n        JSONObject user = new JSONObject();\n        try {\n            user.put(\"isHost\", 1);\n            user.put(\"userId\", userId);\n            user.put(\"nickName\", ARApplication.getNickName());\n            user.put(\"headUrl\", \"www.baidu.com\");\n\n        } catch (JSONException e) {\n            e.printStackTrace();\n        }\n        return user.toString();\n    }\n\n    private void onAudioManagerChangedState() {\n        // TODO(henrika): disable video if\n        // AppRTCAudioManager.AudioDevice.EARPIECE\n        // is active.\n        setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);\n    }\n\n\n    /**\n     * 更细列表\n     *\n     * @param chatMessageBean\n     */\n    private void addChatMessageList(MessageBean chatMessageBean) {\n        // 150 条 修改；\n\n        if (chatMessageBean == null) {\n            return;\n        }\n\n        if (mAdapter.getData().size() < 150) {\n            mAdapter.addData(chatMessageBean);\n        } else {\n            mAdapter.remove(0);\n            mAdapter.addData(chatMessageBean);\n        }\n        rvMsgList.smoothScrollToPosition(mAdapter.getData().size() - 1);\n    }\n\n    private void showChatLayout() {\n        KeyboardDialogFragment keyboardDialogFragment = new KeyboardDialogFragment();\n        keyboardDialogFragment.show(getSupportFragmentManager(), \"KeyboardDialogFragment\");\n        keyboardDialogFragment.setEdittextListener(new KeyboardDialogFragment.EdittextListener() {\n            @Override\n            public void setTextStr(String text) {\n                addChatMessageList(new MessageBean(MessageBean.AUDIO, nickname, text));\n                mHosterKit.sendMessage(0, nickname, \"\", text);\n            }\n\n            @Override\n            public void dismiss(DialogFragment dialogFragment) {\n            }\n        });\n    }\n\n\n    private void ShowExitDialog() {\n        AlertDialog.Builder build = new AlertDialog.Builder(this);\n        build.setTitle(R.string.str_exit);\n        build.setMessage(R.string.str_live_stop);\n        build.setPositiveButton(R.string.str_ok, new DialogInterface.OnClickListener() {\n\n            @Override\n            public void onClick(DialogInterface dialog, int which) {\n                // TODO Auto-generated method stub\n                finishAnimActivity();\n            }\n        });\n        build.setNegativeButton(R.string.str_cancel, new DialogInterface.OnClickListener() {\n\n            @Override\n            public void onClick(DialogInterface dialog, int which) {\n                // TODO Auto-generated method stub\n\n            }\n        });\n\n        build.show();\n    }\n    public void printLog(String log){\n        Log.d(\"RTMPC\", log);\n        logAdapter.addData(log);\n    }\n\n    /**\n     * 主播回调信息接口\n     */\n    private ARRtmpcHosterEvent mHosterListener = new ARRtmpcHosterEvent() {\n        /**\n         * rtmp连接成功\n         */\n        @Override\n        public void onRtmpStreamOk() {\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpStreamOk\");\n                    if (tvRtmpOk != null) {\n                        tvRtmpOk.setText(\"RTMP连接成功\");\n                    }\n                }\n            });\n        }\n\n        /**\n         * rtmp 重连次数\n         * @param times 重连次数\n         */\n        @Override\n        public void onRtmpStreamReconnecting(final int times) {\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpStreamReconnecting times:\" + times);\n\n                }\n            });\n        }\n\n        /**\n         * rtmp 推流状态\n         * @param delayMs 推流延时\n         * @param netBand 推流码流\n         */\n        @Override\n        public void onRtmpStreamStatus(final int delayMs, final int netBand) {\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpStreamStatus delayMs:\" + delayMs + \"netBand:\" + netBand);\n                    if (tvRtmpStatus != null) {\n                        tvRtmpStatus.setText(String.format(getString(R.string.str_rtmp_status), delayMs + \"ms\", netBand / 1024 / 8 + \"kb/s\"));\n                    }\n\n                }\n            });\n        }\n\n        /**\n         * rtmp推流失败回调\n         * @param code\n         */\n        @Override\n        public void onRtmpStreamFailed(final int code) {\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpStreamFailed code:\" + code);\n                    if (tvRtmpStatus != null) {\n                        tvRtmpStatus.setText(\"推流失败\");\n                    }\n                }\n            });\n        }\n\n        /**\n         * rtmp 推流关闭回调\n         */\n        @Override\n        public void onRtmpStreamClosed() {\n            Log.d(\"RTMPC\", \"onRtmpStreamClosed \");\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpStreamClosed \");\n                    if (tvRtmpStatus != null) {\n                        tvRtmpStatus.setText(\"RTMP流关闭\");\n                    }\n                }\n            });\n\n        }\n\n\n        /**\n         * RTC 连接回调\n         * @param code 0： 连接成功\n         */\n        @Override\n        public void onRTCCreateLineResult(final int code, String s) {\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调： onRTCCreateLineResult  code:\" + code);\n                    if (code == 0) {\n                        if (tvRtcOk != null) {\n                            tvRtcOk.setText(R.string.str_rtc_connect_success);\n                        }\n                    } else {\n                        if (tvRtcOk != null) {\n                            tvRtcOk.setText(ARUtils.getErrString(code));\n                        }\n                    }\n                }\n            });\n        }\n\n        /**\n         * 游客有申请连线回调\n         *\n         * @param strLivePeerID\n         * @param strCustomID\n         * @param strUserData\n         */\n\n        @Override\n        public void onRTCApplyToLine(final String strLivePeerID, final String strCustomID, final String strUserData) {\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCApplyToLine  strLivePeerID:\" + strLivePeerID + \" strCustomID:\" + strCustomID + \" strUserData:\" + strUserData);\n                    try {\n                        JSONObject jsonObject = new JSONObject(strUserData);\n                        if (line_dialog != null && lineListener != null && mHosterKit != null) {\n                            lineListener.AddAudioGuest(new LineBean(strLivePeerID, jsonObject.getString(\"nickName\"), false), mHosterKit);\n                            tvLineList.setSelected(true);\n                        }\n                        applyLineList.add(strLivePeerID);\n                    } catch (JSONException e) {\n                        e.printStackTrace();\n                    }\n                }\n            });\n        }\n\n\n        /**\n         * 游客挂断连线回调\n         * @param strLivePeerID\n         */\n        @Override\n        public void onRTCCancelLine(final int nCode, final String strLivePeerID) {\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCCancelLine  strLivePeerID:\" + strLivePeerID + \"nCode:\" + nCode);\n\n                    if (nCode == 602) {\n                        ToastUtil.show(\"连麦人数已满\");\n                    }\n                    if (nCode == 0) {\n                        if (line_dialog != null && lineListener != null) {\n                            lineListener.RemoveGuest(strLivePeerID);\n                        }\n                        if (applyLineList.contains(strLivePeerID)) {\n                            applyLineList.remove(strLivePeerID);\n                        }\n                        if (applyLineList.size()==0){//小红点\n                            tvLineList.setSelected(false);\n                        }\n                    }\n                }\n            });\n        }\n\n\n        @Override\n        public void onRTCOpenRemoteVideoRender(String s, String s1, String s2, String s3) {\n\n        }\n\n        @Override\n        public void onRTCCloseRemoteVideoRender(String s, String s1, String s2) {\n\n        }\n\n        @Override\n        public void onRTCOpenRemoteAudioLine(final String strLivePeerId, final String strUserId, final String strUserData) {\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调： onRTCOpenRemoteAudioLine  strLivePeerID:\" + strLivePeerId + \" strUserId:\" + strUserId + \" strUserData:\" + strUserData);\n                    try {\n                        JSONObject jsonObject = new JSONObject(strUserData);\n                        audioLineAdapter.addData(new LineBean(strLivePeerId, jsonObject.getString(\"nickName\"), false));\n                    } catch (JSONException e) {\n                        e.printStackTrace();\n                    }\n\n                }\n            });\n        }\n\n        @Override\n        public void onRTCCloseRemoteAudioLine(final String strLivePeerId, final String strUserId) {\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调： onRTCCloseRemoteAudioLine  strLivePeerID:\" + strLivePeerId + \" strUserId:\" + strUserId);\n                    int index = 9;\n                    for (int i = 0; i < audioLineAdapter.getData().size(); i++) {\n                        if (audioLineAdapter.getItem(i).peerId.equals(strLivePeerId)) {\n                            index = i;\n                        }\n                    }\n                    if (index != 9 && index <= audioLineAdapter.getData().size()) {\n                        audioLineAdapter.remove(index);\n                    }\n\n                }\n            });\n        }\n\n        @Override\n        public void onRTCLocalAudioActive(final int leave) {\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    Log.d(\"RTMPC\", \"onRTLocalAudioActive leave:\" + leave);\n                }\n            });\n        }\n\n\n        @Override\n        public void onRTCRemoteAudioActive(final String strLivePeerId, final String strUserId, final int nTime) {\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    Log.d(\"RTMPC\", \"onRTCAudioActive  strLivePeerID:\" + strLivePeerId + \" strUserId:\" + strUserId + \" nTime:\" + nTime);\n                    if (strLivePeerId.equals(\"RTMPC_Hoster\")) {//主播\n\n                    } else {\n//                        for (int i = 0; i < audioLineAdapter.getData().size(); i++) {\n//                            if (strLivePeerId.equals(audioLineAdapter.getData().get(i).peerId)) {\n//                                audioLineAdapter.getItem(i).setStartAnim(true);\n//                                audioLineAdapter.notifyItemChanged(i);\n//                            }\n//                        }\n                    }\n\n\n                }\n            });\n        }\n\n        @Override\n        public void onRTCRemoteAVStatus(final String s, boolean b, boolean b1) {\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCRemoteAVStatus peerID:\"+s);\n                }\n            });\n        }\n\n        /**\n         * RTC 连接关闭回调\n         * @param code 207：请去AnyRTC官网申请账号,如有疑问请联系客服!\n         * @param strReason\n         */\n        /**\n         * RTC 连接关闭回调\n         * @param code 207：请去AnyRTC官网申请账号,如有疑问请联系客服!\n         */\n        @Override\n        public void onRTCLineClosed(final int code, String s) {\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCLineClosedLine  code:\" + code);\n                }\n            });\n        }\n\n\n        /**\n         * 消息回调\n         * @param strCustomID 消息的发送者id\n         * @param strCustomName 消息的发送者昵称\n         * @param strCustomHeader 消息的发送者头像url\n         * @param strMessage 消息内容\n         */\n        @Override\n        public void onRTCUserMessage(final int nType, final String strCustomID, final String strCustomName, final String strCustomHeader, final String strMessage) {\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCUserMessage  nType:\" + nType + \" strUserId:\" + strCustomID + \" strCustomName:\" + strCustomName + \" strCustomHeader:\" + strCustomHeader + \" strMessage:\" + strMessage);\n                    addChatMessageList(new MessageBean(MessageBean.AUDIO, strCustomName, strMessage));\n                }\n            });\n        }\n\n        /**\n         * 观看直播的总人数回调\n         * @param totalMembers 观看直播的总人数\n         */\n        @Override\n        public void onRTCMemberNotify(final String strServerId, final String strRoomId, final int totalMembers) {\n            AudioHosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCMemberNotify strServerId:\" + strServerId + \"strRoomId:\" + strRoomId + \"totalMembers:\" + totalMembers);\n                    tvMemberNum.setText(\"在线观看人数\" + totalMembers + \"\");\n                }\n            });\n        }\n\n\n    };\n\n    public void onClick(View view) {\n        switch (view.getId()) {\n            case R.id.btn_close:\n                ShowExitDialog();\n                break;\n            case R.id.iv_message:\n                showChatLayout();\n                break;\n            case R.id.tv_line_list:\n                if (isShowLineList) {\n                    if (line_dialog != null) {\n                        line_dialog.hide();\n                        isShowLineList = false;\n                    }\n                } else {\n                    if (line_dialog != null) {\n                        line_dialog.show();\n                        tvLineList.setSelected(false);\n                        isShowLineList = true;\n                    }\n                }\n                break;\n            case R.id.btn_log:\n                rl_log_layout.setVisibility(View.VISIBLE);\n                break;\n            case R.id.ibtn_close_log:\n                rl_log_layout.setVisibility(View.GONE);\n                break;\n        }\n    }\n\n    private void initLineFragment() {\n        CustomDialog.Builder builder = new CustomDialog.Builder(this);\n        builder.setContentView(R.layout.item_line_list)\n                .setAnimId(R.style.AnimBottom)\n                .setGravity(Gravity.BOTTOM)\n                .setLayoutParams(WindowManager.LayoutParams.MATCH_PARENT, DisplayUtils.getScreenHeightPixels(this) / 3)\n                .setBackgroundDrawable(true)\n                .build();\n        line_dialog = builder.show(new CustomDialog.Builder.onInitListener() {\n            @Override\n            public void init(CustomDialog view) {\n                if (lineFragment == null) {\n                    lineFragment = new LineFragment();\n\n                }\n            }\n        });\n        line_dialog.hide();\n        line_dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {\n            @Override\n            public void onDismiss(DialogInterface dialog) {\n                isShowLineList = false;\n            }\n        });\n\n    }\n\n    public void SetLineListener(HosterActivity.LineListener mLineListener) {\n        this.lineListener = mLineListener;\n    }\n\n\n    @Override\n    public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {\n        if (mHosterKit != null) {\n            mHosterKit.hangupRTCLine(audioLineAdapter.getItem(position).peerId);\n            audioLineAdapter.remove(position);\n        }\n\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/hoster/HosterActivity.java",
    "content": "package org.ar.hoster;\n\nimport android.content.DialogInterface;\nimport android.media.AudioManager;\nimport android.os.Bundle;\nimport android.support.v4.app.DialogFragment;\nimport android.support.v7.app.AlertDialog;\nimport android.support.v7.widget.LinearLayoutManager;\nimport android.support.v7.widget.RecyclerView;\nimport android.util.Log;\nimport android.view.Gravity;\nimport android.view.KeyEvent;\nimport android.view.View;\nimport android.view.WindowManager;\nimport android.widget.ImageButton;\nimport android.widget.LinearLayout;\nimport android.widget.RelativeLayout;\nimport android.widget.TextView;\nimport android.widget.Toast;\n\nimport org.ar.BaseActivity;\nimport org.ar.ARApplication;\nimport org.ar.adapter.LiveMessageAdapter;\nimport org.ar.adapter.LogAdapter;\nimport org.ar.common.utils.ARAudioManager;\nimport org.ar.rtmpc.R;\nimport org.ar.model.LineBean;\nimport org.ar.model.MessageBean;\nimport org.ar.utils.ARUtils;\nimport org.ar.utils.DisplayUtils;\nimport org.ar.utils.ToastUtil;\nimport org.ar.widgets.ARVideoView;\nimport org.ar.widgets.CustomDialog;\nimport org.ar.widgets.KeyboardDialogFragment;\nimport org.ar.common.enums.ARVideoCommon;\nimport org.ar.rtmpc_hybrid.ARRtmpcEngine;\nimport org.ar.rtmpc_hybrid.ARRtmpcHosterEvent;\nimport org.ar.rtmpc_hybrid.ARRtmpcHosterKit;\nimport org.json.JSONException;\nimport org.json.JSONObject;\nimport org.webrtc.VideoRenderer;\n\nimport java.net.URLDecoder;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Set;\n\n\n/**\n * 视频主播页面\n */\npublic class HosterActivity extends BaseActivity {\n    RelativeLayout rlRtmpcVideos,rl_log_layout;\n    TextView tvTitle,tvRtmpOk,tvRtmpStatus,tvRtcOk,tvMemberNum;\n    RecyclerView rvMsgList,rvLog;\n    View viewSpace;\n    ImageButton tvLineList;\n    private ARRtmpcHosterKit mHosterKit;\n    private ARVideoView mVideoView;\n    private ARAudioManager mRtmpAudioManager;\n    private LiveMessageAdapter mAdapter;\n    private LogAdapter logAdapter;\n    private CustomDialog line_dialog;\n    private LineFragment lineFragment;\n    private boolean isShowLineList = false;\n    private LineListener lineListener;\n\n    private String pushURL = \"\",pullURL=\"\";\n    private String liveId= ARApplication.LIVE_ID;\n    private String nickname= ARApplication.getNickName();\n    private String userId=\"host\"+(int)((Math.random()*9+1)*100000)+\"\";\n    private List<String> applyLineList=new ArrayList<>();//申请连麦的人  这个用于判断小红点显示隐藏\n\n    @Override\n    public boolean onKeyDown(int keyCode, KeyEvent event) {\n        if (keyCode == KeyEvent.KEYCODE_BACK) {\n            ShowExitDialog();\n        }\n        return false;\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n\n\n        if (mHosterKit != null) {\n            mVideoView.removeLocalVideoRender();\n            mHosterKit.clean();\n        }\n        // Close RTMPAudioManager\n        if (mRtmpAudioManager != null) {\n            mRtmpAudioManager.stop();\n            mRtmpAudioManager = null;\n        }\n\n    }\n\n    @Override\n    public int getLayoutId() {\n        return R.layout.activity_hoster;\n    }\n\n    @Override\n    public void initView(Bundle savedInstanceState) {\n        //设置屏幕常亮\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n         rlRtmpcVideos=findViewById(R.id.rl_rtmpc_videos);\n        rl_log_layout=findViewById(R.id.rl_log_layout);\n        rvLog=findViewById(R.id.rv_log);\n         tvTitle = findViewById(R.id.tv_title);\n         tvRtmpOk = findViewById(R.id.tv_rtmp_ok);\n         tvRtmpStatus = findViewById(R.id.tv_rtmp_status);\n         tvRtcOk = findViewById(R.id.tv_rtc_ok);\n         rvMsgList = findViewById(R.id.rv_msg_list);\n         viewSpace=findViewById(R.id.view_space);\n        mImmersionBar.titleBar(viewSpace).init();\n         tvMemberNum=findViewById(R.id.tv_member_num);\n         tvLineList=findViewById(R.id.tv_line_list);\n\n        pushURL = getIntent().getStringExtra(\"pushURL\");\n        pullURL=getIntent().getStringExtra(\"pullURL\");\n        initLineFragment();\n        mAdapter = new LiveMessageAdapter();\n        rvMsgList.setLayoutManager(new LinearLayoutManager(this));\n        rvMsgList.setAdapter(mAdapter);\n\n        logAdapter = new LogAdapter();\n        rvLog.setLayoutManager(new LinearLayoutManager(this));\n        logAdapter.bindToRecyclerView(rvLog);\n\n        //设置视频质量 参数对应清晰度，可查看API文档\n        ARRtmpcEngine.Inst().getHosterOption().setVideoProfile(ARVideoCommon.ARVideoProfile.ARVideoProfile480x640);\n        tvTitle.setText(\"房间ID:\" + liveId);\n        ARRtmpcEngine.Inst().getHosterOption().setVideoOrientation(ARVideoCommon.ARVideoOrientation.Portrait);\n        //音频管理对象  当靠近听筒时将会减小音量\n        mRtmpAudioManager = ARAudioManager.create(this);\n        mRtmpAudioManager.start(new ARAudioManager.AudioManagerEvents() {\n            @Override\n            public void onAudioDeviceChanged(ARAudioManager.AudioDevice audioDevice, Set<ARAudioManager.AudioDevice> set) {\n\n            }\n        });\n        ARRtmpcEngine.Inst().getHosterOption().setMediaType(ARVideoCommon.ARMediaType.Video);\n        //实例化主播对象\n\n        mHosterKit = new ARRtmpcHosterKit(mHosterListener);\n        mHosterKit.setAudioActiveCheck(true);\n        //实例化连麦窗口对象\n        mVideoView = new ARVideoView(rlRtmpcVideos, ARRtmpcEngine.Inst().egl(), this,false,true);\n        mVideoView.setVideoViewLayout(false,Gravity.RIGHT,LinearLayout.VERTICAL);\n        mVideoView.setVideoLayoutOnclickEvent(mBtnVideoCloseEvent);\n        //设置本地视频采集\n        VideoRenderer render = mVideoView.openLocalVideoRender();\n        mHosterKit.setLocalVideoCapturer(render.GetRenderPointer());\n        //开始推流\n        mHosterKit.startPushRtmpStream(pushURL);\n        //创建RTC连接，必须放在开始推流之后\n        mHosterKit.createRTCLine(\"\", liveId, userId, getUserData(), getLiveInfo(pullURL,pullURL));\n        //设置音频连麦直播，默认视频\n\n\n\n        //=====================================视频数据相关===============================\n//        /**\n//         *  设置是否采用ARCamera，默认使用ARCamera， 如果设置为false，必须调用setByteBufferFrameCaptured才能本地显示\n//         * @param usedARCamera true：使用ARCamera，false：不使用ARCamera采集的数据\n//         */\n//        mHosterKit.setUsedARCamera(true);\n//        /**\n//         * 设置本地显示的视频数据\n//         * @param data 相机采集数据\n//         * @param width 宽\n//         * @param height 高\n//         * @param rotation 旋转角度\n//         * @param timeStamp 时间戳\n//         */\n//        mHosterKit.setByteBufferFrameCaptured();\n       //设置ARCamera视频回调数据\n//        mHosterKit.setARCameraCaptureObserver(new VideoCapturer.ARCameraCapturerObserver() {\n//            @Override\n//            public void onByteBufferFrameCaptured(byte[] data, int width, int height, int rotation, long timeStamp) {\n//            }\n//        });\n        //=====================================视频数据相关===============================\n    }\n\n    public String getLiveInfo(String pullUrl,String hlsUrl) {\n        JSONObject liveInfo = new JSONObject();\n\n        try {\n            liveInfo.put(\"hosterId\", userId);\n            liveInfo.put(\"rtmpUrl\", pullUrl);\n            liveInfo.put(\"hlsUrl\", hlsUrl);\n            liveInfo.put(\"liveTopic\", ARApplication.LIVE_ID);\n            liveInfo.put(\"anyrtcId\", ARApplication.LIVE_ID);\n            liveInfo.put(\"isAudioLive\", 0);\n            liveInfo.put(\"hosterName\", ARApplication.getNickName());\n        } catch (JSONException e) {\n            e.printStackTrace();\n        }\n        return liveInfo.toString();\n    }\n\n    public String getUserData() {\n        JSONObject user = new JSONObject();\n        try {\n            user.put(\"isHost\", 1);\n            user.put(\"userId\", userId);\n            user.put(\"nickName\", ARApplication.getNickName());\n            user.put(\"headUrl\", \"www.baidu.com\");\n\n        } catch (JSONException e) {\n            e.printStackTrace();\n        }\n        return user.toString();\n    }\n\n    private void onAudioManagerChangedState() {\n        // TODO(henrika): disable video if\n        // AppRTCAudioManager.AudioDevice.EARPIECE\n        // is active.\n        setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);\n    }\n\n\n    /**\n     * 连线时小图标的关闭按钮\n     */\n    private ARVideoView.VideoLayoutOnclickEvent mBtnVideoCloseEvent = new ARVideoView.VideoLayoutOnclickEvent() {\n        @Override\n        public void onCloseVideoRender(View view, String strPeerId) {\n            mHosterKit.hangupRTCLine(strPeerId);\n\n        }\n    };\n\n    /**\n     * 更细列表\n     *\n     * @param chatMessageBean\n     */\n    private void addChatMessageList(MessageBean chatMessageBean) {\n        // 150 条 修改；\n\n        if (chatMessageBean == null) {\n            return;\n        }\n\n        if (mAdapter.getData().size() < 150) {\n            mAdapter.addData(chatMessageBean);\n        } else {\n            mAdapter.remove(0);\n            mAdapter.addData(chatMessageBean);\n        }\n        rvMsgList.smoothScrollToPosition(mAdapter.getData().size() - 1);\n    }\n\n\n    private void showChatLayout() {\n        KeyboardDialogFragment keyboardDialogFragment = new KeyboardDialogFragment();\n        keyboardDialogFragment.show(getSupportFragmentManager(), \"KeyboardDialogFragment\");\n        keyboardDialogFragment.setEdittextListener(new KeyboardDialogFragment.EdittextListener() {\n            @Override\n            public void setTextStr(String text) {\n                addChatMessageList(new MessageBean(MessageBean.VIDEO, nickname, text));\n                mHosterKit.sendMessage(0, nickname, \"\", text);\n            }\n\n            @Override\n            public void dismiss(DialogFragment dialogFragment) {\n            }\n        });\n    }\n\n    private void ShowExitDialog() {\n        AlertDialog.Builder build = new AlertDialog.Builder(this);\n        build.setTitle(R.string.str_exit);\n        build.setMessage(R.string.str_live_stop);\n        build.setPositiveButton(R.string.str_ok, new DialogInterface.OnClickListener() {\n\n            @Override\n            public void onClick(DialogInterface dialog, int which) {\n                // TODO Auto-generated method stub\n                if (mHosterKit != null) {\n                    mHosterKit.stopRtmpStream();\n                }\n                finishAnimActivity();\n            }\n        });\n        build.setNegativeButton(R.string.str_cancel, new DialogInterface.OnClickListener() {\n\n            @Override\n            public void onClick(DialogInterface dialog, int which) {\n                // TODO Auto-generated method stub\n\n            }\n        });\n\n        build.show();\n    }\n\n\n    public void printLog(String log){\n        Log.d(\"RTMPC\", log);\n        logAdapter.addData(log);\n    }\n    /**\n     * 主播回调信息接口\n     */\n    private ARRtmpcHosterEvent mHosterListener = new ARRtmpcHosterEvent() {\n        /**\n         * rtmp连接成功\n         */\n        @Override\n        public void onRtmpStreamOk() {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpStreamOk\");\n                    if (tvRtmpOk != null) {\n                        tvRtmpOk.setText(\"Rtmp连接成功\");\n                    }\n                }\n            });\n        }\n\n        /**\n         * rtmp 重连次数\n         * @param times 重连次数\n         */\n        @Override\n        public void onRtmpStreamReconnecting(final int times) {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpStreamReconnecting times:\" + times);\n                    if (tvRtmpStatus != null) {\n                        tvRtmpStatus.setText(String.format(getString(R.string.str_reconnect_times), times));\n                    }\n                }\n            });\n        }\n\n        /**\n         * rtmp 推流状态\n         * @param delayMs 推流延时\n         * @param netBand 推流码流\n         */\n        @Override\n        public void onRtmpStreamStatus(final int delayMs, final int netBand) {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpStreamStatus delayMs:\" + delayMs + \"netBand:\" + netBand);\n                    if (tvRtmpStatus != null) {\n                        tvRtmpStatus.setText(String.format(getString(R.string.str_rtmp_status), delayMs + \"ms\", netBand / 1024 / 8 + \"kb/s\"));\n                    }\n                }\n            });\n        }\n\n        /**\n         * rtmp推流失败回调\n         * @param code\n         */\n        @Override\n        public void onRtmpStreamFailed(final int code) {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpStreamFailed code:\" + code);\n                    if (tvRtcOk != null) {\n                        tvRtcOk.setText(R.string.str_rtmp_connect_failed);\n                    }\n                }\n            });\n        }\n\n        /**\n         * rtmp 推流关闭回调\n         */\n        @Override\n        public void onRtmpStreamClosed() {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRtmpStreamClosed \");\n                    finish();\n                }\n            });\n\n        }\n\n\n        /**\n         * RTC 连接回调\n         * @param code 0： 连接成功\n         */\n        @Override\n        public void onRTCCreateLineResult(final int code, String s) {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调： onRTCCreateLineResult  code:\" + code);\n                    if (tvRtcOk != null) {\n                        if (code == 0) {\n                            tvRtcOk.setText(R.string.str_rtc_connect_success);\n                        } else {\n                            tvRtcOk.setText(ARUtils.getErrString(code));\n                        }\n                    }\n                }\n            });\n        }\n\n\n        /**\n         * 游客有申请连线回调\n         *\n         * @param strLivePeerID\n         * @param strCustomID\n         * @param strUserData\n         */\n        @Override\n        public void onRTCApplyToLine(final String strLivePeerID, final String strCustomID, final String strUserData) {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCApplyToLine  strLivePeerID:\" + strLivePeerID + \" strCustomID:\" + strCustomID + \" strUserData:\" + strUserData);\n                    try {\n                        String userdata = URLDecoder.decode(strUserData);\n                        JSONObject jsonObject = new JSONObject(userdata);\n                        if (line_dialog != null && lineListener != null && mHosterKit != null && tvLineList != null) {\n                            lineListener.AddGuest(new LineBean(strLivePeerID, jsonObject.getString(\"nickName\"), false), mHosterKit);\n                            tvLineList.setSelected(true);\n                        }\n                        applyLineList.add(strLivePeerID);\n                    } catch (JSONException e) {\n                        e.printStackTrace();\n                    }\n\n                }\n            });\n        }\n\n\n        /**\n         * 游客挂断连线回调\n         * @param strLivePeerID\n         */\n        @Override\n        public void onRTCCancelLine(final int nCode, final String strLivePeerID) {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCCancelLine  strLivePeerID:\" + strLivePeerID + \"nCode:\" + nCode);\n                    if (nCode == 0) {\n                        if (line_dialog != null && lineListener != null) {\n                            lineListener.RemoveGuest(strLivePeerID);\n                        }\n                        if (applyLineList.contains(strLivePeerID)) {\n                            applyLineList.remove(strLivePeerID);\n                        }\n                        if (applyLineList.size()==0){//小红点\n                            tvLineList.setSelected(false);\n                        }\n                    }\n\n                    if (nCode == 602) {\n                        ToastUtil.show(\"连麦人数已满\");\n                    }\n                }\n            });\n        }\n\n\n        @Override\n        public void onRTCOpenRemoteVideoRender(final String strLivePeerId, final String strPublishId, final String strUserId, final String strUserData) {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCOpenVideoRender  strPublishId:\" + strPublishId + \" strUserId:\" + strUserId + \" strUserData:\" + strUserData);\n                    final VideoRenderer render = mVideoView.openRemoteVideoRender(strLivePeerId);\n                    if (null != render) {\n                        mHosterKit.setRTCRemoteVideoRender(strPublishId, render.GetRenderPointer());\n                    }\n                }\n            });\n        }\n\n        @Override\n        public void onRTCCloseRemoteVideoRender(final String strLivePeerId, final String strPublishId, final String strUserId) {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCCloseVideoRender  strPublishId:\" + strPublishId + \" strUserId:\" + strUserId);\n                    mHosterKit.setRTCRemoteVideoRender(strPublishId, 0);\n                    mVideoView.removeRemoteRender(strLivePeerId);\n                    if (line_dialog != null && lineListener != null) {\n                        lineListener.RemoveGuest(strLivePeerId);\n                    }\n                }\n            });\n        }\n\n        @Override\n        public void onRTCOpenRemoteAudioLine(String s, String s1, String s2) {\n\n        }\n\n        @Override\n        public void onRTCCloseRemoteAudioLine(String s, String s1) {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                }\n            });\n        }\n\n        @Override\n        public void onRTCLocalAudioActive(int i) {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    Log.d(\"RTMPC\", \"onRTLocalAudioActive \");\n                }\n            });\n        }\n\n\n        @Override\n        public void onRTCRemoteAudioActive(String s, String s1, int i) {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    Log.d(\"RTMPC\", \"onRTCRemoteAudioActive \");\n                }\n            });\n        }\n\n        @Override\n        public void onRTCRemoteAVStatus(final String s, boolean b, boolean b1) {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCRemoteAVStatus peerID:\"+s);\n                }\n            });\n        }\n\n\n        /**\n         * RTC 连接关闭回调\n         * @param code 207：请去AnyRTC官网申请账号,如有疑问请联系客服!\n         */\n        @Override\n        public void onRTCLineClosed(final int code, String s) {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    Log.d(\"RTMPC\", \"onRTCLineClosedLine  code:\" + code);\n                    if (code == 207) {\n                        Toast.makeText(HosterActivity.this, getString(R.string.str_apply_anyrtc_account), Toast.LENGTH_LONG).show();\n                        finish();\n                    }\n                }\n            });\n        }\n\n        /**\n         * 连线接通时的视频图像回调；\n         */\n\n\n        /**\n         * 连线关闭时的视频图像回调；\n         */\n\n\n        /**\n         * 消息回调\n         * @param strCustomID 消息的发送者id\n         * @param strCustomName 消息的发送者昵称\n         * @param strCustomHeader 消息的发送者头像url\n         * @param strMessage 消息内容\n         */\n        @Override\n        public void onRTCUserMessage(final int nType, final String strCustomID, final String strCustomName, final String strCustomHeader, final String strMessage) {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCUserMessage  nType:\" + nType + \" strUserId:\" + strCustomID + \" strCustomName:\" + strCustomName + \" strCustomHeader:\" + strCustomHeader + \" strMessage:\" + strMessage);\n                    addChatMessageList(new MessageBean(MessageBean.VIDEO, strCustomName, strMessage));\n                }\n            });\n        }\n\n        /**\n         * 观看直播的总人数回调\n         * @param totalMembers 观看直播的总人数\n         */\n        @Override\n        public void onRTCMemberNotify(final String strServerId, final String strRoomId, final int totalMembers) {\n            HosterActivity.this.runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    printLog(\"回调：onRTCMemberNotify strServerId:\" + strServerId + \"strRoomId:\" + strRoomId + \"totalMembers:\" + totalMembers);\n                    tvMemberNum.setText(\"在线人数：\" + totalMembers + \"\");\n\n                }\n            });\n        }\n\n    };\n\n\n    public void onClick(View view) {\n        switch (view.getId()) {\n            case R.id.btn_camare:\n                if (mHosterKit == null) {\n                    return;\n                }\n                mHosterKit.switchCamera();\n                break;\n            case R.id.btn_close:\n                ShowExitDialog();\n                break;\n            case R.id.iv_message:\n                showChatLayout();\n                break;\n            case R.id.tv_line_list:\n                if (isShowLineList) {\n                    if (line_dialog != null) {\n                        line_dialog.hide();\n                        isShowLineList = false;\n                    }\n                } else {\n                    if (line_dialog != null) {\n                        line_dialog.show();\n                        tvLineList.setSelected(false);\n                        isShowLineList = true;\n                    }\n                }\n                break;\n            case R.id.btn_log:\n                rl_log_layout.setVisibility(View.VISIBLE);\n                break;\n            case R.id.ibtn_close_log:\n                rl_log_layout.setVisibility(View.GONE);\n                break;\n        }\n    }\n\n\n    private void initLineFragment() {\n        CustomDialog.Builder builder = new CustomDialog.Builder(this);\n        builder.setContentView(R.layout.item_line_list)\n                .setAnimId(R.style.AnimBottom)\n                .setGravity(Gravity.BOTTOM)\n                .setLayoutParams(WindowManager.LayoutParams.MATCH_PARENT, DisplayUtils.getScreenHeightPixels(this) / 3)\n                .setBackgroundDrawable(true)\n                .build();\n        line_dialog = builder.show(new CustomDialog.Builder.onInitListener() {\n            @Override\n            public void init(CustomDialog view) {\n                if (lineFragment == null) {\n                    lineFragment = new LineFragment();\n                }\n            }\n        });\n        line_dialog.hide();\n        line_dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {\n            @Override\n            public void onDismiss(DialogInterface dialog) {\n                isShowLineList = false;\n            }\n        });\n\n    }\n\n\n\n\n    public interface LineListener {\n        void AddAudioGuest(LineBean lineBean, ARRtmpcHosterKit hosterKit);//添加音频游客的申请到列表\n\n        void AddGuest(LineBean lineBean, ARRtmpcHosterKit hosterKit);//添加游客的申请到列表\n\n        void RemoveGuest(String peerid);//从列表移除游客\n    }\n\n    public void SetLineListener(LineListener mLineListener) {\n        this.lineListener = mLineListener;\n    }\n\n    public void closeLineDialog() {\n        if (line_dialog != null) {\n            line_dialog.hide();\n        }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/hoster/LineFragment.java",
    "content": "package org.ar.hoster;\n\nimport android.os.Bundle;\nimport android.support.annotation.Nullable;\nimport android.support.v4.app.Fragment;\nimport android.support.v4.widget.SwipeRefreshLayout;\nimport android.support.v7.widget.LinearLayoutManager;\nimport android.support.v7.widget.RecyclerView;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport com.chad.library.adapter.base.BaseQuickAdapter;\n\nimport org.ar.adapter.LiveLineAdapter;\nimport org.ar.rtmpc.R;\nimport org.ar.model.LineBean;\nimport org.ar.rtmpc_hybrid.ARRtmpcHosterKit;\n\n/**\n * Created by liuxiaozhong on 2017/9/24.\n */\n\npublic class LineFragment extends Fragment implements HosterActivity.LineListener,BaseQuickAdapter.OnItemChildClickListener{\n\n    private RecyclerView lineList;\n    private LiveLineAdapter mAadapter;\n    private ARRtmpcHosterKit rtmpcHosterKit;\n    private ARRtmpcHosterKit audioHosterKit;\n    private HosterActivity activity;\n    private AudioHosterActivity audioHosterActivity;\n    private SwipeRefreshLayout swipe_refresh;\n    private boolean isAudioLive=false;\n    @Nullable\n    @Override\n    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n\n        View view = inflater.inflate(R.layout.fragment_line, container, false);\n        swipe_refresh= (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh);\n        swipe_refresh.setEnabled(false);\n        lineList= (RecyclerView) view.findViewById(R.id.rv_list);\n        lineList.setLayoutManager(new LinearLayoutManager(getActivity()));\n        mAadapter=new LiveLineAdapter();\n        mAadapter.setEmptyView(R.layout.empty_no_line_data, (ViewGroup) lineList.getParent());\n        mAadapter.setOnItemChildClickListener(this);\n        lineList.setAdapter(mAadapter);\n        if (getActivity() instanceof HosterActivity){\n            isAudioLive=false;\n            activity= (HosterActivity) getActivity();\n            activity.SetLineListener(this);\n        }else {\n            isAudioLive=true;\n            audioHosterActivity= (AudioHosterActivity) getActivity();\n            audioHosterActivity.SetLineListener(this);\n        }\n\n\n        return view;\n\n    }\n\n    @Override\n    public void AddAudioGuest(LineBean lineBean, ARRtmpcHosterKit hosterKit) {\n        isAudioLive=true;\n        this.audioHosterKit=hosterKit;\n        mAadapter.addData(lineBean);\n    }\n\n    @Override\n    public void AddGuest(LineBean lineBean, ARRtmpcHosterKit hosterKit) {\n        isAudioLive=false;\n        this.rtmpcHosterKit=hosterKit;\n        mAadapter.addData(lineBean);\n    }\n\n    @Override\n    public void RemoveGuest(String peerid) {\n        int index=9;\n        for (int i=0;i<mAadapter.getData().size();i++){\n            if (mAadapter.getItem(i).peerId.equals(peerid)){\n                index=i;\n            }\n        }\n        if (index!=9&&index<=mAadapter.getData().size()){\n            mAadapter.remove(index);\n        }\n    }\n\n\n    @Override\n    public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {\n        switch (view.getId()){\n            case R.id.tv_agree:\n                if (isAudioLive){\n                    if (audioHosterKit != null) {\n                        audioHosterKit.acceptRTCLine(mAadapter.getItem(position).peerId);\n                        mAadapter.remove(position);\n\n                    }\n                }else {\n                    if (rtmpcHosterKit != null) {\n                        rtmpcHosterKit.acceptRTCLine(mAadapter.getItem(position).peerId);\n                        mAadapter.remove(position);\n                            if (activity != null) {\n                                activity.closeLineDialog();\n                        }\n                    }\n                }\n\n                break;\n            case R.id.tv_refuse:\n                if (isAudioLive){\n                    if (audioHosterKit != null) {\n                        audioHosterKit.rejectRTCLine(mAadapter.getItem(position).peerId);\n                        mAadapter.remove(position);\n                    }\n                }else {\n                    if (rtmpcHosterKit != null) {\n                        rtmpcHosterKit.rejectRTCLine(mAadapter.getItem(position).peerId);\n                        mAadapter.remove(position);\n                    }\n                }\n                break;\n        }\n    }\n\n    public LiveLineAdapter getmAadapter() {\n        return mAadapter;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/model/LineBean.java",
    "content": "package org.ar.model;\n\n/**\n * Created by liuxiaozhong on 2017/9/24.\n */\n\npublic class LineBean {\n    public String peerId;\n    public String name;\n    public boolean isSelf;\n    public boolean startAnim;\n\n    public LineBean(String peerId, String name,boolean isSelf) {\n        this.peerId = peerId;\n        this.name = name;\n        this.isSelf=isSelf;\n    }\n\n    public boolean isStartAnim() {\n        return startAnim;\n    }\n\n    public void setStartAnim(boolean startAnim) {\n        this.startAnim = startAnim;\n    }\n\n    public boolean isSelf() {\n        return isSelf;\n    }\n\n    public void setSelf(boolean self) {\n        isSelf = self;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/model/LiveBean.java",
    "content": "package org.ar.model;\n\nimport java.io.Serializable;\n\n/**\n * Created by liuxiaozhong on 2017-09-22.\n */\n\npublic class LiveBean implements Serializable{\n\n    public String mRtmpPullUrl;\n    public String mHlsUrl;\n    public String mPushUrl;\n    public String mLiveTopic;\n    public String mAnyrtcId;\n    public int isAudioLive;\n    public int isLiveLandscape;\n    public int liveMode;\n    public String mHostName;\n    public String mMemberNum=\"\";\n\n    public String getmRtmpPullUrl() {\n        return mRtmpPullUrl;\n    }\n\n    public void setmRtmpPullUrl(String mRtmpPullUrl) {\n        this.mRtmpPullUrl = mRtmpPullUrl;\n    }\n\n    public String getmHlsUrl() {\n        return mHlsUrl;\n    }\n\n    public void setmHlsUrl(String mHlsUrl) {\n        this.mHlsUrl = mHlsUrl;\n    }\n\n    public String getmPushUrl() {\n        return mPushUrl;\n    }\n\n    public void setmPushUrl(String mPushUrl) {\n        this.mPushUrl = mPushUrl;\n    }\n\n    public String getmLiveTopic() {\n        return mLiveTopic;\n    }\n\n    public void setmLiveTopic(String mLiveTopic) {\n        this.mLiveTopic = mLiveTopic;\n    }\n\n    public String getmAnyrtcId() {\n        return mAnyrtcId;\n    }\n\n    public void setmAnyrtcId(String mAnyrtcId) {\n        this.mAnyrtcId = mAnyrtcId;\n    }\n\n    public int getIsAudioLive() {\n        return isAudioLive;\n    }\n\n    public void setIsAudioLive(int isAudioLive) {\n        this.isAudioLive = isAudioLive;\n    }\n\n    public int getIsLiveLandscape() {\n        return isLiveLandscape;\n    }\n\n    public void setIsLiveLandscape(int isLiveLandscape) {\n        this.isLiveLandscape = isLiveLandscape;\n    }\n\n    public int getLiveMode() {\n        return liveMode;\n    }\n\n    public void setLiveMode(int liveMode) {\n        this.liveMode = liveMode;\n    }\n\n    public String getmHostName() {\n        return mHostName;\n    }\n\n    public void setmHostName(String mHostName) {\n        this.mHostName = mHostName;\n    }\n\n    public String getmMemberNum() {\n        return mMemberNum;\n    }\n\n    public void setmMemberNum(String mMemberNum) {\n        this.mMemberNum = mMemberNum;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/model/MessageBean.java",
    "content": "package org.ar.model;\n\n/**\n * Created by liuxiaozhong on 2017-09-22.\n */\n\npublic class MessageBean {\n    public final static int VIDEO = 1;\n    public final static int AUDIO = 0\n            ;\n    public int type;//0 video 1 audio\n    public String name;\n    public String content;\n\n    public MessageBean(int type, String name, String content) {\n        this.type = type;\n        this.name = name;\n        this.content = content;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/utils/ARUtils.java",
    "content": "package org.ar.utils;\n\nimport org.ar.ARApplication;\nimport org.ar.rtmpc.R;\n\n/**\n * Created by Skyline on 2016/11/1.\n */\n\npublic enum ARUtils {\n    AnyRTC_OK(0),               // 正常\n    AnyRTC_UNKNOW(1),           // 未知错误\n    AnyRTC_EXCEPTION(2),\t    // SDK调用异常\n\n\n    AnyRTC_NET_ERR(100),\t\t// 网络错误\n    AnyRTC_NET_DISSCONNECT(101),\t// 网络断开\n    AnyRTC_LIVE_ERR(101),\t\t// 直播出错\n\n\n\n    AnyRTC_BAD_REQ(201),\t\t// 服务不支持的错误请求\n    AnyRTC_AUTH_FAIL(202),\t\t// 认证失败\n    AnyRTC_NO_USER(203),\t\t// 此开发者信息不存在\n    AnyRTC_SQL_ERR(204),\t\t// 服务器内部数据库错误\n    AnyRTC_ARREARS(205),\t\t// 账号欠费\n    AnyRTC_LOCKED(206),\t\t    // 账号被锁定\n    AnyRTC_FORCE_EXIT(207),    // 强制离开\n    AnyRTC_ID_INVALIDE(208),\t// AnyRTC ID非法(仅会议和RTCP中检测)\n    AnyRTC_SERVICE_CLOSED (209),// 服务未开通\n    AnyRTC_BUNDLE_ID_ERR (210),\t// Bundle ID不匹配\n    AnyRTC_PUB_GONE (211),\t\t// 订阅的PubID已过期\n    AnyRTC_NO_RTC_SVR(212);\t// 没有RTC服务器\n\n    private int value;\n\n    ARUtils(int value) {\n        this.value = value;\n    }\n\n    public int getValue() {\n        return value;\n    }\n\n    /**\n     * 根据错误码获取文字描述\n     * @param value\n     * @return\n     */\n    public static String getErrString(int value) {\n        if (value == AnyRTC_OK.getValue()) {\n            return ARApplication.App().getString(R.string.str_anyrtc_ok);\n        } else if (value == AnyRTC_UNKNOW.getValue()) {\n            return ARApplication.App().getString(R.string.str_unknow_exception);\n        } else if (value == AnyRTC_EXCEPTION.getValue()) {\n            return ARApplication.App().getString(R.string.str_anyrtc_exception);\n        } else if (value == AnyRTC_NET_ERR.getValue()) {\n            return ARApplication.App().getString(R.string.str_anyrtc_net_err);\n        } else if (value == AnyRTC_LIVE_ERR.getValue()) {\n            return ARApplication.App().getString(R.string.str_anyrtc_live_err);\n        } else if (value == AnyRTC_BAD_REQ.getValue()) {\n            return ARApplication.App().getString(R.string.str_anyrtc_bad_req);\n        } else if (value == AnyRTC_AUTH_FAIL.getValue()) {\n            return ARApplication.App().getString(R.string.str_anyrtc_auth_fail);\n        } else if (value == AnyRTC_NO_USER.getValue()) {\n            return ARApplication.App().getString(R.string.str_anyrtc_no_user);\n        } else if (value == AnyRTC_SQL_ERR.getValue()) {\n            return ARApplication.App().getString(R.string.str_anyrtc_sql_err);\n        } else if (value == AnyRTC_ARREARS.getValue()) {\n            return ARApplication.App().getString(R.string.str_anyrtc_arrears);\n        } else if (value == AnyRTC_LOCKED.getValue()) {\n            return ARApplication.App().getString(R.string.str_anyrtc_locked);\n        } else if (value == AnyRTC_FORCE_EXIT.getValue()) {\n            return ARApplication.App().getString(R.string.str_anyrtc_force_exit);\n        } else {\n            return \"\";\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/utils/DisplayUtils.java",
    "content": "package org.ar.utils;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.util.DisplayMetrics;\n\npublic class DisplayUtils {\n\t/**\n\t * 将px值转换为dp值\n\t */\n\tpublic static int px2dp(Context context, float pxValue) {\n\t\tfinal float scale = context.getResources().getDisplayMetrics().density;\n\t\treturn (int) (pxValue / scale + 0.5f);\n\t}\n\n\t/**\n\t * 将dp值转换为px值\n\t */\n\tpublic static int dp2px(Context context, float dpValue) {\n\t\tfinal float scale = context.getResources().getDisplayMetrics().density;\n\t\treturn (int) (dpValue * scale + 0.5f);\n\t}\n\n\t/**\n\t * 将px值转换为sp值\n\t */\n\tpublic static int px2sp(Context context, float pxValue) {\n\t\tfinal float fontScale = context.getResources().getDisplayMetrics().scaledDensity;\n\t\treturn (int) (pxValue / fontScale + 0.5f);\n\t}\n\n\t/**\n\t * 将sp值转换为px值\n\t */\n\tpublic static int sp2px(Context context, float spValue) {\n\t\tfinal float fontScale = context.getResources().getDisplayMetrics().scaledDensity;\n\t\treturn (int) (spValue * fontScale + 0.5f);\n\t}\n\n\t/**\n\t * 获取屏幕宽度\n\t */\n\tpublic static int getScreenWidthPixels(Activity context) {\n\t\tDisplayMetrics metric = new DisplayMetrics();\n\t\tcontext.getWindowManager().getDefaultDisplay().getMetrics(metric);\n\t\treturn metric.widthPixels;\n\t}\n\n\t/**\n\t * 获取屏幕高度\n\t */\n\tpublic static int getScreenHeightPixels(Activity context) {\n\t\tDisplayMetrics metric = new DisplayMetrics();\n\t\tcontext.getWindowManager().getDefaultDisplay().getMetrics(metric);\n\t\treturn metric.heightPixels;\n\t}\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/utils/MD5.java",
    "content": "package org.ar.utils;\n\nimport java.security.MessageDigest;\nimport java.security.NoSuchAlgorithmException;\n\n/**\n * Created by liuxiaozhong on 2016/5/30.\n */\npublic class MD5 {\n\n    public static String getMD5(String password ) {\n        try {\n            MessageDigest md = MessageDigest.getInstance(\"MD5\");\n            md.update(password.getBytes());\n            byte b[] = md.digest();\n            int i;\n            StringBuffer buf = new StringBuffer(\"\");\n            for (int offset = 0; offset < b.length; offset++) {\n                i = b[offset];\n                if(i<0) i+= 256;\n                if(i<16)\n                    buf.append(\"0\");\n                buf.append(Integer.toHexString(i));\n            }\n            return buf.toString().toLowerCase();\n            //System.out.println(\"result: \" + buf.toString());//32位的加密\n           // System.out.println(\"result: \" + buf.toString().substring(8,24));//16位的加密\n        } catch (NoSuchAlgorithmException e) {\n            e.printStackTrace();\n        }\n        return \"\";\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/utils/NameUtils.java",
    "content": "package org.ar.utils;\n\nimport java.util.Random;\n\n/**\n * Created by Skyline on 2016/8/8.\n */\npublic class NameUtils {\n    public static String[] userNickname = new String[]{\"John\", \"Michelle\", \"Amy\", \"Kim\", \"Mary\", \"David\", \"Sunny\", \"James\", \"Maria\", \"Michael\", \"Sarah\", \"Robert\", \"Lily\"\n            , \"William\", \"Jessica\", \"Paul\", \"Crystal\", \"Peter\", \"Jennifer\", \"George\", \"Rachel\", \"Thomas\", \"Lisa\", \"Daniel\", \"Elizabeth\"\n            , \"Kevin\", \"Angela\", \"Richard\", \"Emily\", \"Charles\", \"Eva\", \"Jason\", \"Jenny\", \"Mark\", \"Alice\", \"Eric\", \"Candy\", \"Chris\", \"Linda\"\n            , \"Jack\", \"Tina\", \"Alex\", \"Sara\", \"Edward\", \"Emma\", \"Tony\", \"Anne\", \"Joseph\", \"Cindy\", \"Henry\", \"Grace\", \"Alan\", \"Susan\", \"Anna\"\n            , \"Maggie\", \"Christian\", \"Annie\", \"Tom\", \"Rebecca\", \"Andy\", \"Claire\", \"Carlos\", \"Vanessa\", \"Steven\", \"Judy\", \"Stephen\", \"Catherine\"\n            , \"Jean\", \"Helen\", \"Andrew\", \"Christina\", \"Jonathan\", \"Karen\", \"Frank\", \"Marco\", \"Elaine\", \"Gary\", \"Nana\", \"Antonio\", \"Nicole\"\n            , \"Alexander\", \"Margaret\", \"Matthew\", \"Julia\", \"Louis\", \"Lucy\", \"Jose\", \"Natalie\", \"Martin\", \"Kate\", \"Patrick\", \"Olivia\", \"Sam\"\n            , \"Betty\", \"Angel\", \"Laura\", \"Anthony\", \"Ellen\", \"Luis\", \"Elena\", \"Leo\", \"Samuel\", \"Vicky\", \"Brian\", \"Summer\", \"Sean\", \"Nancy\"\n            , \"Carl\", \"Zoe\", \"Diego\", \"Teresa\", \"Danny\", \"Wendy\", \"Jerry\", \"Christine\", \"Karl\", \"Princess\", \"Nick\", \"Barbara\", \"Albert\"\n            , \"Julie\", \"Ryan\", \"Amber\", \"Johnny\", \"Stephanie\", \"Mike\", \"Sharon\", \"Aaron\", \"Sophia\", \"Kelly\", \"Yvonne\", \"Tim\", \"Tiffany\"\n            , \"Roberto\", \"Marie\", \"Alfred\", \"Simon\", \"Lauren\", \"Andrea\", \"Gina\", \"Diana\", \"Mario\", \"Doris\", \"Victor\", \"Fiona\", \"Ivan\"\n            , \"Victoria\", \"Fernando\", \"Caroline\", \"Adam\", \"Ivy\", \"Miguel\", \"Alexandra\", \"Raymond\", \"Jessie\", \"Ray\", \"Lulu\", \"Arthur\"\n            , \"Janet\", \"Ricardo\", \"King\", \"Cynthia\", \"Vincent\", \"Cherry\", \"Jeremy\", \"Bonnie\", \"Andre\", \"Isabella\", \"Christopher\", \"Kitty\"\n            , \"Dennis\", \"Mia\", \"Harry\", \"Rose\", \"Leon\", \"Cecilia\", \"Jacky\", \"Louise\", \"Bob\", \"Rita\", \"Bill\", \"Katie\", \"Sebastian\", \"Erica\"\n            , \"Oscar\", \"Jacqueline\", \"Philip\", \"Ruby\", \"Benjamin\", \"Miranda\", \"Jim\", \"Iris\", \"Jeff\", \"Queen\", \"Scott\", \"Esther\", \"Kenneth\"\n            , \"Melissa\", \"Justin\", \"Nathan\"};\n\n    public static String getNickName() {\n        return userNickname[new Random().nextInt(200)];\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/utils/PermissionsCheckUtil.java",
    "content": "package org.ar.utils;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.content.DialogInterface;\nimport android.content.Intent;\nimport android.net.Uri;\nimport android.os.Build;\nimport android.provider.Settings;\n\npublic class PermissionsCheckUtil {\n\n    public static final int SETTING_APP = 0x123;\n    private static String TAG = \"PermissionsCheckUtil\";\n    private static String[] PHONE_MTYB = new String[]{\"sanxing\", \"xiaomi\"};\n\n    /**\n     * @param activity\n     * @param message  显示缺失权限提示说明\n     */\n    public static void showMissingPermissionDialog(final Activity activity, String message) {\n        boolean canSetting = false;\n        String mtyb = Build.BRAND;//手机品牌\n        for (int i = 0; i < PHONE_MTYB.length; i++) {\n            if (PHONE_MTYB[i].equalsIgnoreCase(mtyb)) {//相等可以调用到设置界面进行权限设置\n                canSetting = true;\n                break;\n            } else {\n                canSetting = false;\n            }\n        }\n        final AlertDialog.Builder builder = new AlertDialog.Builder(activity);\n        builder.setTitle(\"帮助\");\n        builder.setMessage(message);\n        if (canSetting) {\n            builder.setPositiveButton(\"设置\", new DialogInterface.OnClickListener() {\n\n                @Override\n                public void onClick(DialogInterface dialog, int which) {\n                    startAppSettings(activity);\n                    dialog.dismiss();\n                }\n            });\n        }\n        builder.setNegativeButton(\"取消\", new DialogInterface.OnClickListener() {\n\n            @Override\n            public void onClick(DialogInterface dialog, int which) {\n                dialog.dismiss();\n            }\n        });\n        builder.show();\n    }\n\n    // 启动应用的设置\n    public static void startAppSettings(Activity activity) {\n        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);\n        intent.setData(Uri.parse(\"package:\" + activity.getPackageName()));\n        activity.startActivityForResult(intent, SETTING_APP);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/utils/ScreenUtils.java",
    "content": "package org.ar.utils;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.content.res.Resources;\nimport android.graphics.Bitmap;\nimport android.graphics.Rect;\nimport android.util.DisplayMetrics;\nimport android.util.TypedValue;\nimport android.view.View;\nimport android.view.WindowManager;\n\n/**\n * Get screen associated auxiliary class\n *\n * @author Ming <br/>\n */\npublic class ScreenUtils {\n    private ScreenUtils() {\n        /* cannot be instantiated */\n        throw new UnsupportedOperationException(\"cannot be instantiated\");\n    }\n\n    /**\n     * dip to px\n     *\n     * @param dip\n     * @param context\n     * @return\n     */\n    public static float dip2Dimension(float dip, Context context) {\n        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();\n        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, displayMetrics);\n    }\n\n    public static int dpToP(Resources paramResources, int paramInt) {\n        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, paramInt,\n                paramResources.getDisplayMetrics());\n    }\n\n    /**\n     * @param context\n     * @param complexUnit {@link TypedValue#COMPLEX_UNIT_DIP}\n     *                    {@link TypedValue#COMPLEX_UNIT_SP}\n     * @return\n     */\n    public static float toDimension(float dip, Context context, int complexUnit) {\n        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();\n        return TypedValue.applyDimension(complexUnit, dip, displayMetrics);\n    }\n\n    /**\n     * Get screen width\n     *\n     * @param context\n     * @return\n     */\n    public static int getScreenWidth(Context context) {\n        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);\n        DisplayMetrics outMetrics = new DisplayMetrics();\n        wm.getDefaultDisplay().getMetrics(outMetrics);\n\n        return outMetrics.widthPixels;\n    }\n\n    /**\n     * Get screen height\n     *\n     * @param context\n     * @return\n     */\n    public static int getScreenHeight(Context context) {\n        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);\n        DisplayMetrics outMetrics = new DisplayMetrics();\n        wm.getDefaultDisplay().getMetrics(outMetrics);\n        return outMetrics.heightPixels;\n    }\n\n\n    /**\n     * 判断是否为平板\n     *\n     * @return\n     */\n    public static boolean isPad(Context context) {\n\n        DisplayMetrics dm = context.getResources().getDisplayMetrics();\n        int width = dm.widthPixels;\n        int height = dm.heightPixels;\n        double x = Math.pow(width, 2);\n        double y = Math.pow(height, 2);\n        double diagonal = Math.sqrt(x + y);\n\n        int dens = dm.densityDpi;\n        double screenInches = diagonal / (double) dens;\n        // 大于6尺寸则为Pad\n        if (screenInches >= 6.0) {\n            return true;\n        }\n        return false;\n\n    }\n\n    /**\n     * 获得状态栏的高度\n     *\n     * @param context\n     * @return\n     */\n    public static int getStatusHeight(Context context) {\n\n        int statusHeight = -1;\n        try {\n            Class<?> clazz = Class.forName(\"com.android.internal.R$dimen\");\n            Object object = clazz.newInstance();\n            int height = Integer.parseInt(clazz.getField(\"status_bar_height\").get(object).toString());\n            statusHeight = context.getResources().getDimensionPixelSize(height);\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return statusHeight;\n    }\n\n    /**\n     * 获取当前屏幕截图，包含状态栏\n     *\n     * @param activity\n     * @return\n     */\n    public static Bitmap snapShotWithStatusBar(Activity activity) {\n        View view = activity.getWindow().getDecorView();\n        view.setDrawingCacheEnabled(true);\n        view.buildDrawingCache();\n        Bitmap bmp = view.getDrawingCache();\n        int width = getScreenWidth(activity);\n        int height = getScreenHeight(activity);\n        Bitmap bp = null;\n        bp = Bitmap.createBitmap(bmp, 0, 0, width, height);\n        view.destroyDrawingCache();\n        return bp;\n\n    }\n\n    /**\n     * 获取当前屏幕截图，不包含状态栏\n     *\n     * @param activity\n     * @return\n     */\n    public static Bitmap snapShotWithoutStatusBar(Activity activity) {\n        View view = activity.getWindow().getDecorView();\n        view.setDrawingCacheEnabled(true);\n        view.buildDrawingCache();\n        Bitmap bmp = view.getDrawingCache();\n        Rect frame = new Rect();\n        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);\n        int statusBarHeight = frame.top;\n\n        int width = getScreenWidth(activity);\n        int height = getScreenHeight(activity);\n        Bitmap bp = null;\n        bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height - statusBarHeight);\n        view.destroyDrawingCache();\n        return bp;\n\n    }\n\n    public static final int getHeightInPx(Context context) {\n        final int height = context.getResources().getDisplayMetrics().heightPixels;\n        return height;\n    }\n\n    public static final int getWidthInPx(Context context) {\n        final int width = context.getResources().getDisplayMetrics().widthPixels;\n        return width;\n    }\n\n    public static final int getHeightInDp(Context context) {\n        final float height = context.getResources().getDisplayMetrics().heightPixels;\n        int heightInDp = px2dip(context, height);\n        return heightInDp;\n    }\n\n    public static final int getWidthInDp(Context context) {\n        final float height = context.getResources().getDisplayMetrics().heightPixels;\n        int widthInDp = px2dip(context, height);\n        return widthInDp;\n    }\n\n    public static int dip2px(Context context, float dpValue) {\n        final float scale = context.getResources().getDisplayMetrics().density;\n        return (int) (dpValue * scale + 0.5f);\n    }\n\n    public static int px2dip(Context context, float pxValue) {\n        final float scale = context.getResources().getDisplayMetrics().density;\n        return (int) (pxValue / scale + 0.5f);\n    }\n\n    public static int px2sp(Context context, float pxValue) {\n        final float scale = context.getResources().getDisplayMetrics().density;\n        return (int) (pxValue / scale + 0.5f);\n    }\n\n    public static int sp2px(Context context, float spValue) {\n        final float scale = context.getResources().getDisplayMetrics().density;\n        return (int) (spValue * scale + 0.5f);\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/utils/ToastUtil.java",
    "content": "package org.ar.utils;\n\n\nimport android.content.Context;\nimport android.text.TextUtils;\nimport android.view.Gravity;\nimport android.widget.Toast;\n\nimport org.ar.ARApplication;\n\n/**\n * Created by Skyline on 2016/5/24.\n */\npublic class ToastUtil {\n    private static Context context = ARApplication.App();\n    private static Toast mToast;\n\n    public static void show(int resId) {\n        show(context.getResources().getText(resId), Toast.LENGTH_SHORT);\n    }\n\n    public static void show(int resId, int duration) {\n        show(context.getResources().getText(resId), duration);\n    }\n\n    public static void show(CharSequence text) {\n        show(text, Toast.LENGTH_SHORT);\n    }\n\n    public static void show(CharSequence text, int duration) {\n        text = TextUtils.isEmpty(text == null ? \"\" : text.toString()) ? \"\"\n                : text;\n        if (mToast == null) {\n            mToast = Toast.makeText(context, text, duration);\n            mToast.setGravity(Gravity.CENTER, 0, 0);\n        } else {\n            mToast.setText(text);\n        }\n        mToast.show();\n    }\n\n    public static void show(int resId, Object... args) {\n        show(String.format(context.getResources().getString(resId), args),\n                Toast.LENGTH_SHORT);\n    }\n\n    public static void show(String format, Object... args) {\n        show(String.format(format, args), Toast.LENGTH_SHORT);\n    }\n\n    public static void show(int resId, int duration, Object... args) {\n        show(String.format(context.getResources().getString(resId), args),\n                duration);\n    }\n\n    public static void show(String format, int duration, Object... args) {\n        show(String.format(format, args), duration);\n    }\n\n    public void cancelToast() {\n        if (mToast != null) {\n            mToast.cancel();\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/widgets/ARVideoView.java",
    "content": "package org.ar.widgets;\n\nimport android.content.Context;\nimport android.content.res.Configuration;\nimport android.graphics.Bitmap;\nimport android.util.Log;\nimport android.view.Gravity;\nimport android.view.MotionEvent;\nimport android.view.View;\nimport android.widget.FrameLayout;\nimport android.widget.ImageButton;\nimport android.widget.LinearLayout;\nimport android.widget.RelativeLayout;\n\nimport org.ar.common.utils.ScreenUtils;\nimport org.ar.rtmpc.R;\nimport org.webrtc.EglBase;\nimport org.webrtc.EglRenderer;\nimport org.webrtc.PercentFrameLayout;\nimport org.webrtc.RendererCommon;\nimport org.webrtc.SurfaceViewRenderer;\nimport org.webrtc.VideoRenderer;\n\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport static android.view.View.VISIBLE;\n\n/**\n * Created by liuxiaozhong on 2019/1/11.\n */\npublic class ARVideoView implements View.OnTouchListener{\n\n    public RelativeLayout rlVideoGroup;//所有视频的容器布局\n\n    private EglBase eglBase;//底层视频渲染相关对象\n\n    private Context mContext;//上下文对象\n\n    private VideoView LocalVideoRender;//本地视频显示对象\n\n    private LinkedHashMap<String, VideoView> mRemoteRenderList;//远程视频集合\n\n    private static int mScreenWidth;//屏幕宽\n\n    private static int mScreenHeight;//屏幕高\n\n    private boolean isSameSize=false;//是否是平均大小模式\n    private boolean is169 = false;//比例是否是16：9\n    private int direction = Gravity.CENTER;//1大几小的时候  小像位置\n    private int orientation = LinearLayout.HORIZONTAL;//1大几小的时候  小像横向或纵向排列\n\n    private static int SUB_WIDTH = 0;\n    private static int SUB_HEIGHT = 0;\n\n    private boolean isHost ;//是否是主播\n\n    VideoLayoutOnclickEvent videoLayoutOnclickEvent;\n\n    public interface VideoLayoutOnclickEvent {\n        void onCloseVideoRender(View view, String strPeerId);\n\n    }\n\n    public void setVideoLayoutOnclickEvent(VideoLayoutOnclickEvent videoLayoutOnclickEvent) {\n        this.videoLayoutOnclickEvent = videoLayoutOnclickEvent;\n    }\n\n    public ARVideoView(RelativeLayout rlVideoGroup, EglBase eglBase, Context context, boolean isSameSize, boolean isHost) {\n\n        this.rlVideoGroup = rlVideoGroup;\n        this.eglBase = eglBase;\n        this.mContext = context;\n        this.isSameSize=isSameSize;\n        this.isHost=isHost;\n        mRemoteRenderList = new LinkedHashMap<>();\n        mScreenWidth = ScreenUtils.getScreenWidth(mContext);\n        mScreenHeight = ScreenUtils.getScreenHeight(mContext) - ScreenUtils.getStatusHeight(mContext);\n    }\n\n    public void setVideoSwitchEnable(boolean enable) {\n        if (!isSameSize) {\n            rlVideoGroup.setOnTouchListener(this);\n        }\n    }\n\n    @Override\n    public boolean onTouch(View v, MotionEvent event) {\n        if (event.getAction() == MotionEvent.ACTION_DOWN) {\n            int startX = (int) event.getX();\n            int startY = (int) event.getY();\n            if (LocalVideoRender.Hited(startX, startY)) {\n                return true;\n            } else {\n                Iterator<Map.Entry<String, VideoView>> iter = mRemoteRenderList.entrySet().iterator();\n                while (iter.hasNext()) {\n                    Map.Entry<String, VideoView> entry = iter.next();\n                    String peerId = entry.getKey();\n                    VideoView render = entry.getValue();\n                    if (render.Hited(startX, startY)) {\n                        return true;\n                    }\n                }\n            }\n        } else if (event.getAction() == MotionEvent.ACTION_UP) {\n            int startX = (int) event.getX();\n            int startY = (int) event.getY();\n            if (LocalVideoRender.Hited(startX, startY)) {\n                SwitchViewToFullscreen(LocalVideoRender, GetFullScreen());\n                return true;\n            } else {\n                Iterator<Map.Entry<String, VideoView>> iter = mRemoteRenderList.entrySet().iterator();\n                while (iter.hasNext()) {\n                    Map.Entry<String, VideoView> entry = iter.next();\n                    String peerId = entry.getKey();\n                    VideoView render = entry.getValue();\n                    if (render.Hited(startX, startY)) {\n                        SwitchViewToFullscreen(render, GetFullScreen());\n                        return true;\n                    }\n                }\n            }\n        }\n        return false;\n    }\n\n\n    /**\n     * 一个VideoView对象 就是一个视频渲染对象 里面的方法 UI 可以根据需求自定义\n     */\n    protected static class VideoView {\n        public String videoId; //视频ID 保持唯一\n        public int index; //视频的下标\n        public int x; //装载视频的容器的起始X轴位置  最大100 最左边为0\n        public int y; //装载视频的容器的起始Y轴位置  最大100 最上边为0\n        public int w; //装载视频的容器的宽  最大100\n        public int h; //装载视频的容器的高  最大100\n        public PercentFrameLayout mLayout = null;//自定义宽高为百分比的布局控件\n        public SurfaceViewRenderer surfaceViewRenderer = null; //显示视频的SurfaceView\n        private FrameLayout flLoading; //视频显示前的Loading\n        public VideoRenderer videoRenderer = null; //底层视频渲染对象\n        public ImageButton btnHangUp;\n\n        public VideoView(String videoId, Context ctx, EglBase eglBase, int index, int x, int y, int w, int h) {\n            this.videoId = videoId;\n            this.index = index;\n            this.x = x;\n            this.y = y;\n            this.w = w;\n            this.h = h;\n\n            mLayout = new PercentFrameLayout(ctx);\n            mLayout.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));\n            View view = View.inflate(ctx, R.layout.layout_arvideo, null);//这个View可完全自定义 需要显示名字或者其他图标可以在里面加\n            flLoading = (FrameLayout) view.findViewById(R.id.fl_video_loading);\n            btnHangUp=view.findViewById(R.id.ibtn_hang_up);\n            surfaceViewRenderer = (SurfaceViewRenderer) view.findViewById(R.id.sv_video_render);\n            surfaceViewRenderer.init(eglBase.getEglBaseContext(), null);\n            surfaceViewRenderer.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));\n            mLayout.addView(view);//将SurfaceView添加到自定义宽高为百分比的布局控件中\n        }\n\n        /**\n         * 该视频对象是否全屏显示\n         *\n         * @return true false\n         */\n        public Boolean isFullScreen() {\n            return w == 100 || h == 100;\n        }\n\n        /**\n         * 是否点击了该视频对象\n         *\n         * @param px\n         * @param py\n         * @return\n         */\n        public Boolean Hited(int px, int py) {\n            if (!isFullScreen()) {\n                int left = x * mScreenWidth / 100;\n                int top = y * mScreenHeight / 100;\n                int right = (x + w) * mScreenWidth / 100;\n                int bottom = (y + h) * mScreenHeight / 100;\n                if ((px >= left && px <= right) && (py >= top && py <= bottom)) {\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        public void close() {\n            mLayout.removeView(surfaceViewRenderer);\n            surfaceViewRenderer.release();\n            surfaceViewRenderer = null;\n            videoRenderer = null;\n        }\n\n    }\n\n\n    /**\n     * 仅用于1大几小\n     * 1个大像和几个小像的时候设置\n     * @param is169  比例是否是16：9  true 16:9  false 4:3\n     * @param direction 显示位置 左边 中间  右边\n     * @param orientation 排列方式 垂直 横向\n     */\n    public void setVideoViewLayout(boolean is169, int direction, int orientation) {\n        this.is169 = is169;\n        this.direction = direction;\n        this.orientation = orientation;\n        if (!isSameSize) {\n            changeSizeWhenRotate(false);\n        }\n    }\n\n    /**\n     * 仅用于1大几小\n     * 旋转屏幕时改变尺寸\n     * isFirst 是否是第一次  是的话 是不需要更新视频View的\n     */\n    public void changeSizeWhenRotate(boolean isFirst) {\n        if (is169) {\n            if (mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {//横屏\n                SUB_WIDTH = (int) (((mScreenWidth / 5f) * 1.777777f) / (mScreenHeight / 100f));\n                SUB_HEIGHT=(int) ((mScreenWidth / 5f) / (mScreenWidth / 100f));\n            } else {\n                SUB_HEIGHT = (int) (((mScreenWidth / 5f) * 1.777777f) / (mScreenHeight / 100f));\n                SUB_WIDTH = (int) ((mScreenWidth / 5f) / (mScreenWidth / 100f));\n            }\n        } else {\n            if (mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {//横屏\n                SUB_WIDTH = (int) (((mScreenWidth / 4f) * 1.33333f) / (mScreenHeight / 100f));\n                SUB_HEIGHT=(int) ((mScreenWidth / 4f) / (mScreenWidth / 100f));\n            } else {\n                SUB_HEIGHT = (int) (((mScreenWidth / 3f) /1.33333f) / (mScreenHeight / 100f));\n                SUB_WIDTH = (int) ((mScreenWidth / 3f) / (mScreenWidth / 100f));\n            }\n        }\n        if (!isFirst){\n            updateVideoView1Big();\n        }\n\n    }\n\n\n\n\n    /**\n     * 获取视频窗口的个数\n     *\n     * @return\n     */\n    public int getVideoRenderSize() {\n        int size = mRemoteRenderList.size();\n        if (LocalVideoRender != null) {\n            size += 1;\n        }\n        return size;\n    }\n\n\n    /**\n     * 打开本地摄像头渲染对象\n     *\n     * @return\n     */\n    public VideoRenderer openLocalVideoRender() {\n        int size = getVideoRenderSize();\n        if (size == 0) {\n            LocalVideoRender = new VideoView(\"localRender\", rlVideoGroup.getContext(), eglBase, 0, 0, 0, 100, 100);\n            LocalVideoRender.surfaceViewRenderer.setZOrderMediaOverlay(false);\n        } else {\n            LocalVideoRender = new VideoView(\"localRender\", rlVideoGroup.getContext(), eglBase, size, 0, 0, 100, 100);\n            LocalVideoRender.surfaceViewRenderer.setZOrderMediaOverlay(false);\n        }\n        rlVideoGroup.addView(LocalVideoRender.mLayout, -1);\n        LocalVideoRender.mLayout.setPosition(\n                LocalVideoRender.x, LocalVideoRender.y, LocalVideoRender.w, LocalVideoRender.h);\n        LocalVideoRender.surfaceViewRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);\n        LocalVideoRender.flLoading.setVisibility(VISIBLE);\n        LocalVideoRender.surfaceViewRenderer.addFrameListener(new EglRenderer.FrameListener() {\n            @Override\n            public void onFrame(Bitmap frame) {\n                Log.d(\"surfaceView\", frame.toString());\n                LocalVideoRender.surfaceViewRenderer.post(new Runnable() {\n                    @Override\n                    public void run() {\n                        LocalVideoRender.flLoading.setVisibility(View.GONE);\n                    }\n                });\n\n            }\n        }, 1f);\n        if (isSameSize){\n            updateVideoViewSameSize();\n        }else {\n            updateVideoView1Big();\n        }\n        LocalVideoRender.videoRenderer = new VideoRenderer(LocalVideoRender.surfaceViewRenderer);\n        return LocalVideoRender.videoRenderer;\n    }\n\n    /**\n     * 移除本地视频渲染对象\n     */\n    public void removeLocalVideoRender() {\n        if (LocalVideoRender != null) {\n            LocalVideoRender.close();\n            LocalVideoRender.videoRenderer = null;\n            rlVideoGroup.removeView(LocalVideoRender.mLayout);\n            LocalVideoRender = null;\n            if (isSameSize){\n                updateVideoViewSameSize();\n            }else {\n                updateVideoView1Big();\n            }\n        }\n    }\n\n\n    /**\n     * 打开远程视频渲染对象\n     *\n     * @param videoId 视频ID\n     * @return\n     */\n    public VideoRenderer openRemoteVideoRender(final String videoId) {\n        VideoView remoteVideoRender = mRemoteRenderList.get(videoId);\n        if (remoteVideoRender == null) {\n            int size = getVideoRenderSize();\n            if (size == 0) {\n                remoteVideoRender = new VideoView(videoId, rlVideoGroup.getContext(), eglBase, 0, 0, 0, 100, 100);\n            } else {\n                remoteVideoRender = new VideoView(videoId, rlVideoGroup.getContext(), eglBase, size, 0, 0, 0, 0);\n                remoteVideoRender.surfaceViewRenderer.setZOrderMediaOverlay(true);\n            }\n            rlVideoGroup.addView(remoteVideoRender.mLayout, -1);\n            remoteVideoRender.mLayout.setPosition(\n                    remoteVideoRender.x, remoteVideoRender.y, remoteVideoRender.w, remoteVideoRender.h);\n            remoteVideoRender.surfaceViewRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);\n            remoteVideoRender.flLoading.setVisibility(VISIBLE);\n            final VideoView finalRemoteVideoRender = remoteVideoRender;\n            remoteVideoRender.surfaceViewRenderer.addFrameListener(new EglRenderer.FrameListener() {\n                @Override\n                public void onFrame(Bitmap frame) {\n                    finalRemoteVideoRender.surfaceViewRenderer.post(new Runnable() {\n                        @Override\n                        public void run() {\n                            finalRemoteVideoRender.flLoading.setVisibility(View.GONE);\n                        }\n                    });\n                }\n            }, 1f);\n            remoteVideoRender.videoRenderer = new VideoRenderer(remoteVideoRender.surfaceViewRenderer);\n            mRemoteRenderList.put(videoId, remoteVideoRender);\n            if (isSameSize){\n                updateVideoViewSameSize();\n            }else {\n                updateVideoView1Big();\n            }\n            if (isHost || (!isHost && videoId.equals(\"LocalCameraRender\"))) {\n                remoteVideoRender.btnHangUp.setVisibility(View.VISIBLE);\n                remoteVideoRender.btnHangUp.setOnClickListener(new View.OnClickListener() {\n                    @Override\n                    public void onClick(View v) {\n                        if (null != videoLayoutOnclickEvent) {\n                            videoLayoutOnclickEvent.onCloseVideoRender(v, videoId);\n                        }\n                    }\n                });\n            }\n        }\n        return remoteVideoRender.videoRenderer;\n    }\n\n    /**\n     * 移除远程像\n     *\n     * @param videoId\n     */\n    public void removeRemoteRender(String videoId) {\n        VideoView remoteVideoRender = mRemoteRenderList.get(videoId);\n        if (remoteVideoRender != null) {\n            remoteVideoRender.close();\n            rlVideoGroup.removeView(remoteVideoRender.mLayout);\n            mRemoteRenderList.remove(videoId);\n            sortVideoRenderIndex();\n            if (isSameSize){\n                updateVideoViewSameSize();\n            }else {\n                updateVideoView1Big();\n            }\n        }\n    }\n\n    public void sortVideoRenderIndex() {\n        List<Map.Entry<String, VideoView>> list = new ArrayList<Map.Entry<String, VideoView>>(mRemoteRenderList.entrySet());\n        for (int i = 0; i < list.size(); i++) {\n            list.get(i).getValue().index = i + 1;\n        }\n    }\n\n\n    //第一种 1个大 多个小 小像从中间位置开始 最多5个\n\n    /**\n     * 1个大像 5个小像示例\n     * 小像横排/竖排排列\n     * 小像从左边 中间 右边开始排列\n     */\n    private void updateVideoView1Big() {\n        int size = mRemoteRenderList.size();\n        if (size == 0) {\n            if (LocalVideoRender != null) {\n                LocalVideoRender.x = 0;\n                LocalVideoRender.y = 0;\n                LocalVideoRender.w = 100;\n                LocalVideoRender.h = 100;\n                LocalVideoRender.mLayout.setPosition(0, 0, 100, 100);\n                LocalVideoRender.surfaceViewRenderer.requestLayout();\n            }\n        } else {\n            int startX = 0;\n            int startY = 100-SUB_HEIGHT-2;\n            if (orientation== LinearLayout.HORIZONTAL){\n                if (direction == Gravity.CENTER) {\n                    startX = (100 - (SUB_WIDTH * size)) / 2;//小像起始位置\n                } else if (direction == Gravity.LEFT) {\n                    startX = 0;\n                } else if (direction == Gravity.RIGHT) {\n                    startX = 100 - SUB_WIDTH;\n                } else {\n                    startX = (100 - (SUB_WIDTH * size)) / 2;\n                }\n            }else {\n                if (direction == Gravity.CENTER) {\n                    startX = (100 - SUB_WIDTH) / 2;//小像起始位置\n                } else if (direction == Gravity.LEFT) {\n                    startX = 0;\n                } else if (direction == Gravity.RIGHT) {\n                    startX = 100 - SUB_WIDTH-5;\n                } else {\n                    startX = (100 - SUB_WIDTH) / 2;\n                }\n            }\n\n            if (LocalVideoRender != null) {\n                LocalVideoRender.x = 0;\n                LocalVideoRender.y = 0;\n                LocalVideoRender.w = 100;\n                LocalVideoRender.h = 100;\n                LocalVideoRender.mLayout.setPosition(0, 0, 100, 100);\n                LocalVideoRender.surfaceViewRenderer.requestLayout();\n            }\n            Iterator<Map.Entry<String, VideoView>> iter = mRemoteRenderList.entrySet().iterator();\n            while (iter.hasNext()) {\n                Map.Entry<String, VideoView> entry = iter.next();\n                VideoView render = entry.getValue();\n\n                if (orientation == LinearLayout.HORIZONTAL) {\n                    if (direction == Gravity.CENTER) {\n                        render.x = startX + (render.index - 1) * SUB_WIDTH;\n                    } else if (direction == Gravity.LEFT) {\n                        render.x = startX + (render.index - 1) * SUB_WIDTH;\n                    } else if (direction == Gravity.RIGHT) {\n                        render.x = startX - (render.index - 1) * SUB_WIDTH;\n                    } else {\n                        render.x = startX + (render.index - 1) * SUB_WIDTH;\n                    }\n                    render.y = startY;\n                } else {\n                    render.x=startX;\n                    render.y = startY - (render.index - 1) * SUB_HEIGHT;\n                }\n                render.w = SUB_WIDTH;\n                render.h = SUB_HEIGHT;\n                render.mLayout.setPosition(render.x, render.y, render.w, render.h);\n                render.surfaceViewRenderer.requestLayout();\n            }\n        }\n    }\n\n    /**\n     * 适合横屏\n     * 平均大小模式示例\n     * 1个全屏 2个上下或左右个1  3个品字形状  4个田字形状 5个上2下3  6个上3下3\n     */\n    public void updateVideoViewSameSize() {\n        int HEIGHT, WIDTH;\n        //平均大小模式\n        int size = mRemoteRenderList.size();\n        if (size == 0) {\n            LocalVideoRender.mLayout.setPosition(0, 0, 100, 100);\n            LocalVideoRender.surfaceViewRenderer.requestLayout();\n        } else if (size == 1) {\n            if (!is169) {\n                HEIGHT = (int) (((mScreenWidth / 2f) / 1.33333f) / (mScreenHeight / 100));\n                WIDTH = (int) ((mScreenWidth / 2f) / (mScreenWidth / 100));\n            } else {\n                HEIGHT = (int) (((mScreenWidth / 2f) / 1.77777f) / (mScreenHeight / 100));\n                WIDTH = (int) ((mScreenWidth / 2f) / (mScreenWidth / 100));\n            }\n            int Y = (100 - HEIGHT) / 2;\n            Iterator<Map.Entry<String, VideoView>> iter = mRemoteRenderList.entrySet().iterator();\n            while (iter.hasNext()) {\n                Map.Entry<String, VideoView> entry = iter.next();\n                VideoView render = entry.getValue();\n                LocalVideoRender.mLayout.setPosition(0, Y, WIDTH, HEIGHT);\n                LocalVideoRender.surfaceViewRenderer.requestLayout();\n                if (render.index == 1) {\n                    render.mLayout.setPosition(WIDTH, Y, WIDTH, HEIGHT);\n                    render.surfaceViewRenderer.requestLayout();\n                }\n            }\n        } else if (size == 2) {\n            if (!is169) {\n                WIDTH = (int) (((mScreenHeight / 2f) * 1.33333f) / (mScreenWidth / 100));\n                HEIGHT = (int) ((mScreenHeight / 2f) / (mScreenHeight / 100));\n            } else {\n                WIDTH = (int) (((mScreenHeight / 2f) * 1.77777f) / (mScreenWidth / 100));\n                HEIGHT = (int) ((mScreenHeight / 2f) / (mScreenHeight / 100));\n            }\n            int X = 0;\n            int Y = 0;\n//            int WIDTH = 100 / 2;\n//            int HEIGHT = 50;\n\n            Iterator<Map.Entry<String, VideoView>> iter = mRemoteRenderList.entrySet().iterator();\n            while (iter.hasNext()) {\n                Map.Entry<String, VideoView> entry = iter.next();\n\n                VideoView render = entry.getValue();\n                LocalVideoRender.mLayout.setPosition((100 - WIDTH) / 2, Y, WIDTH, HEIGHT);\n                LocalVideoRender.surfaceViewRenderer.requestLayout();\n                if (render.index == 1) {\n                    render.mLayout.setPosition((100 - 2 * WIDTH) / 2, Y + HEIGHT, WIDTH, HEIGHT);\n                    render.surfaceViewRenderer.requestLayout();\n                } else if (render.index == 2) {\n                    render.mLayout.setPosition((100 - 2 * WIDTH) / 2 + WIDTH, Y + HEIGHT, WIDTH, HEIGHT);\n                    render.surfaceViewRenderer.requestLayout();\n                }\n            }\n        } else if (size == 3) {\n            if (!is169) {\n                WIDTH = (int) (((mScreenHeight / 2f) * 1.33333f) / (mScreenWidth / 100));\n                HEIGHT = (int) ((mScreenHeight / 2f) / (mScreenHeight / 100));\n            } else {\n                WIDTH = (int) (((mScreenHeight / 2f) * 1.77777f) / (mScreenWidth / 100));\n                HEIGHT = (int) ((mScreenHeight / 2f) / (mScreenHeight / 100));\n            }\n            int X = 0;\n            int Y = 0;\n//            int WIDTH = 50;\n//            int HEIGHT = 50;\n            Iterator<Map.Entry<String, VideoView>> iter = mRemoteRenderList.entrySet().iterator();\n            while (iter.hasNext()) {\n                Map.Entry<String, VideoView> entry = iter.next();\n                VideoView render = entry.getValue();\n                LocalVideoRender.mLayout.setPosition((100 - WIDTH * 2) / 2, Y, WIDTH, HEIGHT);\n                LocalVideoRender.surfaceViewRenderer.requestLayout();\n                if (render.index == 1) {\n                    render.mLayout.setPosition((100 - 2 * WIDTH) / 2 + WIDTH, Y, WIDTH, HEIGHT);\n                    render.surfaceViewRenderer.requestLayout();\n                } else if (render.index == 2) {\n                    render.mLayout.setPosition((100 - 2 * WIDTH) / 2, Y + HEIGHT, WIDTH, HEIGHT);\n                    render.surfaceViewRenderer.requestLayout();\n                } else if (render.index == 3) {\n                    render.mLayout.setPosition((100 - 2 * WIDTH) / 2 + WIDTH, Y + HEIGHT, WIDTH, HEIGHT);\n                    render.surfaceViewRenderer.requestLayout();\n                }\n            }\n        } else if (size == 4) {\n            if (!is169) {\n                WIDTH = (int) (((mScreenHeight / 2f) * 1.33333f) / (mScreenWidth / 100));\n                HEIGHT = (int) ((mScreenHeight / 2f) / (mScreenHeight / 100));\n            } else {\n                HEIGHT = (int) (((mScreenWidth / 3f) / 1.77777f) / (mScreenHeight / 100));\n                WIDTH = (int) ((mScreenWidth / 3f) / (mScreenWidth / 100));\n            }\n            int X = (100 - WIDTH * 3) / 2;\n            int Y = (100-HEIGHT*2)/2;\n            Iterator<Map.Entry<String, VideoView>> iter = mRemoteRenderList.entrySet().iterator();\n            while (iter.hasNext()) {\n                Map.Entry<String, VideoView> entry = iter.next();\n                VideoView render = entry.getValue();\n                LocalVideoRender.mLayout.setPosition((100 - WIDTH * 2) / 2, Y, WIDTH, HEIGHT);\n                LocalVideoRender.surfaceViewRenderer.requestLayout();\n                if (render.index == 1) {\n                    render.mLayout.setPosition((100 - WIDTH * 2) / 2 + WIDTH, Y, WIDTH, HEIGHT);\n                    render.surfaceViewRenderer.requestLayout();\n                } else {\n                    if (render.index % 3 == 0) {\n                        render.mLayout.setPosition(X, Y + HEIGHT, WIDTH, HEIGHT);\n                        render.surfaceViewRenderer.requestLayout();\n                    } else {\n                        render.mLayout.setPosition(X + (render.index % 3 * WIDTH), Y + HEIGHT, WIDTH, HEIGHT);\n                        render.surfaceViewRenderer.requestLayout();\n                    }\n\n                }\n\n            }\n        } else {\n            if (!is169) {\n                WIDTH = (int) (((mScreenHeight / 2f) * 1.33333f) / (mScreenWidth / 100));\n                HEIGHT = (int) ((mScreenHeight / 2f) / (mScreenHeight / 100));\n            } else {\n                HEIGHT = (int) (((mScreenWidth / 3f) / 1.77777f) / (mScreenHeight / 100));\n                WIDTH = (int) ((mScreenWidth / 3f) / (mScreenWidth / 100));\n            }\n            int X = (100 - WIDTH * 3) / 2;\n            int Y = (100-HEIGHT*2)/2;\n//            int WIDTH = 100 / 3;\n//            int HEIGHT = 30;\n            Iterator<Map.Entry<String, VideoView>> iter = mRemoteRenderList.entrySet().iterator();\n            while (iter.hasNext()) {\n                Map.Entry<String, VideoView> entry = iter.next();\n                VideoView render = entry.getValue();\n                LocalVideoRender.mLayout.setPosition(X, Y, WIDTH, HEIGHT);\n                LocalVideoRender.surfaceViewRenderer.requestLayout();\n                if (render.index == 1) {\n                    render.mLayout.setPosition(X + WIDTH, Y, WIDTH, HEIGHT);\n                    render.surfaceViewRenderer.requestLayout();\n                } else if (render.index == 2) {\n                    render.mLayout.setPosition(X + (WIDTH * 2), Y, WIDTH, HEIGHT);\n                    render.surfaceViewRenderer.requestLayout();\n                } else if (render.index == 3) {\n                    render.mLayout.setPosition(X, HEIGHT+Y, WIDTH, HEIGHT);\n                    render.surfaceViewRenderer.requestLayout();\n                } else if (render.index == 4) {\n                    render.mLayout.setPosition(X + WIDTH, HEIGHT+Y, WIDTH, HEIGHT);\n                    render.surfaceViewRenderer.requestLayout();\n                } else if (render.index == 5) {\n                    render.mLayout.setPosition(X + (WIDTH * 2), HEIGHT+Y, WIDTH, HEIGHT);\n                    render.surfaceViewRenderer.requestLayout();\n                }\n            }\n        }\n        }\n\n\n\n    private void SwitchViewToFullscreen(VideoView view1, VideoView fullscrnView) {\n        if (view1==null||fullscrnView==null){\n            return;\n        }\n        int index, x, y, w, h;\n\n        index = view1.index;\n        x = view1.x;\n        y = view1.y;\n        w = view1.w;\n        h = view1.h;\n\n        view1.index = fullscrnView.index;\n        view1.x = fullscrnView.x;\n        view1.y = fullscrnView.y;\n        view1.w = fullscrnView.w;\n        view1.h = fullscrnView.h;\n\n        fullscrnView.index = index;\n        fullscrnView.x = x;\n        fullscrnView.y = y;\n        fullscrnView.w = w;\n        fullscrnView.h = h;\n\n        fullscrnView.mLayout.setPosition(fullscrnView.x, fullscrnView.y, fullscrnView.w, fullscrnView.h);\n        view1.mLayout.setPosition(view1.x, view1.y, view1.w, view1.h);\n\n        updateVideoLayout(view1, fullscrnView);\n    }\n    /**\n     * 视频切换后更新视频的布局\n     *\n     * @param view1\n     * @param view2\n     */\n    private void updateVideoLayout(VideoView view1, VideoView view2) {\n        if (view1.isFullScreen()) {\n            view1.surfaceViewRenderer.setZOrderMediaOverlay(false);\n            view2.surfaceViewRenderer.setZOrderMediaOverlay(true);\n            view1.mLayout.requestLayout();\n            view2.mLayout.requestLayout();\n            rlVideoGroup.removeView(view1.mLayout);\n            rlVideoGroup.removeView(view2.mLayout);\n            rlVideoGroup.addView(view1.mLayout, -1);\n            rlVideoGroup.addView(view2.mLayout, 0);\n        } else if (view2.isFullScreen()) {\n            view1.surfaceViewRenderer.setZOrderMediaOverlay(true);\n            view2.surfaceViewRenderer.setZOrderMediaOverlay(false);\n            view2.mLayout.requestLayout();\n            view1.mLayout.requestLayout();\n            rlVideoGroup.removeView(view1.mLayout);\n            rlVideoGroup.removeView(view2.mLayout);\n            rlVideoGroup.addView(view1.mLayout, 0);\n            rlVideoGroup.addView(view2.mLayout, -1);\n        } else {\n            view1.mLayout.requestLayout();\n            view2.mLayout.requestLayout();\n            rlVideoGroup.removeView(view1.mLayout);\n            rlVideoGroup.removeView(view2.mLayout);\n            rlVideoGroup.addView(view1.mLayout, 0);\n            rlVideoGroup.addView(view2.mLayout, 0);\n        }\n    }\n\n    /**\n     * 获取全屏的界面\n     *\n     * @return\n     */\n    private VideoView GetFullScreen() {\n        if (LocalVideoRender.isFullScreen()) {\n            return LocalVideoRender;\n        }\n        Iterator<Map.Entry<String, VideoView>> iter = mRemoteRenderList.entrySet().iterator();\n        while (iter.hasNext()) {\n            Map.Entry<String, VideoView> entry = iter.next();\n            String peerId = entry.getKey();\n            VideoView render = entry.getValue();\n            if (render.isFullScreen())\n                return render;\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/widgets/AppBaseDialogFragment.java",
    "content": "package org.ar.widgets;\n\nimport android.os.Bundle;\nimport android.support.annotation.LayoutRes;\nimport android.support.annotation.Nullable;\nimport android.support.v4.app.DialogFragment;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\n/**\n * Created by KathLine on 2016/12/30.\n */\n\npublic abstract class AppBaseDialogFragment extends DialogFragment {\n    private View view;\n\n    public AppBaseDialogFragment() {\n        // Required empty public constructor\n    }\n\n    @Nullable\n    @Override\n    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n//        getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);//必须放在setContextView之前调用, 去掉Dialog中的蓝线\n//        view = LayoutInflater.from(getActivity()).inflate(getContentViewID(), container, false);\n        view = inflater.inflate(getContentViewID(), container);\n        setLayout();\n        initData(view);\n        return view;\n    }\n\n    protected void setLayout() {\n    }\n\n    @LayoutRes\n    protected abstract int getContentViewID();\n\n    protected abstract void initData(View view);\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/widgets/BaseDialog.java",
    "content": "package org.ar.widgets;\n\nimport android.app.Dialog;\nimport android.content.Context;\nimport android.view.MotionEvent;\nimport android.view.View;\nimport android.view.ViewConfiguration;\n\n/**\n * Created by KathLine on 2016/11/8.\n */\n\npublic abstract class BaseDialog extends Dialog {\n\n    public BaseDialog(Context context) {\n        super(context);\n    }\n\n    protected abstract void onTouchOutside();\n\n    @Override\n    public boolean onTouchEvent(MotionEvent event) {\n        /* 触摸外部弹窗 */\n        if (isOutOfBounds(getContext(), event)) {\n            onTouchOutside();\n        }\n        return super.onTouchEvent(event);\n    }\n\n    /**\n     * 判断当前用户触摸是否超出了Dialog的显示区域\n     *\n     * @param context\n     * @param event\n     * @return\n     */\n    private boolean isOutOfBounds(Context context, MotionEvent event) {\n        final int x = (int) event.getX();\n        final int y = (int) event.getY();\n        final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();\n        final View decorView = getWindow().getDecorView();\n        return (x < -slop) || (y < -slop) || (x > (decorView.getWidth() + slop))\n                || (y > (decorView.getHeight() + slop));\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/widgets/CustomDialog.java",
    "content": "package org.ar.widgets;\n\nimport android.content.Context;\nimport android.graphics.drawable.ColorDrawable;\nimport android.os.Bundle;\nimport android.support.annotation.LayoutRes;\nimport android.view.Gravity;\nimport android.view.Window;\nimport android.view.WindowManager;\n\nimport org.ar.rtmpc.R;\n\n\n/**\n * Created by KathLine on 2016/8/2.\n */\npublic class CustomDialog extends BaseDialog {\n\n    protected Builder builder;\n    protected int layoutId;\n    protected int gravity;\n    protected int animId;\n    protected boolean backgroundDrawableable;\n    protected float dimAmount;\n    protected boolean cancelable;\n    protected boolean existDialogLined;\n    public boolean isFullScreen;\n    protected int width;\n    protected int height;\n\n    protected CustomDialog(Context context, Builder builder) {\n        super(context);\n        this.builder = builder;\n        layoutId = builder.layoutId;\n        gravity = builder.gravity;\n        animId = builder.animId;\n        backgroundDrawableable = builder.backgroundDrawableable;\n        dimAmount = builder.dimAmount;\n        cancelable = builder.cancelable;\n        existDialogLined = builder.existDialogLined;\n        isFullScreen = builder.isFullScreen;\n        width = builder.width;\n        height = builder.height;\n    }\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        if (existDialogLined) {\n            requestWindowFeature(Window.FEATURE_NO_TITLE);\n        }\n        setContentView(layoutId);\n        Window window = getWindow();\n        window.setGravity(gravity);\n        window.setWindowAnimations(animId);\n        window.getDecorView().setPadding(0, 0, 0, 0);\n        WindowManager.LayoutParams lp = window.getAttributes();\n        if (width != 0 && height != 0) {\n            lp.width = width;\n            lp.height = height;\n        }\n        if (isFullScreen) {\n            window.setFlags(\n                    WindowManager.LayoutParams.FLAG_FULLSCREEN,\n                    WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏，即没有系统状态栏\n        }\n        if (backgroundDrawableable) {\n            window.setBackgroundDrawable(new ColorDrawable(0));\n        }\n        if (dimAmount < 0f || dimAmount > 1f) {\n            throw new RuntimeException(\"透明度必须在0~1之间\");\n        }else {\n            lp.dimAmount = dimAmount;\n        }\n        window.setAttributes(lp);\n        setCancelable(cancelable);\n        if (cancelable) {\n            setCanceledOnTouchOutside(true);\n        }\n    }\n\n    @Override\n    protected void onTouchOutside() {\n        if (onTouchOutsideListener != null){\n            onTouchOutsideListener.touchOutSide();\n        }\n    }\n\n    public interface onTouchOutsideListener{\n        void touchOutSide();\n    }\n\n    public onTouchOutsideListener onTouchOutsideListener;\n\n    public void setOnTouchOutsideListener(onTouchOutsideListener listener){\n        onTouchOutsideListener = listener;\n    }\n\n    public Builder getBuilder() {\n        return builder;\n    }\n\n    public CustomDialog show(Builder.onInitListener listener) {\n        this.show();\n        if (listener != null) {\n            listener.init(this);\n        }\n        return this;\n    }\n\n    public static class Builder {\n        public Context context;\n        public int layoutId;\n        public int gravity;\n        public int animId;\n        public boolean backgroundDrawableable;\n        public float dimAmount;\n        public boolean cancelable;\n        public boolean existDialogLined;\n        public boolean isFullScreen;\n        public int width;\n        public int height;\n\n        public Builder(Context context) {\n            this.context = context;\n            layoutId = R.layout.dialog_base;\n            gravity = Gravity.CENTER;\n            animId = R.style.default_dialog_style;\n            backgroundDrawableable = false;\n            dimAmount = 0.5f;\n            cancelable = true;\n            existDialogLined = true;\n            width = 0;\n            height = 0;\n        }\n\n        public Builder setContentView(@LayoutRes int layoutId) {\n            this.layoutId = layoutId;\n            return this;\n        }\n\n        /**\n         * 必须使用Gravity的静态常量，默认在中间弹出\n         *\n         * @param gravity 详见{@link Gravity}\n         * @return\n         * @see Gravity\n         */\n        public Builder setGravity(int gravity) {\n            this.gravity = gravity;\n            return this;\n        }\n\n        /**\n         * 设置Dialog弹出和Dialog退出的动画\n         *\n         * @param animId\n         * @return\n         */\n        public Builder setAnimId(int animId) {\n            this.animId = animId;\n            return this;\n        }\n\n        /**\n         * Creates a new set of layout parameters with the specified width\n         * and height.\n         *\n         * @param width  the width, either set WindowManager.LayoutParams.WRAP_CONTENT or\n         *               WindowManager.LayoutParams.FILL_PARENT (replaced by WindowManager.LayoutParams.MATCH_PARENT in\n         *               API Level 8), or a fixed size in pixels\n         * @param height the height, either set WindowManager.LayoutParams.WRAP_CONTENT or\n         *               WindowManager.LayoutParams.FILL_PARENT (replaced by WindowManager.LayoutParams.MATCH_PARENT in\n         *               API Level 8), or a fixed size in pixels\n         * @return\n         */\n        public Builder setLayoutParams(int width, int height) {\n            this.width = width;\n            this.height = height;\n            return this;\n        }\n\n        /**\n         * 是否给Dialog的背景设置透明，默认false\n         *\n         * @param backgroundDrawableable\n         * @return\n         */\n        public Builder setBackgroundDrawable(boolean backgroundDrawableable) {\n            this.backgroundDrawableable = backgroundDrawableable;\n            return this;\n        }\n\n        /**\n         * 设置Dialog之外的背景透明度，0~1之间，默认值 0.5f，半透明\n         *\n         * @param dimAmount\n         * @return\n         */\n        public Builder setDimAmount(float dimAmount) {\n            this.dimAmount = dimAmount;\n            return this;\n        }\n\n        /**\n         * 设置Dialog是否可以关闭在Dialog之外的区域，默认true\n         *\n         * @param cancelable\n         * @return\n         */\n        public Builder setCancelable(boolean cancelable) {\n            this.cancelable = cancelable;\n            return this;\n        }\n\n        /**\n         * 如果存在Holo主题下Dialog有蓝色线(含有标题栏)可以尝试调用该方法，默认不存在\n         *\n         * @param existDialogLined\n         * @return\n         */\n        public Builder setExistDialogLined(boolean existDialogLined) {\n            this.existDialogLined = existDialogLined;\n            return this;\n        }\n\n        /**\n         * 是否设置全屏模式，指的是去除系统状态栏，默认不去除\n         *\n         * @param isFullScreen\n         * @return\n         */\n        public Builder setFullScreen(boolean isFullScreen) {\n            this.isFullScreen = isFullScreen;\n            return this;\n        }\n\n        public interface onInitListener {\n            /**\n             * 绑定控件\n             *\n             * @param customDialog\n             */\n            void init(CustomDialog customDialog);\n        }\n\n        public CustomDialog build() {\n            return new CustomDialog(context, this);\n        }\n\n        /**\n         * 如果对话框仅仅起提示作用，可以传入null\n         *\n         * @param listener\n         * @return\n         */\n        public CustomDialog show(onInitListener listener) {\n            CustomDialog dialog = build();\n            dialog.show();\n            if (listener != null) {\n                listener.init(dialog);\n            }\n            return dialog;\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/org/ar/widgets/KeyboardDialogFragment.java",
    "content": "package org.ar.widgets;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.content.res.Configuration;\nimport android.graphics.drawable.ColorDrawable;\nimport android.support.v4.app.DialogFragment;\nimport android.text.TextUtils;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.view.Window;\nimport android.view.WindowManager;\nimport android.view.inputmethod.InputMethodManager;\nimport android.widget.Button;\nimport android.widget.EditText;\nimport android.widget.TextView;\n\nimport org.ar.rtmpc.R;\n\nimport java.util.Timer;\nimport java.util.TimerTask;\n\n/**\n * Created by KathLine on 2016/12/30.\n */\n\npublic class KeyboardDialogFragment extends AppBaseDialogFragment {\n\n    TextView close;\n    EditText editSendMessage;\n    Button btnSend;\n    private static InputMethodManager imm;\n    public KeyboardDialogFragment() {\n        // Required empty public constructor\n    }\n\n\n    @Override\n    public void onConfigurationChanged(Configuration newConfig) {\n        super.onConfigurationChanged(newConfig);\n    }\n\n\n\n\n    public interface EdittextListener {\n        void setTextStr(String text);\n\n        void dismiss(DialogFragment dialogFragment);\n    }\n\n    private EdittextListener edittextListener;\n\n    public void setEdittextListener(EdittextListener listener) {\n        edittextListener = listener;\n    }\n\n    @Override\n    protected void setLayout() {\n        Window window = getDialog().getWindow();\n        window.getDecorView().setPadding(0, 0, 0, 0);\n        window.setBackgroundDrawable(new ColorDrawable(0));//背景透明\n        WindowManager.LayoutParams lp = window.getAttributes();\n        lp.width = ViewGroup.LayoutParams.MATCH_PARENT;\n        lp.height =ViewGroup.LayoutParams.MATCH_PARENT;\n        lp.dimAmount = 0;\n        window.setAttributes(lp);\n    }\n\n    @Override\n    protected int getContentViewID() {\n        return R.layout.dialogfragment_keyboard;\n    }\n\n    @Override\n    protected void initData(View view) {\n        close=view.findViewById(R.id.close);\n        close.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                if (edittextListener != null) {\n                    hideKeyboard();\n                   dismiss();\n                }\n            }\n        });\n        editSendMessage=view.findViewById(R.id.edit_send_message);\n        btnSend=view.findViewById(R.id.btn_send);\n\n        btnSend.setOnClickListener(new View.OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                String text = editSendMessage.getText().toString();\n                if (!TextUtils.isEmpty(text)) {\n                    if (edittextListener != null) {\n                        edittextListener.setTextStr(text);\n                        editSendMessage.setText(\"\");\n                        hideKeyboard();\n                        dismiss();\n                    }\n                }\n            }\n        });\n        Timer timer = new Timer();\n            timer.schedule(new TimerTask() {\n                               public void run() {\n                                  showKeyboard(editSendMessage.getContext(), editSendMessage);\n                               }\n                           },\n                    150);\n\n    }\n\n\n    private void hideKeyboard() {\n        try {\n            InputMethodManager imm = (InputMethodManager) editSendMessage.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);\n            if (imm!=null&&getDialog()!=null) {\n                imm.hideSoftInputFromWindow(getDialog().getCurrentFocus().getWindowToken(),\n                        InputMethodManager.HIDE_NOT_ALWAYS);\n            }\n        }catch (Exception e){\n        }\n\n    }\n\n    @Override\n    public void onDismiss(DialogInterface dialog) {\n        super.onDismiss(dialog);\n        if (edittextListener != null) {\n            edittextListener.dismiss(this);\n        }\n    }\n\n    public  void hideKeyboard(Context context, View view) {\n        try {\n            view.requestFocus();\n            imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);\n            if (imm!=null) {\n                imm.hideSoftInputFromWindow(view.getApplicationWindowToken(),\n                        InputMethodManager.HIDE_NOT_ALWAYS);\n            }\n        }catch (Exception e){\n\n        }\n\n    }\n\n    public  void hideKeyboard(Activity activity) {\n        try {\n            imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);\n            if (imm!=null) {\n                imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(),\n                        InputMethodManager.HIDE_NOT_ALWAYS);\n            }\n        }catch (Exception e){\n\n        }\n\n    }\n\n    public  void showKeyboard(Context context, View view) {\n        try {\n            imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);\n//        imm.showSoftInput(view, 0);\n            if (imm!=null) {\n                imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);\n            }\n        }catch (Exception e){\n\n        }\n\n    }\n\n\n\n\n}\n"
  },
  {
    "path": "app/src/main/res/anim/push_bottom_in.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <translate\n        android:duration=\"200\"\n        android:fromYDelta=\"100.0%p\"\n        android:toYDelta=\"0.0\" />\n    <alpha\n        android:duration=\"700\"\n        android:fromAlpha=\"0.0\"\n        android:toAlpha=\"1.0\" />\n</set>"
  },
  {
    "path": "app/src/main/res/anim/push_bottom_out.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <translate\n        android:duration=\"200\"\n        android:fromYDelta=\"0.0\"\n        android:toYDelta=\"50.0%p\" />\n    <alpha\n        android:duration=\"200\"\n        android:fromAlpha=\"1.0\"\n        android:toAlpha=\"0.0\" />\n</set>"
  },
  {
    "path": "app/src/main/res/color/select_text_host_input.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:state_selected=\"true\" android:color=\"#ff9b00\" />\n    <item android:state_selected=\"false\" android:color=\"@color/white\" />\n</selector>\n"
  },
  {
    "path": "app/src/main/res/drawable/bg_host_head.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\" >\n    <solid\n        android:width=\"1px\"\n        android:color=\"@color/alpha_20_black\"\n        />\n    <corners\n        android:radius=\"100dp\"\n        />\n    <padding\n        android:left=\"2dp\"\n        android:top=\"2dp\"\n        android:right=\"2dp\"\n        android:bottom=\"2dp\"/>\n</shape>\n"
  },
  {
    "path": "app/src/main/res/drawable/bg_list_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item android:state_pressed=\"true\">\n        <shape>\n            <solid android:color=\"@color/layout_bg\" />\n        </shape>\n    </item>\n    <item>\n        <shape>\n            <solid android:color=\"@color/item_white\" />\n        </shape>\n    </item>\n\n</selector>"
  },
  {
    "path": "app/src/main/res/drawable/bg_white.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n    <item >\n        <shape >\n            <solid android:color=\"#D0D0CF\"/>\n            <corners android:bottomLeftRadius=\"5dp\"\n                android:bottomRightRadius=\"5dp\"/>\n        </shape>\n    </item>\n\n    <item android:top=\"1dp\">\n        <shape >\n            <solid android:color=\"#FFFFFF\"/>\n            <corners android:bottomLeftRadius=\"5dp\"\n                android:bottomRightRadius=\"5dp\"/>\n        </shape>\n    </item>\n</layer-list>"
  },
  {
    "path": "app/src/main/res/drawable/default_input_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item android:state_focused=\"true\">\n        <layer-list>\n            <item>\n                <shape>\n                    <solid android:color=\"#5990e2\" />\n                </shape>\n            </item>\n            <item android:bottom=\"1dp\">\n                <shape>\n                    <solid android:color=\"#FFFFFF\" />\n                </shape>\n            </item>\n        </layer-list>\n    </item>\n\n    <item android:state_focused=\"false\">\n        <layer-list>\n            <item>\n                <shape>\n                    <solid android:color=\"#d3d3d3\" />\n                </shape>\n            </item>\n            <item android:bottom=\"1dp\">\n                <shape>\n                    <solid android:color=\"#FFFFFF\" />\n                </shape>\n            </item>\n        </layer-list>\n    </item>\n\n\n</selector>"
  },
  {
    "path": "app/src/main/res/drawable/line_anim.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<animation-list xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:oneshot=\"true\">\n    <item android:drawable=\"@drawable/img_line_a\" android:duration=\"100\" />\n    <item android:drawable=\"@drawable/img_line_b\" android:duration=\"100\" />\n    <item android:drawable=\"@drawable/img_line_c\" android:duration=\"100\" />\n    <item android:drawable=\"@drawable/img_line_d\" android:duration=\"100\" />\n    <item android:drawable=\"@drawable/img_line_e\" android:duration=\"100\" />\n</animation-list>"
  },
  {
    "path": "app/src/main/res/drawable/list_item_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item android:state_pressed=\"true\">\n        <shape>\n            <solid android:color=\"@color/item_click_bg_color\" />\n        </shape>\n    </item>\n\n</selector>"
  },
  {
    "path": "app/src/main/res/drawable/selector_apply.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:state_selected=\"true\" android:drawable=\"@drawable/img_has_apply\"></item>\n    <item android:state_selected=\"false\" android:drawable=\"@drawable/img_line_list\"></item>\n</selector>"
  },
  {
    "path": "app/src/main/res/drawable/shape_creat_btn_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n\n    <solid android:color=\"@color/pop_blue\"></solid>\n    <corners android:radius=\"6dp\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/shape_edittext_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n\n    <solid android:color=\"#ffffff\"></solid>\n    <corners android:radius=\"6dp\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/shape_home_green_btn.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <solid android:color=\"#33B15D\" ></solid>\n    <corners android:radius=\"2dp\"></corners>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/shape_meet_id.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\" android:shape=\"rectangle\">\n    <solid android:color=\"#80000000\"></solid>\n    <corners android:radius=\"4dp\"></corners>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/shape_message.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\" android:shape=\"rectangle\">\n    <gradient android:startColor=\"@color/alpha_05_black\" android:endColor=\"@color/alpha_20_black\"\n        android:angle=\"270\"\n        ></gradient>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/shape_popuwindow.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n\n<solid android:color=\"@color/item_white\"></solid>\n    <corners android:radius=\"10dp\"></corners>\n\n\n\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/shape_room_apply_audio_line.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n        <solid android:color=\"#155DEF\"></solid>\n    <corners android:radius=\"100dp\"></corners>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/shape_room_apply_line.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n        <solid android:color=\"#33B15D\"></solid>\n    <corners android:radius=\"8dp\"></corners>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/shape_room_hang_up_line.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n        <solid android:color=\"#FF6264\"></solid>\n    <corners android:radius=\"8dp\"></corners>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/shape_room_member.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n        <solid android:color=\"@color/alpha_30_black\"></solid>\n    <corners android:radius=\"100dp\"></corners>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/shape_room_message.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n        <solid android:color=\"@color/alpha_30_black\"></solid>\n    <corners android:radius=\"10dp\"></corners>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/shape_room_name.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n        <solid android:color=\"@color/alpha_40_black\"></solid>\n    <corners android:radius=\"100dp\"></corners>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable-xxhdpi/selector_video_manager.xml",
    "content": "<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:state_selected=\"false\" android:drawable=\"@drawable/img_video_open\">\n\n    </item>\n    <item android:state_selected=\"true\" android:drawable=\"@drawable/img_video_close\">\n    </item>\n</selector>"
  },
  {
    "path": "app/src/main/res/drawable-xxhdpi/shape_back_btn.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n    <stroke android:color=\"@color/huise\" android:width=\"1dp\"></stroke>\n    <corners android:radius=\"6dp\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable-xxhdpi/shape_index_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n  -->\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n\n    <stroke\n        android:width=\"1dp\"\n        android:color=\"@color/pop_blue\"></stroke>\n    <corners android:radius=\"20dp\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable-xxhdpi/shape_index_solid_button.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n  -->\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n\n    <solid\n        android:width=\"1dp\"\n        android:color=\"@color/pop_blue\"></solid>\n    <corners android:radius=\"20dp\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/layout/activity_audio_guest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@drawable/img_bg\"\n   >\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\"\n        android:padding=\"12dp\">\n\n        <View\n            android:id=\"@+id/view_space\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"></View>\n\n        <RelativeLayout\n\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\">\n\n            <RelativeLayout\n                android:id=\"@+id/rl_room\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:background=\"@drawable/shape_meet_id\"\n                android:padding=\"8dp\">\n\n                <TextView\n                    android:id=\"@+id/tv_title\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"20dp\"\n                    android:gravity=\"center\"\n                    android:text=\"直播名称：999999\"\n                    android:textColor=\"@color/white\"\n                    android:textSize=\"12sp\" />\n\n\n                <TextView\n                    android:id=\"@+id/tv_member_num\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"20dp\"\n                    android:layout_below=\"@+id/tv_title\"\n                    android:gravity=\"center\"\n                    android:text=\"在线人数：0\"\n                    android:textColor=\"@color/white\"\n                    android:textSize=\"12sp\" />\n\n            </RelativeLayout>\n\n            <LinearLayout\n                android:id=\"@+id/ll_status\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_below=\"@+id/rl_room\"\n                android:orientation=\"vertical\"\n                android:paddingLeft=\"5dp\">\n\n                <TextView\n                    android:id=\"@+id/tv_rtmp_ok\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@android:color/transparent\"\n                    android:textColor=\"@color/dialog_blue\" />\n\n\n                <TextView\n                    android:id=\"@+id/tv_rtmp_status\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@android:color/transparent\"\n                    android:textColor=\"@color/dialog_blue\" />\n\n                <TextView\n                    android:id=\"@+id/tv_rtc_ok\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@android:color/transparent\"\n                    android:textColor=\"@color/dialog_blue\" />\n\n            </LinearLayout>\n\n            <LinearLayout\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentRight=\"true\"\n                android:orientation=\"vertical\">\n\n                <ImageButton\n                    android:id=\"@+id/btn_close\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@null\"\n                    android:onClick=\"onClick\"\n                    android:src=\"@drawable/img_close\" />\n\n\n                <ImageButton\n                    android:id=\"@+id/btn_log\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginTop=\"12dp\"\n                    android:background=\"@null\"\n                    android:onClick=\"onClick\"\n                    android:src=\"@drawable/img_log\" />\n\n            </LinearLayout>\n\n\n            <LinearLayout\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_below=\"@+id/ll_status\"\n                android:layout_centerHorizontal=\"true\"\n                android:orientation=\"vertical\">\n\n                <FrameLayout\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n\n                    >\n\n                    <ImageView\n                        android:layout_width=\"wrap_content\"\n                        android:layout_height=\"wrap_content\"\n                        android:layout_gravity=\"center\"\n                        android:src=\"@drawable/img_touxiang\" />\n\n                    <ImageView\n                        android:id=\"@+id/iv_line_anim\"\n                        android:layout_width=\"wrap_content\"\n                        android:layout_height=\"wrap_content\"\n                        android:layout_gravity=\"center\"\n                        android:visibility=\"gone\"\n                        android:background=\"@drawable/line_anim\" />\n                </FrameLayout>\n\n                <TextView\n                    android:id=\"@+id/tv_host_name\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_gravity=\"center\"\n                    android:text=\"host\"\n                    android:textColor=\"#666666\" />\n\n            </LinearLayout>\n\n\n        </RelativeLayout>\n\n\n    </LinearLayout>\n\n    <android.support.v7.widget.RecyclerView\n        android:id=\"@+id/rv_line_list\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\"></android.support.v7.widget.RecyclerView>\n\n\n    <RelativeLayout\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\">\n\n\n        <android.support.v7.widget.RecyclerView\n            android:id=\"@+id/rv_msg_list\"\n            android:layout_width=\"210dp\"\n            android:background=\"@drawable/shape_message\"\n            android:layout_height=\"200dp\"\n            android:layout_marginBottom=\"8dp\"\n            android:layout_above=\"@+id/ll_apply\">\n\n        </android.support.v7.widget.RecyclerView>\n\n        <LinearLayout\n            android:id=\"@+id/ll_apply\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"50dp\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_marginLeft=\"12dp\"\n            android:orientation=\"horizontal\">\n\n            <TextView\n                android:id=\"@+id/tv_apply_line\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_centerVertical=\"true\"\n                android:background=\"@drawable/shape_room_apply_line\"\n                android:paddingBottom=\"6dp\"\n                android:paddingLeft=\"12dp\"\n                android:paddingRight=\"12dp\"\n                android:paddingTop=\"6dp\"\n                android:text=\"连麦\"\n                android:onClick=\"onClick\"\n                android:textColor=\"@color/white\" />\n\n\n            <ImageView\n                android:id=\"@+id/iv_message\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginLeft=\"12dp\"\n                android:onClick=\"onClick\"\n                android:src=\"@drawable/img_message\" />\n\n\n        </LinearLayout>\n    </RelativeLayout>\n    </LinearLayout>\n\n    <RelativeLayout\n        android:id=\"@+id/rl_log_layout\"\n        android:layout_width=\"match_parent\"\n        android:background=\"@color/alpha_90_white\"\n        android:paddingTop=\"25dp\"\n        android:visibility=\"gone\"\n        android:layout_height=\"match_parent\">\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:textColor=\"#333333\"\n            android:textStyle=\"bold\"\n            android:layout_marginLeft=\"12dp\"\n            android:textSize=\"26sp\"\n            android:text=\"日志\"/>\n\n        <ImageButton\n            android:id=\"@+id/ibtn_close_log\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:src=\"@drawable/img_guanbi\"\n            android:background=\"@null\"\n            android:padding=\"12dp\"\n            android:onClick=\"onClick\"\n            android:layout_alignParentRight=\"true\"/>\n\n        <android.support.v7.widget.RecyclerView\n            android:id=\"@+id/rv_log\"\n            android:layout_width=\"match_parent\"\n            android:layout_marginLeft=\"12dp\"\n            android:layout_marginRight=\"12dp\"\n            android:layout_height=\"match_parent\"\n            android:layout_below=\"@+id/ibtn_close_log\"\n            android:layout_marginTop=\"12dp\"></android.support.v7.widget.RecyclerView>\n\n    </RelativeLayout>\n\n</FrameLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_audio_hoster.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:background=\"@drawable/img_bg\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:orientation=\"vertical\"\n        android:layout_height=\"match_parent\">\n\n\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\"\n        android:padding=\"12dp\">\n\n        <View\n            android:id=\"@+id/view_space\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"></View>\n\n        <RelativeLayout\n\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\">\n\n            <RelativeLayout\n                android:id=\"@+id/rl_room\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:background=\"@drawable/shape_meet_id\"\n                android:padding=\"8dp\">\n\n                <TextView\n                    android:id=\"@+id/tv_title\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"20dp\"\n                    android:gravity=\"center\"\n                    android:text=\"直播名称：999999\"\n                    android:textColor=\"@color/white\"\n                    android:textSize=\"12sp\" />\n\n\n                <TextView\n                    android:id=\"@+id/tv_member_num\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"20dp\"\n                    android:layout_below=\"@+id/tv_title\"\n                    android:gravity=\"center\"\n                    android:text=\"在线人数：0\"\n                    android:textColor=\"@color/white\"\n                    android:textSize=\"12sp\" />\n\n            </RelativeLayout>\n\n            <LinearLayout\n                android:id=\"@+id/ll_status\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_below=\"@+id/rl_room\"\n                android:orientation=\"vertical\"\n                android:paddingLeft=\"5dp\">\n\n                <TextView\n                    android:id=\"@+id/tv_rtmp_ok\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@android:color/transparent\"\n                    android:textColor=\"@color/dialog_blue\" />\n\n\n                <TextView\n                    android:id=\"@+id/tv_rtmp_status\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@android:color/transparent\"\n                    android:textColor=\"@color/dialog_blue\" />\n\n                <TextView\n                    android:id=\"@+id/tv_rtc_ok\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@android:color/transparent\"\n                    android:textColor=\"@color/dialog_blue\" />\n\n            </LinearLayout>\n\n            <LinearLayout\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentRight=\"true\"\n                android:orientation=\"vertical\">\n\n                <ImageButton\n                    android:id=\"@+id/btn_close\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@null\"\n                    android:onClick=\"onClick\"\n                    android:src=\"@drawable/img_close\" />\n\n\n                <ImageButton\n                    android:id=\"@+id/btn_log\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@null\"\n                    android:onClick=\"onClick\"\n                    android:layout_marginTop=\"12dp\"\n                    android:src=\"@drawable/img_log\" />\n\n            </LinearLayout>\n\n            <LinearLayout\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_centerHorizontal=\"true\"\n                android:orientation=\"vertical\"\n                android:layout_below=\"@+id/ll_status\">\n\n            <FrameLayout\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n              >\n\n                <ImageView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:src=\"@drawable/img_touxiang\"/>\n\n            </FrameLayout>\n\n                <TextView\n                    android:id=\"@+id/tv_host_name\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_gravity=\"center\"\n                    android:text=\"host\"\n                    android:textColor=\"#666666\" />\n            </LinearLayout>\n        </RelativeLayout>\n\n\n    </LinearLayout>\n    <android.support.v7.widget.RecyclerView\n        android:id=\"@+id/rv_line_list\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\">\n    </android.support.v7.widget.RecyclerView>\n    <RelativeLayout\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\"\n        >\n\n\n        <android.support.v7.widget.RecyclerView\n            android:id=\"@+id/rv_msg_list\"\n            android:layout_width=\"230dp\"\n            android:layout_height=\"200dp\"\n            android:layout_marginBottom=\"8dp\"\n          android:layout_above=\"@+id/ll_apply\">\n\n        </android.support.v7.widget.RecyclerView>\n\n        <LinearLayout\n            android:id=\"@+id/ll_apply\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"50dp\"\n            android:layout_marginLeft=\"12dp\"\n            android:layout_alignParentBottom=\"true\"\n            android:orientation=\"horizontal\">\n\n\n\n            <ImageView\n                android:id=\"@+id/iv_message\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:onClick=\"onClick\"\n                android:src=\"@drawable/img_message\" />\n\n            <ImageButton\n                android:id=\"@+id/tv_line_list\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:background=\"@null\"\n                android:layout_marginLeft=\"12dp\"\n                android:onClick=\"onClick\"\n                android:src=\"@drawable/selector_apply\" />\n\n        </LinearLayout>\n    </RelativeLayout>\n\n    </LinearLayout>\n\n    <RelativeLayout\n        android:id=\"@+id/rl_log_layout\"\n        android:layout_width=\"match_parent\"\n        android:background=\"@color/alpha_90_white\"\n        android:paddingTop=\"25dp\"\n        android:visibility=\"gone\"\n        android:layout_height=\"match_parent\">\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:textColor=\"#333333\"\n            android:textStyle=\"bold\"\n            android:layout_marginLeft=\"12dp\"\n            android:textSize=\"26sp\"\n            android:text=\"日志\"/>\n\n        <ImageButton\n            android:id=\"@+id/ibtn_close_log\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:src=\"@drawable/img_guanbi\"\n            android:background=\"@null\"\n            android:padding=\"12dp\"\n            android:onClick=\"onClick\"\n            android:layout_alignParentRight=\"true\"/>\n\n        <android.support.v7.widget.RecyclerView\n            android:id=\"@+id/rv_log\"\n            android:layout_width=\"match_parent\"\n            android:layout_marginLeft=\"12dp\"\n            android:layout_marginRight=\"12dp\"\n            android:layout_height=\"match_parent\"\n            android:layout_below=\"@+id/ibtn_close_log\"\n            android:layout_marginTop=\"12dp\"></android.support.v7.widget.RecyclerView>\n\n    </RelativeLayout>\n\n</FrameLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_guest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n\n    android:layout_height=\"match_parent\">\n\n    <RelativeLayout\n        android:id=\"@+id/rl_rtmpc_videos\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"></RelativeLayout>\n\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\"\n        android:padding=\"12dp\">\n\n        <View\n            android:id=\"@+id/view_space\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"></View>\n\n        <RelativeLayout\n\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\">\n\n            <RelativeLayout\n                android:id=\"@+id/rl_room\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:background=\"@drawable/shape_meet_id\"\n                android:padding=\"8dp\">\n\n                <TextView\n                    android:id=\"@+id/tv_title\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"20dp\"\n                    android:gravity=\"center\"\n                    android:text=\"直播名称：999999\"\n                    android:textColor=\"@color/white\"\n                    android:textSize=\"12sp\" />\n\n\n                <TextView\n                    android:id=\"@+id/tv_member_num\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"20dp\"\n                    android:layout_below=\"@+id/tv_title\"\n                    android:gravity=\"center\"\n                    android:text=\"在线人数：0\"\n                    android:textColor=\"@color/white\"\n                    android:textSize=\"12sp\" />\n\n            </RelativeLayout>\n\n            <LinearLayout\n                android:id=\"@+id/ll_status\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_below=\"@+id/rl_room\"\n                android:orientation=\"vertical\"\n                android:paddingLeft=\"5dp\">\n\n                <TextView\n                    android:id=\"@+id/tv_rtmp_ok\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@android:color/transparent\"\n                    android:textColor=\"@color/dialog_blue\" />\n\n\n                <TextView\n                    android:id=\"@+id/tv_rtmp_status\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@android:color/transparent\"\n                    android:textColor=\"@color/dialog_blue\" />\n\n                <TextView\n                    android:id=\"@+id/tv_rtc_ok\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@android:color/transparent\"\n                    android:textColor=\"@color/dialog_blue\" />\n\n            </LinearLayout>\n\n            <LinearLayout\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentRight=\"true\"\n                android:orientation=\"vertical\">\n\n                <ImageButton\n                    android:id=\"@+id/btn_close\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@null\"\n                    android:onClick=\"onClick\"\n                    android:src=\"@drawable/img_close\" />\n\n                <ImageButton\n                    android:id=\"@+id/btn_camare\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@null\"\n                    android:onClick=\"onClick\"\n                    android:visibility=\"gone\"\n                    android:layout_marginTop=\"12dp\"\n                    android:src=\"@drawable/img_camera\" />\n\n                <ImageButton\n                    android:id=\"@+id/btn_log\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@null\"\n                    android:onClick=\"onClick\"\n                    android:layout_marginTop=\"12dp\"\n                    android:src=\"@drawable/img_log\" />\n\n            </LinearLayout>\n\n        </RelativeLayout>\n\n\n\n\n    </LinearLayout>\n\n\n    <RelativeLayout\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        >\n\n\n        <android.support.v7.widget.RecyclerView\n            android:id=\"@+id/rv_msg_list\"\n            android:layout_width=\"210dp\"\n            android:background=\"@drawable/shape_message\"\n            android:layout_height=\"200dp\"\n            android:layout_marginBottom=\"8dp\"\n            android:layout_above=\"@+id/ll_apply\">\n\n        </android.support.v7.widget.RecyclerView>\n\n        <LinearLayout\n            android:id=\"@+id/ll_apply\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"50dp\"\n            android:layout_marginLeft=\"12dp\"\n            android:layout_alignParentBottom=\"true\"\n            android:orientation=\"horizontal\">\n\n            <TextView\n                android:id=\"@+id/tv_apply_line\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:paddingLeft=\"12dp\"\n                android:paddingRight=\"12dp\"\n                android:paddingTop=\"6dp\"\n                android:onClick=\"onClick\"\n                android:paddingBottom=\"6dp\"\n                android:textColor=\"@color/white\"\n                android:layout_centerVertical=\"true\"\n                android:background=\"@drawable/shape_room_apply_line\"\n                android:text=\"连麦\"/>\n\n            <ImageView\n                android:id=\"@+id/iv_message\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:onClick=\"onClick\"\n                android:layout_marginLeft=\"12dp\"\n                android:src=\"@drawable/img_message\" />\n\n\n\n        </LinearLayout>\n    </RelativeLayout>\n\n\n    <RelativeLayout\n        android:id=\"@+id/rl_log_layout\"\n        android:layout_width=\"match_parent\"\n        android:background=\"@color/alpha_90_white\"\n        android:paddingTop=\"25dp\"\n        android:visibility=\"gone\"\n        android:layout_height=\"match_parent\">\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:textColor=\"#333333\"\n            android:textStyle=\"bold\"\n            android:layout_marginLeft=\"12dp\"\n            android:textSize=\"26sp\"\n            android:text=\"日志\"/>\n\n        <ImageButton\n            android:id=\"@+id/ibtn_close_log\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:src=\"@drawable/img_guanbi\"\n            android:background=\"@null\"\n            android:padding=\"12dp\"\n            android:onClick=\"onClick\"\n            android:layout_alignParentRight=\"true\"/>\n\n        <android.support.v7.widget.RecyclerView\n            android:id=\"@+id/rv_log\"\n            android:layout_width=\"match_parent\"\n            android:layout_marginLeft=\"12dp\"\n            android:layout_marginRight=\"12dp\"\n            android:layout_height=\"match_parent\"\n            android:layout_below=\"@+id/ibtn_close_log\"\n            android:layout_marginTop=\"12dp\"></android.support.v7.widget.RecyclerView>\n\n    </RelativeLayout>\n\n</RelativeLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_hoster.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n\n    android:layout_height=\"match_parent\">\n\n    <RelativeLayout\n        android:id=\"@+id/rl_rtmpc_videos\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"></RelativeLayout>\n\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\"\n        android:padding=\"12dp\">\n\n        <View\n            android:id=\"@+id/view_space\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"></View>\n\n        <RelativeLayout\n\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\">\n\n            <RelativeLayout\n                android:id=\"@+id/rl_room\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:background=\"@drawable/shape_meet_id\"\n                android:padding=\"8dp\">\n\n                <TextView\n                    android:id=\"@+id/tv_title\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"20dp\"\n                    android:gravity=\"center\"\n                    android:text=\"直播名称：999999\"\n                    android:textColor=\"@color/white\"\n                    android:textSize=\"12sp\" />\n\n\n                <TextView\n                    android:id=\"@+id/tv_member_num\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"20dp\"\n                    android:layout_below=\"@+id/tv_title\"\n                    android:gravity=\"center\"\n                    android:text=\"在线人数：0\"\n                    android:textColor=\"@color/white\"\n                    android:textSize=\"12sp\" />\n\n            </RelativeLayout>\n\n            <LinearLayout\n                android:id=\"@+id/ll_status\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_below=\"@+id/rl_room\"\n                android:orientation=\"vertical\"\n                android:paddingLeft=\"5dp\">\n\n                <TextView\n                    android:id=\"@+id/tv_rtmp_ok\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@android:color/transparent\"\n                    android:textColor=\"@color/dialog_blue\" />\n\n\n                <TextView\n                    android:id=\"@+id/tv_rtmp_status\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@android:color/transparent\"\n                    android:textColor=\"@color/dialog_blue\" />\n\n                <TextView\n                    android:id=\"@+id/tv_rtc_ok\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@android:color/transparent\"\n                    android:textColor=\"@color/dialog_blue\" />\n\n            </LinearLayout>\n\n            <LinearLayout\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentRight=\"true\"\n                android:orientation=\"vertical\">\n\n                <ImageButton\n                    android:id=\"@+id/btn_close\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@null\"\n                    android:onClick=\"onClick\"\n                    android:src=\"@drawable/img_close\" />\n\n                <ImageButton\n                    android:id=\"@+id/btn_camare\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@null\"\n                    android:layout_marginTop=\"12dp\"\n                    android:onClick=\"onClick\"\n                    android:src=\"@drawable/img_camera\" />\n\n                <ImageButton\n                    android:id=\"@+id/btn_log\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@null\"\n                    android:layout_marginTop=\"12dp\"\n                    android:onClick=\"onClick\"\n                    android:src=\"@drawable/img_log\" />\n\n            </LinearLayout>\n\n        </RelativeLayout>\n\n\n\n\n    </LinearLayout>\n\n\n    <RelativeLayout\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        >\n\n\n        <android.support.v7.widget.RecyclerView\n            android:id=\"@+id/rv_msg_list\"\n            android:layout_width=\"210dp\"\n            android:background=\"@drawable/shape_message\"\n            android:layout_height=\"200dp\"\n            android:layout_marginBottom=\"8dp\"\n            android:layout_above=\"@+id/ll_apply\">\n\n        </android.support.v7.widget.RecyclerView>\n\n        <LinearLayout\n            android:id=\"@+id/ll_apply\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"50dp\"\n            android:layout_marginLeft=\"12dp\"\n            android:layout_alignParentBottom=\"true\"\n            android:orientation=\"horizontal\">\n\n\n\n        <ImageView\n            android:id=\"@+id/iv_message\"\n            android:layout_width=\"wrap_content\"\n            android:onClick=\"onClick\"\n            android:layout_height=\"wrap_content\"\n            android:src=\"@drawable/img_message\" />\n\n        <ImageButton\n            android:id=\"@+id/tv_line_list\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:background=\"@null\"\n            android:onClick=\"onClick\"\n            android:layout_marginLeft=\"12dp\"\n            android:src=\"@drawable/selector_apply\" />\n\n        </LinearLayout>\n    </RelativeLayout>\n    <RelativeLayout\n        android:id=\"@+id/rl_log_layout\"\n        android:layout_width=\"match_parent\"\n        android:background=\"@color/alpha_90_white\"\n        android:paddingTop=\"25dp\"\n        android:visibility=\"gone\"\n        android:layout_height=\"match_parent\">\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:textColor=\"#333333\"\n            android:textStyle=\"bold\"\n            android:layout_marginLeft=\"12dp\"\n            android:textSize=\"26sp\"\n            android:text=\"日志\"/>\n\n        <ImageButton\n            android:id=\"@+id/ibtn_close_log\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:src=\"@drawable/img_guanbi\"\n            android:background=\"@null\"\n            android:padding=\"12dp\"\n            android:onClick=\"onClick\"\n            android:layout_alignParentRight=\"true\"/>\n\n        <android.support.v7.widget.RecyclerView\n            android:id=\"@+id/rv_log\"\n            android:layout_width=\"match_parent\"\n            android:layout_marginLeft=\"12dp\"\n            android:layout_marginRight=\"12dp\"\n            android:layout_height=\"match_parent\"\n            android:layout_below=\"@+id/ibtn_close_log\"\n            android:layout_marginTop=\"12dp\"></android.support.v7.widget.RecyclerView>\n\n    </RelativeLayout>\n\n\n</RelativeLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_live_list.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@drawable/img_bg\"\n    android:orientation=\"vertical\"\n    tools:context=\"org.ar.guest.LiveListActivity\">\n\n    <FrameLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\">\n\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:textColor=\"#333333\"\n            android:layout_gravity=\"center\"\n            android:drawableTop=\"@drawable/img_logo\"\n            android:text=\"AR直播连麦DEMO\"/>\n\n\n    </FrameLayout>\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:orientation=\"vertical\"\n        android:layout_marginLeft=\"12dp\"\n        android:layout_marginRight=\"12dp\"\n        android:layout_weight=\"1\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\">\n            <Button\n                android:id=\"@+id/btn_video\"\n                android:layout_width=\"0dp\"\n                android:layout_weight=\"1\"\n                android:layout_height=\"wrap_content\"\n                android:background=\"@drawable/shape_home_green_btn\"\n                android:textColor=\"#ffffff\"\n                android:text=\"视频直播\"/>\n            <android.support.v4.widget.Space\n                android:layout_width=\"10dp\"\n                android:layout_height=\"match_parent\" />\n            <Button\n                android:id=\"@+id/btn_audio\"\n                android:layout_width=\"0dp\"\n                android:layout_weight=\"1\"\n                android:layout_height=\"wrap_content\"\n                android:background=\"@drawable/shape_home_green_btn\"\n                android:textColor=\"#ffffff\"\n                android:text=\"音频直播\"/>\n        </LinearLayout>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"直播房间列表\"\n            android:layout_marginTop=\"40dp\"\n            android:textSize=\"12sp\"/>\n\n\n    <android.support.v4.widget.SwipeRefreshLayout\n        android:id=\"@+id/swipe_refresh\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_marginTop=\"10dp\"\n        android:layout_marginBottom=\"10dp\"\n        android:layout_weight=\"1\">\n\n        <android.support.v7.widget.RecyclerView\n            android:id=\"@+id/rv_list\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"></android.support.v7.widget.RecyclerView>\n    </android.support.v4.widget.SwipeRefreshLayout>\n    </LinearLayout>\n\n    <TextView\n        android:id=\"@+id/tv_version\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:layout_marginBottom=\"6dp\"\n        android:textSize=\"12sp\"\n        android:textColor=\"#999999\"\n        android:text=\"\"/>\n    <TextView\n        android:id=\"@+id/tv_support\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:textSize=\"12sp\"\n        android:textColor=\"#999999\"\n        android:layout_marginBottom=\"12dp\"\n        android:text=\"技术支持 hi@dync.cc\"/>\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/dialog_base.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"260dp\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_vertical|center_horizontal\"\n    android:orientation=\"vertical\">\n\n    <TextView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"10dp\"\n        android:gravity=\"center\"\n        android:textSize=\"18sp\"/>\n\n\n    <TextView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:padding=\"5dp\"\n        android:layout_margin=\"10dp\"\n        android:layout_gravity=\"center_horizontal\"\n        android:textSize=\"@dimen/text_normal_size\"\n        android:textColor=\"#000000\"\n        />\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"1dp\"\n        />\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\">\n\n        <Button\n            android:layout_height=\"50dp\"\n            android:layout_width=\"match_parent\"\n            android:text=\"确定\"\n            android:textColor=\"#000000\"\n            />\n\n    </LinearLayout>\n\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/dialogfragment_keyboard.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <TextView\n        android:id=\"@+id/close\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\" />\n\n    <!--输入模块一-->\n    <LinearLayout\n        android:id=\"@+id/ll_input_h\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"50dp\"\n        android:layout_alignParentBottom=\"true\"\n        android:background=\"@color/alpha_60_black\"\n        android:orientation=\"horizontal\"\n        android:padding=\"8dp\"\n      >\n\n\n            <EditText\n                android:id=\"@+id/edit_send_message\"\n                android:layout_width=\"0dp\"\n                android:layout_height=\"match_parent\"\n                android:layout_weight=\"1\"\n                android:background=\"@null\"\n                android:hint=\"说两句\"\n                android:imeOptions=\"flagNoExtractUi\"\n                android:paddingLeft=\"12dp\"\n                android:singleLine=\"true\"\n                android:maxLength=\"256\"\n                android:textColor=\"@color/white\"\n                android:textColorHint=\"@color/alpha_30_white\"\n                android:textSize=\"@dimen/text_small_size\" />\n\n            <View\n                android:layout_width=\"0.7dp\"\n                android:layout_height=\"25dp\"\n                android:layout_gravity=\"center_vertical\"\n                android:background=\"#20ffffff\"></View>\n\n            <Button\n                android:id=\"@+id/btn_send\"\n                android:layout_width=\"60dp\"\n                android:layout_height=\"match_parent\"\n                android:background=\"@null\"\n                android:text=\"发送\"\n                android:textColor=\"@color/select_text_host_input\"\n                android:textSize=\"@dimen/text_default_size\" />\n    </LinearLayout>\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/empty_act_data.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"vertical\" android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n    <TextView\n        android:id=\"@+id/tv_tip\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:drawablePadding=\"24dp\"\n        android:gravity=\"center\"\n        android:textSize=\"14sp\"\n        android:textColor=\"#333333\"\n        android:text=\"暂无直播\"/>\n    <TextView\n        android:id=\"@+id/tv_reget\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_below=\"@+id/tv_tip\"\n        android:layout_centerHorizontal=\"true\"\n        android:layout_marginTop=\"12dp\"\n        android:textSize=\"12sp\"\n        android:text=\"点击刷新\"\n        android:textColor=\"#248DE6\"/>\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/empty_no_line_data.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"vertical\" android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n    <TextView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:drawableTop=\"@drawable/img_no_line\"\n        android:drawablePadding=\"24dp\"\n        android:gravity=\"center\"\n        android:textColor=\"@color/edittext_hint\"\n        android:text=\"还没有人申请连麦哦~\"/>\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_line.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\"\n  >\n\n    <TextView\n        android:id=\"@+id/tv_title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:gravity=\"center_vertical\"\n        android:padding=\"12dp\"\n        android:textColor=\"#333333\"\n        android:background=\"#FFFFFF\"\n        android:text=\"连麦列表\"\n        />\n\n    <View\n        android:background=\"@color/line\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0.5dp\"></View>\n    <android.support.v4.widget.SwipeRefreshLayout\n        android:id=\"@+id/swipe_refresh\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n\n\n    <android.support.v7.widget.RecyclerView\n        android:id=\"@+id/rv_list\"\n        android:background=\"#F6F8F9\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n       ></android.support.v7.widget.RecyclerView>\n    </android.support.v4.widget.SwipeRefreshLayout>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_audio_line.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginRight=\"12dp\"\n    android:orientation=\"vertical\">\n\n    <FrameLayout\n        android:layout_width=\"90dp\"\n        android:layout_height=\"90dp\"\n        android:layout_gravity=\"center\">\n\n\n        <ImageView\n            android:id=\"@+id/tv_icon\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:src=\"@drawable/img_touxiang\"\n          />\n    </FrameLayout>\n\n    <TextView\n        android:id=\"@+id/tv_name\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:layout_marginTop=\"6dp\"\n        android:textColor=\"#666666\" />\n\n    <TextView\n        android:id=\"@+id/tv_hangup\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"12dp\"\n        android:layout_gravity=\"center\"\n      android:background=\"@drawable/img_hangup\" />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_line.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:gravity=\"center_vertical\"\n    android:layout_height=\"70dp\">\n\n    <TextView\n        android:id=\"@+id/tv_name\"\n        android:layout_width=\"wrap_content\"\n        android:paddingTop=\"6dp\"\n        android:paddingBottom=\"6dp\"\n        android:text=\"11111111\"\n        android:layout_marginLeft=\"12dp\"\n        android:textColor=\"#666666\"\n        android:layout_height=\"wrap_content\"\n        />\n    <TextView\n        android:id=\"@+id/tv_agree\"\n        android:layout_width=\"70dp\"\n        android:layout_height=\"wrap_content\"\n        android:gravity=\"center\"\n        android:paddingTop=\"6dp\"\n        android:paddingBottom=\"6dp\"\n        android:textColor=\"@color/white\"\n        android:text=\"同意\"\n        android:layout_marginRight=\"12dp\"\n        android:layout_toLeftOf=\"@+id/tv_refuse\"\n        android:background=\"@drawable/shape_creat_btn_bg\"/>\n\n    <TextView\n        android:id=\"@+id/tv_refuse\"\n        android:layout_width=\"70dp\"\n        android:layout_height=\"wrap_content\"\n        android:gravity=\"center\"\n        android:paddingTop=\"6dp\"\n        android:paddingBottom=\"6dp\"\n        android:textColor=\"@color/huise\"\n        android:text=\"拒绝\"\n        android:layout_marginRight=\"12dp\"\n        android:layout_alignParentRight=\"true\"\n        android:background=\"@drawable/shape_back_btn\"/>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_line_list.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"vertical\" android:layout_width=\"match_parent\"\n    android:background=\"@color/white\"\n    android:layout_height=\"match_parent\"\n   >\n    <fragment\n        android:id=\"@+id/fragment_line\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:name=\"org.ar.hoster.LineFragment\"></fragment>\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_live.xml",
    "content": "<android.support.v7.widget.CardView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"70dp\"\n    android:layout_marginTop=\"12dp\"\n    android:layout_marginRight=\"8dp\"\n    android:translationZ=\"3dp\"\n    app:cardElevation=\"1dp\">\n\n    <LinearLayout\n        android:layout_width=\"wrap_content\"\n        android:orientation=\"vertical\"\n        android:paddingLeft=\"12dp\"\n        android:paddingRight=\"12dp\"\n        android:layout_height=\"match_parent\">\n\n        <TextView\n            android:id=\"@+id/tv_name\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:textSize=\"14sp\"\n            android:gravity=\"center_vertical\"\n            android:text=\"NAME\"\n            android:textColor=\"#333333\" />\n\n        <LinearLayout\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:gravity=\"center_vertical\"\n            android:orientation=\"horizontal\">\n\n        <TextView\n            android:id=\"@+id/tv_live_type\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:textColor=\"#33B15D\"\n            android:textSize=\"12sp\"\n            android:text=\"视频直播\"\n            android:drawablePadding=\"4dp\"\n            android:layout_marginRight=\"12dp\"\n            android:drawableLeft=\"@drawable/img_video\" />\n        <TextView\n            android:id=\"@+id/tv_num\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:drawableLeft=\"@drawable/img_people_num\"\n            android:gravity=\"center_vertical\"\n            android:drawablePadding=\"4dp\"\n            android:textSize=\"12sp\"\n            android:text=\"1\"\n            android:textColor=\"#999999\" />\n        </LinearLayout>\n\n    </LinearLayout>\n\n\n\n\n</android.support.v7.widget.CardView>"
  },
  {
    "path": "app/src/main/res/layout/item_live_chat.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/ll_itemt\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:gravity=\"center_vertical\"\n    android:layout_marginTop=\"6dp\"\n    android:orientation=\"horizontal\"\n    >\n\n\n    <TextView\n        android:id=\"@+id/txt_chat_name\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:padding=\"12dp\"\n         />\n\n    <TextView\n        android:id=\"@+id/txt_chat_message\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:textColor=\"@android:color/white\"\n        android:layout_marginRight=\"4dp\"/>\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_member.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:padding=\"12dp\"\n    android:orientation=\"horizontal\">\n\n   <ImageView\n       android:id=\"@+id/iv_icon\"\n       android:layout_width=\"40dp\"\n       android:layout_height=\"40dp\"\n       android:background=\"@drawable/icon\"/>\n    <TextView\n        android:id=\"@+id/tv_name\"\n        android:layout_marginLeft=\"12dp\"\n        android:layout_toRightOf=\"@+id/iv_icon\"\n        android:layout_width=\"wrap_content\"\n        android:gravity=\"center_vertical\"\n        android:layout_height=\"40dp\"\n        />\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_more_futures.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n     android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n\n    android:background=\"@color/white\">\n<fragment\n    android:id=\"@+id/fragment_futures\"\n    android:name=\"org.anyrtc.hoster.MoreFuturesFragment\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    ></fragment>\n\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/layout_arvideo.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"vertical\" android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n    <org.webrtc.SurfaceViewRenderer\n        android:id=\"@+id/sv_video_render\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n\n    <FrameLayout\n        android:id=\"@+id/fl_video_loading\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:background=\"#292E35\"\n        android:visibility=\"gone\"\n        >\n        <ProgressBar\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"/>\n    </FrameLayout>\n\n    <ImageButton\n        android:id=\"@+id/ibtn_hang_up\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:background=\"@null\"\n        android:layout_centerHorizontal=\"true\"\n      android:layout_above=\"@+id/space\"\n        android:visibility=\"gone\"\n        android:src=\"@drawable/img_hangup\"/>\n\n    <android.support.v4.widget.Space\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"10dp\"\n        android:id=\"@+id/space\"\n        android:layout_alignParentBottom=\"true\"/>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/values/attrs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <!-- 圆形头像 -->\n    <declare-styleable name=\"CustomRoundView\">\n        <attr name=\"border_width\" format=\"dimension\"/>\n        <attr name=\"border_color\" format=\"color\"/>\n    </declare-styleable>\n\n\n    <declare-styleable name=\"CircleImageView\">\n        <attr name=\"civ_border_width\" format=\"dimension\" />\n        <attr name=\"civ_border_color\" format=\"color\" />\n        <attr name=\"civ_border_overlay\" format=\"boolean\" />\n        <attr name=\"civ_fill_color\" format=\"color\" />\n    </declare-styleable>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">@color/main_red</color>\n    <color name=\"colorPrimaryDark\">@color/main_red</color>\n    <color name=\"colorAccent\">@color/main_red</color>\n\n\n\n    <color name=\"alpha_05_white\">#0DFFFFFF</color>\n    <color name=\"alpha_10_white\">#1AFFFFFF</color>\n    <color name=\"alpha_15_white\">#26FFFFFF</color>\n    <color name=\"alpha_20_white\">#33FFFFFF</color>\n    <color name=\"alpha_25_white\">#40FFFFFF</color>\n    <color name=\"alpha_30_white\">#4DFFFFFF</color>\n    <color name=\"alpha_35_white\">#59FFFFFF</color>\n    <color name=\"alpha_40_white\">#66FFFFFF</color>\n    <color name=\"alpha_45_white\">#73FFFFFF</color>\n    <color name=\"alpha_50_white\">#80FFFFFF</color>\n    <color name=\"alpha_55_white\">#8CFFFFFF</color>\n    <color name=\"alpha_60_white\">#99FFFFFF</color>\n    <color name=\"alpha_65_white\">#A6FFFFFF</color>\n    <color name=\"alpha_70_white\">#B3FFFFFF</color>\n    <color name=\"alpha_75_white\">#BFFFFFFF</color>\n    <color name=\"alpha_80_white\">#CCFFFFFF</color>\n    <color name=\"alpha_85_white\">#D9FFFFFF</color>\n    <color name=\"alpha_90_white\">#E6FFFFFF</color>\n    <color name=\"alpha_95_white\">#F2FFFFFF</color>\n\n\n    <color name=\"alpha_05_black\">#0D000000</color>\n    <color name=\"alpha_10_black\">#1A000000</color>\n    <color name=\"alpha_15_black\">#26000000</color>\n    <color name=\"alpha_20_black\">#33000000</color>\n    <color name=\"alpha_25_black\">#40000000</color>\n    <color name=\"alpha_30_black\">#4D000000</color>\n    <color name=\"alpha_35_black\">#59000000</color>\n    <color name=\"alpha_40_black\">#66000000</color>\n    <color name=\"alpha_45_black\">#73000000</color>\n    <color name=\"alpha_50_black\">#80000000</color>\n    <color name=\"alpha_55_black\">#8C000000</color>\n    <color name=\"alpha_60_black\">#99000000</color>\n    <color name=\"alpha_65_black\">#A6000000</color>\n    <color name=\"alpha_70_black\">#B3000000</color>\n    <color name=\"alpha_75_black\">#BF000000</color>\n    <color name=\"alpha_80_black\">#CC000000</color>\n    <color name=\"alpha_85_black\">#D9000000</color>\n    <color name=\"alpha_90_black\">#E6000000</color>\n    <color name=\"alpha_95_black\">#F2000000</color>\n\n\n    <color name=\"alphayiban\">#50FFFFFF</color>\n    <color name=\"huise\">#999999</color>\n    <color name=\"hint\">#dddddd</color>\n\n    <color name=\"center\">#EBEBEB</color>\n    <color name=\"yellow_normol\">#FFAC00</color>\n    <color name=\"yellow_press\">#ffbc00</color>\n    <color name=\"yellow_edit\">#ffae00</color>\n    <color name=\"login_un_select\">#f5c490</color>\n    <color name=\"login_select\">#ffac00</color>\n\n    <color name=\"unwatch\">#ffac00</color>\n    <color name=\"watch\">#ff9b00</color>\n\n\n    <color name=\"scan_bg\">#7f000000</color>\n\n    <color name=\"bottom_text_select\">#333333</color>\n    <color name=\"bottom_text_normol\">#999999</color>\n\n    <color name=\"select_txt\">#1F91EF</color>\n\n    <color name=\"success\">#999999</color>\n    <color name=\"fail\">#fb4d3d</color>\n    <color name=\"hintcolor\">#cccccc</color>\n\n    <color name=\"gift_v_bar\">#ffffff</color>\n    <color name=\"gift_h_bar\">#88000000</color>\n    <color name=\"gift_chongzhi\">#576b93</color>\n    <color name=\"yue\">#333333</color>\n    <color name=\"dialog_blue\">#0986ed</color>\n\n    <color name=\"search_status\">#f3f4f5</color>\n\n    <color name=\"main_red\">#D4333C</color>\n    <color name=\"message_list_v_text\">#555555</color>\n    <color name=\"message_list_v_name\">#b38989</color>\n    <color name=\"message_list_v_name_hor\">#ff9696</color>\n    <color name=\"message_list_v_job\">#b5b9bf</color>\n    <color name=\"down_dialog_text\">#3C3C3C</color>\n    <color name=\"down_progress_default\">#DBDBDB</color>\n    <color name=\"down_progress_ing\">#A67838</color>\n    <color name=\"host_name_color_message\">#FF4A54</color>\n    <color name=\"edittext_hint\">#CFCFCF</color>\n    <color name=\"layout_bg\">#EDEDED</color>\n    <color name=\"font_color\">#333333</color>\n    <color name=\"pop_blue\">#007aff</color>\n    <color name=\"login_line_color\">#E8E8E8</color>\n    <color name=\"line\">#dddddd</color>\n    <color name=\"text_hui\">#8C8C8C</color>\n    <color name=\"layout_bg_fc\">#FCFCFC</color>\n\n    <color name=\"black_overlay\">#66000000</color>\n    <color name=\"item_white\">#ffffff</color>\n    <color name=\"yellow\">#FFFF00</color>\n\n    <color name=\"white\">#FFFFFF</color>\n    <color name=\"black\">#000000</color><!--黑色 -->\n    <color name=\"item_selector\">#808080</color>\n\n    <color name=\"red\">#FF0000</color>\n    <color name=\"item_click_bg_color\">#dddddd</color>\n    <color name=\"aliceblue\">#F0F8FF</color>\n    <color name=\"default_cursor_color\">#8db4eb</color>\n    <color name=\"antiquewhite\">#FAEBD7</color>\n\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/dimens.xml",
    "content": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n\n    <!-- 文字的大小 -->\n    <dimen name=\"text_minimum_size\">10sp</dimen>\n    <dimen name=\"text_default_size\">12sp</dimen>\n    <dimen name=\"text_small_size\">14sp</dimen>\n    <dimen name=\"text_normal_size\">16sp</dimen>\n    <dimen name=\"text_medium_size\">18sp</dimen>\n    <dimen name=\"text_large_size\">22sp</dimen>\n    <dimen name=\"default_padding_top\">5dp</dimen>\n    <dimen name=\"default_padding_bottom\">5dp</dimen>\n    <dimen name=\"default_padding_right\">15dp</dimen>\n    <dimen name=\"default_padding_left\">15dp</dimen>\n    <dimen name=\"contact_item_padding_left\">5dp</dimen>\n    <dimen name=\"item_head_icon_size\">50dp</dimen>\n    <dimen name=\"chat_head_icon_size\">40dp</dimen>\n    <dimen name=\"save_btn_height\">30dp</dimen>en>\n    <dimen name=\"me_head_icon_size\">75dp</dimen>\n    <dimen name=\"drop_down_list_header_padding_top\">12dp</dimen>\n    <dimen name=\"drop_down_list_header_padding_bottom\">5dp</dimen>\n    <dimen name=\"drop_down_list_header_release_min_distance\">0dp</dimen>\n    <dimen name=\"drop_down_list_header_progress_bar_height\">36dp</dimen>\n\n\n    <dimen name=\"action_button_height\">32dp</dimen>\n    <dimen name=\"action_button_text_size\">14sp</dimen>\n    <dimen name=\"action_button_min_width\">56dp</dimen>\n    <dimen name=\"action_button_padding_horizontal\">4dp</dimen>\n    <dimen name=\"fab_margin\">0dp</dimen>\n    <dimen name=\"margin_left\">12dp</dimen>\n    <dimen name=\"item_height\">48dp</dimen>\n    <dimen name=\"item_margin\">12dp</dimen>\n    <dimen name=\"bottom_item_height\">250dp</dimen>\n    <dimen name=\"audience_controls_margin\">8dp</dimen>\n\n    <dimen name=\"room_share_icon_width\">25.0dip</dimen>\n    <dimen name=\"room_share_dialog_height\">250.0dip</dimen>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/ids.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <item name=\"wave_view\" type=\"id\"/>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">AR直播连麦</string>\n    <string name=\"str_title\">AR Live Hybird</string>\n    <string name=\"main_title\">多人连麦直播</string>\n    <string name=\"str_version\">www.anyrtc.io Version: ${VERSION}</string>\n\n    <!-- Strings related to start live -->\n    <string name=\"prompt_live_topic\">直播主题</string>\n    <string name=\"str_start_live\">发起直播</string>\n    <string name=\"str_start_video_live\">发起视频直播</string>\n    <string name=\"str_start_video_live_audio_line\">发起视频直播音频连麦</string>\n    <string name=\"str_start_audio_live\">发起音频直播</string>\n    <string name=\"str_audio_living\">音频直播</string>\n    <string name=\"str_live_info\">请创建一个直播主题</string>\n    <string name=\"title_activity_pre_start_live\">开始直播</string>\n    <string name=\"str_rtmp_connect_success\">RTMP 连接成功</string>\n    <string name=\"str_rtmp_connect_failed\">RTMP 连接失败</string>\n    <string name=\"str_rtc_connect_success\">RTC 连接成功</string>\n    <string name=\"str_rtc_connect_failed\">RTC 连接失败</string>\n    <string name=\"str_reconnect_times\">重连服务器：%1$d 次</string>\n    <string name=\"str_rtmp_status\">RTMP 延迟：%1$s 网络：%2$s</string>\n    <string name=\"str_live_watcher_number\">在线观看人数：%1$d</string>\n    <string name=\"str_hoster_leave\">主播已离开，2秒后关闭页面</string>\n    <string name=\"str_hoster_not_live\">主播还未开启直播, 2秒后关闭页面</string>\n\n    <string name=\"str_setting\">设置</string>\n    <string name=\"str_connect_hoster\">连麦</string>\n    <string name=\"str_connect_audio_hoster\">音频连麦</string>\n    <string name=\"str_hangup_connect\">挂断</string>\n    <string name=\"str_apply_connect_line\">%1$s 请求连线</string>\n    <string name=\"str_agree\">同意</string>\n    <string name=\"str_refused\">拒绝</string>\n    <string name=\"str_line_disconnect\">连线已断开</string>\n    <string name=\"str_hoster_refused\">主播拒绝连线</string>\n    <string name=\"str_connect_full\">连线已达最大人数</string>\n    <string name=\"str_apply_anyrtc_account\">请去AnyRTC官网申请账号,如有疑问请联系客服!</string>\n    <string name=\"str_exit\">退出</string>\n    <string name=\"str_ok\">确定</string>\n    <string name=\"str_cancel\">取消</string>\n    <string name=\"str_live_stop\">您正在进行直播，确定要退出吗？</string>\n    <string name=\"str_line_hangup\">您正在与主播进行连麦互动，确定要退出吗？</string>\n    <string name=\"str_no_audio_record_permission\">缺少录音权限</string>\n    <string name=\"str_no_camera_permission\">缺少摄像头权限</string>\n\n    <string name=\"str_anyrtc_ok\">正常</string>\n    <string name=\"str_unknow_exception\">未知错误</string>\n    <string name=\"str_anyrtc_exception\">SDK调用异常</string>\n    <string name=\"str_anyrtc_net_err\">网络错误</string>\n    <string name=\"str_anyrtc_live_err\">直播出错</string>\n    <string name=\"str_anyrtc_bad_req\">服务不支持的错误请求</string>\n    <string name=\"str_anyrtc_auth_fail\">认证失败</string>\n    <string name=\"str_anyrtc_no_user\">此开发者信息不存在</string>\n    <string name=\"str_anyrtc_sql_err\">服务器内部数据库错误</string>\n    <string name=\"str_anyrtc_arrears\">账号欠费</string>\n    <string name=\"str_anyrtc_locked\">账号被锁定</string>\n    <string name=\"str_anyrtc_force_exit\">强制离开</string>\n\n    <string name=\"share_str_weixin_title\">&#160;连麦互动视频直播正在进行，快来围观...</string>\n    <string name=\"str_barrage\">弹幕</string>\n    <string name=\"str_send\">发送</string>\n    <string name=\"str_online\">&#160;来了，欢迎~</string>\n\n    <string name=\"str_live_close\">关闭</string>\n    <string name=\"str_switch_camera\">切换</string>\n    <string name=\"str_live_share\">分享至微信</string>\n\n    <string name=\"str_copy_success\">复制hls成功</string>\n\n    <string name=\"str_video_hd\">超高清</string>\n    <string name=\"str_video_qhd\">高清</string>\n    <string name=\"str_video_sd\">标清</string>\n    <string name=\"str_video_low\">流畅</string>\n\n    <string name=\"str_live_landscape\">橫屏直播</string>\n    <string name=\"str_live_portrait\">竖屏直播</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n    <style name=\"default_dialog_style\">\n        <item name=\"android:windowIsFloating\">true</item>\n        <item name=\"android:windowIsTranslucent\">true</item>\n        <item name=\"android:windowFrame\">@null</item>\n        <item name=\"android:windowNoTitle\">true</item>\n        <item name=\"android:colorBackgroundCacheHint\">@null</item>\n        <item name=\"android:windowBackground\">@android:color/transparent</item>\n        <item name=\"android:windowContentOverlay\">@null</item>\n        <item name=\"android:radius\">5dp</item>\n    </style>\n\n    <style name=\"AnimBottom\" parent=\"@android:style/Animation\">\n        <item name=\"android:windowEnterAnimation\">@anim/push_bottom_in</item>\n        <item name=\"android:windowExitAnimation\">@anim/push_bottom_out</item>\n    </style>\n    <style name=\"SplashTheme\" parent=\"AppTheme\">\n        <item name=\"android:windowBackground\">@drawable/splash</item>\n        <item name=\"android:windowFullscreen\">true</item>\n    </style>\n    <!--自定义Dialog样式-->\n    <style name=\"MyDialog\" parent=\"AlertDialog.AppCompat\">\n        <item name=\"android:background\">@android:color/transparent</item>\n        <item name=\"android:backgroundDimEnabled\">true</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-w820dp/dimens.xml",
    "content": "<resources>\n    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n         (such as screen margins) for screens with more than 820dp of available width. This\n         would include 7\" and 10\" devices in landscape (~960dp and ~1280dp respectively). -->\n    <dimen name=\"activity_horizontal_margin\">64dp</dimen>\n</resources>\n"
  },
  {
    "path": "app/src/test/java/org/ar/rtmpc/ExampleUnitTest.java",
    "content": "package org.ar.rtmpc;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * To work on unit tests, switch the Test Artifact in the Build Variants view.\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() throws Exception {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:2.3.3'\n    }\n}\n\nallprojects {\n    repositories {\n        jcenter()\n        maven { url \"https://jitpack.io\" }\n//        maven{\n//            url 'file://D:\\\\liuxiaozhong\\\\LocalMaven'\n//        }\n        google()\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Wed Sep 13 13:52:57 CST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.4-all.zip\n"
  },
  {
    "path": "gradle.properties",
    "content": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\n# Default value: -Xmx10248m -XX:MaxPermSize=256m\n# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\n\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\nandroid.injected.testOnly=false"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windowz variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\ngoto execute\n\n:4NT_args\n@rem Get arguments from the 4NT Shell from JP Software\nset CMD_LINE_ARGS=%$\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "settings.gradle",
    "content": "include ':app'\n"
  }
]