diff --git a/3rdpart/ZLToolKit b/3rdpart/ZLToolKit
index beb3be99..da51d596 160000
--- a/3rdpart/ZLToolKit
+++ b/3rdpart/ZLToolKit
@@ -1 +1 @@
-Subproject commit beb3be990a26b395359c9e1965a1f645267133fa
+Subproject commit da51d5969a11e573e2dc4c9846e92cb6521fc726
diff --git a/Android/.gitignore b/Android/.gitignore
new file mode 100644
index 00000000..5edb4eeb
--- /dev/null
+++ b/Android/.gitignore
@@ -0,0 +1,10 @@
+*.iml
+.gradle
+/local.properties
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/Android/app/.gitignore b/Android/app/.gitignore
new file mode 100644
index 00000000..796b96d1
--- /dev/null
+++ b/Android/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/Android/app/build.gradle b/Android/app/build.gradle
new file mode 100644
index 00000000..da3ae89b
--- /dev/null
+++ b/Android/app/build.gradle
@@ -0,0 +1,43 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 28
+ defaultConfig {
+ applicationId "com.zlmediakit.demo"
+ minSdkVersion 19
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ externalNativeBuild {
+ externalNativeBuild {
+ cmake {
+ cppFlags "-std=c++11 -frtti -fexceptions"
+ }
+ }
+ ndk {
+ abiFilters "armeabi-v7a"//, "arm64-v8a"
+ }
+ }
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ externalNativeBuild {
+ cmake {
+ path "src/main/cpp/CMakeLists.txt"
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'com.android.support:appcompat-v7:28.0.0'
+ implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+}
diff --git a/Android/app/proguard-rules.pro b/Android/app/proguard-rules.pro
new file mode 100644
index 00000000..f1b42451
--- /dev/null
+++ b/Android/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/Android/app/src/androidTest/java/com/zlmediakit/demo/ExampleInstrumentedTest.java b/Android/app/src/androidTest/java/com/zlmediakit/demo/ExampleInstrumentedTest.java
new file mode 100644
index 00000000..8900124a
--- /dev/null
+++ b/Android/app/src/androidTest/java/com/zlmediakit/demo/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.zlmediakit.demo;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.zlmediakit.demo", appContext.getPackageName());
+ }
+}
diff --git a/Android/app/src/main/AndroidManifest.xml b/Android/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..1da6cc39
--- /dev/null
+++ b/Android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Android/app/src/main/cpp/CMakeLists.txt b/Android/app/src/main/cpp/CMakeLists.txt
new file mode 100644
index 00000000..c4ba78b7
--- /dev/null
+++ b/Android/app/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,110 @@
+# For more information about using CMake with Android Studio, read the
+# documentation: https://d.android.com/studio/projects/add-native-code.html
+
+# Sets the minimum version of CMake required to build the native library.
+
+cmake_minimum_required(VERSION 3.4.1)
+
+#设置生成的so动态库最后输出的路径
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/libs_export/${ANDROID_ABI})
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/libs_export/${ANDROID_ABI})
+
+#设置工程源码根目录
+set(ZLMediaKit_Root ${CMAKE_SOURCE_DIR}/../../../../../)
+set(JNI_Root ${CMAKE_SOURCE_DIR})
+set(ToolKit_Root ${ZLMediaKit_Root}/3rdpart/ZLToolKit/src)
+set(MediaKit_Root ${ZLMediaKit_Root}/src)
+
+#设置头文件目录
+INCLUDE_DIRECTORIES(${ToolKit_Root})
+INCLUDE_DIRECTORIES(${MediaKit_Root})
+INCLUDE_DIRECTORIES(${JNI_Root})
+
+#收集源代码
+file(GLOB ToolKit_src_list ${ToolKit_Root}/*/*.cpp ${ToolKit_Root}/*/*.h ${ToolKit_Root}/*/*.c)
+file(GLOB MediaKit_src_list ${MediaKit_Root}/*/*.cpp ${MediaKit_Root}/*/*.h ${MediaKit_Root}/*/*.c)
+file(GLOB JNI_src_list ${JNI_Root}/*.cpp ${JNI_Root}/*.h)
+
+#去除win32的适配代码
+list(REMOVE_ITEM ToolKit_src_list ${ToolKit_Root}/win32/getopt.c)
+
+set(ENABLE_HLS true)
+#默认禁用的库,如果要开启,请指定其路径
+set(ENABLE_OPENSSL false)
+set(ENABLE_MYSQL false)
+set(ENABLE_MP4V2 false)
+set(ENABLE_FAAC false)
+set(ENABLE_X264 false)
+
+#添加两个静态库
+if(ENABLE_HLS)
+ message(STATUS "ENABLE_HLS defined")
+ add_definitions(-DENABLE_HLS)
+ set(MediaServer_Root ${ZLMediaKit_Root}/3rdpart/media-server)
+ set(LINK_LIB_LIST zlmediakit zltoolkit mpeg)
+else()
+ set(LINK_LIB_LIST zlmediakit zltoolkit)
+endif()
+
+#查找openssl是否安装
+find_package(OpenSSL QUIET)
+if (OPENSSL_FOUND AND ENABLE_OPENSSL)
+ message(STATUS "found library:${OPENSSL_LIBRARIES},ENABLE_OPENSSL defined")
+ include_directories(${OPENSSL_INCLUDE_DIR})
+ add_definitions(-DENABLE_OPENSSL)
+ list(APPEND LINK_LIB_LIST ${OPENSSL_LIBRARIES})
+endif ()
+
+#查找mysql是否安装
+find_package(MYSQL QUIET)
+if (MYSQL_FOUND AND ENABLE_MYSQL)
+ message(STATUS "found library:${MYSQL_LIBRARIES},ENABLE_MYSQL defined")
+ include_directories(${MYSQL_INCLUDE_DIR})
+ add_definitions(-DENABLE_MYSQL)
+ list(APPEND LINK_LIB_LIST ${MYSQL_LIBRARIES})
+endif ()
+
+#查找MP4V2是否安装
+find_package(MP4V2 QUIET)
+if (MP4V2_FOUND AND ENABLE_MP4V2)
+ include_directories(${MP4V2_INCLUDE_DIR})
+ list(APPEND LINK_LIB_LIST ${MP4V2_LIBRARY})
+ add_definitions(-DENABLE_MP4V2)
+ message(STATUS "found library:${MP4V2_LIBRARY},ENABLE_MP4V2 defined")
+endif ()
+
+#查找x264是否安装
+find_package(X264 QUIET)
+if (X264_FOUND AND ENABLE_X264)
+ message(STATUS "found library:${X264_LIBRARIES},ENABLE_X264 defined")
+ include_directories(${X264_INCLUDE_DIRS})
+ add_definitions(-DENABLE_X264)
+ list(APPEND LINK_LIB_LIST ${X264_LIBRARIES})
+endif ()
+
+#查找faac是否安装
+find_package(FAAC QUIET)
+if (FAAC_FOUND AND ENABLE_FAAC)
+ message(STATUS "found library:${FAAC_LIBRARIES},ENABLE_FAAC defined")
+ include_directories(${FAAC_INCLUDE_DIR})
+ add_definitions(-DENABLE_FAAC)
+ list(APPEND LINK_LIB_LIST ${FAAC_LIBRARIES})
+endif ()
+
+
+#libmpeg
+if(ENABLE_HLS)
+ aux_source_directory(${MediaServer_Root}/libmpeg/include src_mpeg)
+ aux_source_directory(${MediaServer_Root}/libmpeg/source src_mpeg)
+ include_directories(${MediaServer_Root}/libmpeg/include)
+ add_library(mpeg STATIC ${src_mpeg})
+endif()
+
+
+#添加库
+add_library(zltoolkit STATIC ${ToolKit_src_list})
+add_library(zlmediakit STATIC ${MediaKit_src_list})
+add_library(zlmediakit_jni SHARED ${JNI_src_list})
+
+#链接
+target_link_libraries(zlmediakit_jni ${LINK_LIB_LIST} log z)
\ No newline at end of file
diff --git a/Android/app/src/main/cpp/native-lib.cpp b/Android/app/src/main/cpp/native-lib.cpp
new file mode 100644
index 00000000..ec89d2fe
--- /dev/null
+++ b/Android/app/src/main/cpp/native-lib.cpp
@@ -0,0 +1,102 @@
+#include
+#include
+#include "test_server.cpp"
+
+#define JNI_API(retType,funName,...) extern "C" JNIEXPORT retType Java_com_zlmediakit_jni_ZLMediaKit_##funName(JNIEnv* env, jclass cls,##__VA_ARGS__)
+
+
+string stringFromJstring(JNIEnv *env,jstring jstr){
+ if(!env || !jstr){
+ WarnL << "invalid args";
+ return "";
+ }
+ const char *field_char = env->GetStringUTFChars(jstr, 0);
+ string ret(field_char,env->GetStringUTFLength(jstr));
+ env->ReleaseStringUTFChars(jstr, field_char);
+ return ret;
+}
+string stringFromJbytes(JNIEnv *env,jbyteArray jbytes){
+ if(!env || !jbytes){
+ WarnL << "invalid args";
+ return "";
+ }
+ jbyte *bytes = env->GetByteArrayElements(jbytes, 0);
+ string ret((char *)bytes,env->GetArrayLength(jbytes));
+ env->ReleaseByteArrayElements(jbytes,bytes,0);
+ return ret;
+}
+string stringFieldFromJava(JNIEnv *env, jobject jdata,jfieldID jid){
+ if(!env || !jdata || !jid){
+ WarnL << "invalid args";
+ return "";
+ }
+ jstring field_str = (jstring)env->GetObjectField(jdata,jid);
+ auto ret = stringFromJstring(env,field_str);
+ env->DeleteLocalRef(field_str);
+ return ret;
+}
+
+string bytesFieldFromJava(JNIEnv *env, jobject jdata,jfieldID jid){
+ if(!env || !jdata || !jid){
+ WarnL << "invalid args";
+ return "";
+ }
+ jbyteArray jbufArray = (jbyteArray)env->GetObjectField(jdata, jid);
+ string ret = stringFromJbytes(env,jbufArray);
+ env->DeleteLocalRef(jbufArray);
+ return ret;
+}
+
+jstring jstringFromString(JNIEnv* env, const char* pat) {
+ return (jstring)env->NewStringUTF(pat);
+}
+
+jbyteArray jbyteArrayFromString(JNIEnv* env, const char* pat,int len = 0){
+ if(len <= 0){
+ len = strlen(pat);
+ }
+ jbyteArray jarray = env->NewByteArray(len);
+ env->SetByteArrayRegion(jarray, 0, len, (jbyte *)(pat));
+ return jarray;
+}
+
+/*
+ * 加载动态库
+ */
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
+ //设置日志
+ Logger::Instance().add(std::make_shared());
+ Logger::Instance().setWriter(std::make_shared());
+ InfoL;
+ return JNI_VERSION_1_6;
+}
+/*
+ * 卸载动态库
+ */
+JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved){
+ InfoL;
+ s_sem.post();
+}
+
+
+JNI_API(jboolean,startDemo,jstring path_to_jni_file){
+ string sd_path = stringFromJstring(env,path_to_jni_file);
+ string jni_file = sd_path + "/zlmediakit.jni";
+
+ DebugL << "sd_path:" << sd_path;
+ DebugL << "jni file:" << sd_path;
+
+ static thread s_th([sd_path,jni_file](){
+ try {
+ mINI::Instance()[Http::kRootPath] = mINI::Instance()[Hls::kFilePath] = sd_path + "/httpRoot";
+ do_main(jni_file);
+ }catch (std::exception &ex){
+ WarnL << ex.what();
+ }
+ });
+
+ static onceToken s_token([]{
+ s_th.detach();
+ });
+ return true;
+};
diff --git a/Android/app/src/main/cpp/test_server.cpp b/Android/app/src/main/cpp/test_server.cpp
new file mode 100644
index 00000000..e4ff8120
--- /dev/null
+++ b/Android/app/src/main/cpp/test_server.cpp
@@ -0,0 +1,344 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
+ *
+ * This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include