diff --git a/Android/app/build.gradle b/Android/app/build.gradle index 56c5646d..7e02236a 100644 --- a/Android/app/build.gradle +++ b/Android/app/build.gradle @@ -13,6 +13,7 @@ android { externalNativeBuild { cmake { cppFlags "-std=c++11 -frtti -fexceptions" + arguments "-DENABLE_API=off", "-DENABLE_TESTS=off", "-DENABLE_PLAYER=off", "-DENABLE_SERVER_LIB=on" } } ndk { diff --git a/Android/app/src/main/cpp/CMakeLists.txt b/Android/app/src/main/cpp/CMakeLists.txt index 9d3aac46..cbf19cbf 100644 --- a/Android/app/src/main/cpp/CMakeLists.txt +++ b/Android/app/src/main/cpp/CMakeLists.txt @@ -6,106 +6,30 @@ set(CMAKE_CXX_STANDARD 11) #设置生成的so动态库最后输出的路径 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/libs_export/${ANDROID_ABI}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/libs_export/${ANDROID_ABI}) - -LINK_DIRECTORIES(${LIBRARY_OUTPUT_PATH}) +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/libs_export/${ANDROID_ABI}/binary) +set(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${ANDROID_ABI}/") #设置工程源码根目录 -set(ZLMediaKit_Root ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../) set(JNI_Root ${CMAKE_CURRENT_SOURCE_DIR}) -set(ToolKit_Root ${ZLMediaKit_Root}/3rdpart/ZLToolKit/src) -set(MediaKit_Root ${ZLMediaKit_Root}/src) -set(MediaServer_Root ${ZLMediaKit_Root}/3rdpart/media-server/) +set(ZLMediaKit_Root ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../) -#设置头文件目录 -INCLUDE_DIRECTORIES(${ToolKit_Root}) -INCLUDE_DIRECTORIES(${MediaKit_Root}) -INCLUDE_DIRECTORIES(${JNI_Root}) +#添加主工程cmake +add_subdirectory(${ZLMediaKit_Root} ${EXECUTABLE_OUTPUT_PATH}) -#收集源代码 -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) +#设置include +include_directories(${JNI_Root}) +include_directories(${ZLMediaKit_Root}/src) +include_directories(${ZLMediaKit_Root}/srt) +include_directories(${ZLMediaKit_Root}/webrtc) +include_directories(${ZLMediaKit_Root}/server) +include_directories(${ZLMediaKit_Root}/3rdpart) +include_directories(${ZLMediaKit_Root}/3rdpart/media-server) +include_directories(${ZLMediaKit_Root}/3rdpart/ZLToolKit/src) + +#收集源代码添加动态库 file(GLOB JNI_src_list ${JNI_Root}/*.cpp ${JNI_Root}/*.h) - -#去除win32的适配代码 -if (NOT WIN32) - list(REMOVE_ITEM ToolKit_src_list ${ToolKit_Root}/win32/getopt.c) -else() - #防止Windows.h包含Winsock.h - add_definitions(-DWIN32_LEAN_AND_MEAN -DMP4V2_NO_STDINT_DEFS) -endif () - -set(ENABLE_HLS true) -set(ENABLE_OPENSSL true) -set(ENABLE_MYSQL false) -set(ENABLE_FAAC false) -set(ENABLE_X264 false) -set(ENABLE_MP4 true) - -#添加两个静态库 -if(ENABLE_HLS) - message(STATUS "ENABLE_HLS defined") - add_definitions(-DENABLE_HLS) - set(LINK_LIB_LIST zlmediakit zltoolkit mpeg) -else() - set(LINK_LIB_LIST zlmediakit zltoolkit) -endif() - - -if(ENABLE_MP4) - message(STATUS "ENABLE_MP4 defined") - add_definitions(-DENABLE_MP4) - list(APPEND LINK_LIB_LIST mov flv) -endif() - -if (ENABLE_OPENSSL) - #openssl - add_definitions(-DENABLE_OPENSSL) - INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/../../../libs/${ANDROID_ABI}/include) - LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/../../../libs/${ANDROID_ABI}/) - list(APPEND LINK_LIB_LIST ssl crypto) -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}) - if(MSVC) - set_target_properties(mpeg PROPERTIES COMPILE_FLAGS ${VS_FALGS} ) - endif() -endif() - -if(ENABLE_MP4) - aux_source_directory(${MediaServer_Root}/libmov/include src_mov) - aux_source_directory(${MediaServer_Root}/libmov/source src_mov) - include_directories(${MediaServer_Root}/libmov/include) - aux_source_directory(${MediaServer_Root}/libflv/include src_flv) - aux_source_directory(${MediaServer_Root}/libflv/source src_flv) - include_directories(${MediaServer_Root}/libflv/include) - add_library(mov STATIC ${src_mov}) - add_library(flv STATIC ${src_flv}) - if(MSVC) - set_target_properties(mov flv PROPERTIES COMPILE_FLAGS ${VS_FALGS} ) - endif() -endif() - - -#添加库 -add_library(zltoolkit STATIC ${ToolKit_src_list}) -add_library(zlmediakit STATIC ${MediaKit_src_list}) add_library(zlmediakit_jni SHARED ${JNI_src_list}) -add_definitions(-DDISABLE_MAIN) -#添加json以及MediaServer相关代码 -include_directories(${ZLMediaKit_Root}/3rdpart) -include_directories(${ZLMediaKit_Root}/server) -file(GLOB jsoncpp_src_list ${ZLMediaKit_Root}/3rdpart/jsoncpp/*.cpp) -file(GLOB MediaServer_src_list ${ZLMediaKit_Root}/server/*.cpp) -add_library(jsoncpp STATIC ${jsoncpp_src_list}) -add_library(MediaServer STATIC ${MediaServer_src_list}) - #链接 -target_link_libraries(zlmediakit_jni MediaServer jsoncpp ${LINK_LIB_LIST} log z) - +target_link_libraries(zlmediakit_jni -Wl,--start-group log z ${LINK_LIB_LIST} -Wl,--end-group) diff --git a/Android/app/src/main/cpp/native-lib.cpp b/Android/app/src/main/cpp/native-lib.cpp index 016d81ff..5713b11e 100644 --- a/Android/app/src/main/cpp/native-lib.cpp +++ b/Android/app/src/main/cpp/native-lib.cpp @@ -15,92 +15,94 @@ #include "Common/config.h" #include "Player/MediaPlayer.h" #include "Extension/Frame.h" + using namespace std; using namespace toolkit; using namespace mediakit; -#define JNI_API(retType,funName,...) extern "C" JNIEXPORT retType Java_com_zlmediakit_jni_ZLMediaKit_##funName(JNIEnv* env, jclass cls,##__VA_ARGS__) +#define JNI_API(retType, funName, ...) extern "C" JNIEXPORT retType Java_com_zlmediakit_jni_ZLMediaKit_##funName(JNIEnv* env, jclass cls,##__VA_ARGS__) #define MediaPlayerCallBackSign "com/zlmediakit/jni/ZLMediaKit$MediaPlayerCallBack" #define MediaFrameSign "com/zlmediakit/jni/ZLMediaKit$MediaFrame" - -string stringFromJstring(JNIEnv *env,jstring jstr){ - if(!env || !jstr){ +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)); + string ret(field_char, env->GetStringUTFLength(jstr)); env->ReleaseStringUTFChars(jstr, field_char); return ret; } -string stringFromJbytes(JNIEnv *env,jbyteArray jbytes){ - if(!env || !jbytes){ + +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); + 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){ + +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); + 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){ +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); + 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); +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){ +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)); + env->SetByteArrayRegion(jarray, 0, len, (jbyte * )(pat)); return jarray; } -jobject makeJavaFrame(JNIEnv* env,const Frame::Ptr &frame){ - static jclass jclass_obj = (jclass)env->NewGlobalRef(env->FindClass(MediaFrameSign)); +jobject makeJavaFrame(JNIEnv *env, const Frame::Ptr &frame) { + static jclass jclass_obj = (jclass) env->NewGlobalRef(env->FindClass(MediaFrameSign)); static jmethodID jmethodID_init = env->GetMethodID(jclass_obj, "", "()V"); - static jfieldID jfieldID_dts = env->GetFieldID(jclass_obj,"dts","I"); - static jfieldID jfieldID_pts = env->GetFieldID(jclass_obj,"pts","I"); - static jfieldID jfieldID_prefixSize = env->GetFieldID(jclass_obj,"prefixSize","I"); - static jfieldID jfieldID_keyFrame = env->GetFieldID(jclass_obj,"keyFrame","Z"); - static jfieldID jfieldID_data = env->GetFieldID(jclass_obj,"data","[B"); - static jfieldID jfieldID_trackType = env->GetFieldID(jclass_obj,"trackType","I"); - static jfieldID jfieldID_codecId = env->GetFieldID(jclass_obj,"codecId","I"); + static jfieldID jfieldID_dts = env->GetFieldID(jclass_obj, "dts", "I"); + static jfieldID jfieldID_pts = env->GetFieldID(jclass_obj, "pts", "I"); + static jfieldID jfieldID_prefixSize = env->GetFieldID(jclass_obj, "prefixSize", "I"); + static jfieldID jfieldID_keyFrame = env->GetFieldID(jclass_obj, "keyFrame", "Z"); + static jfieldID jfieldID_data = env->GetFieldID(jclass_obj, "data", "[B"); + static jfieldID jfieldID_trackType = env->GetFieldID(jclass_obj, "trackType", "I"); + static jfieldID jfieldID_codecId = env->GetFieldID(jclass_obj, "codecId", "I"); - if(!frame){ + if (!frame) { return nullptr; } jobject ret = env->NewObject(jclass_obj, jmethodID_init); - env->SetIntField(ret,jfieldID_dts,frame->dts()); - env->SetIntField(ret,jfieldID_pts,frame->pts()); - env->SetIntField(ret,jfieldID_prefixSize,frame->prefixSize()); - env->SetBooleanField(ret,jfieldID_keyFrame,frame->keyFrame()); - env->SetObjectField(ret,jfieldID_data,jbyteArrayFromString(env,frame->data(),frame->size())); - env->SetIntField(ret,jfieldID_trackType,frame->getTrackType()); - env->SetIntField(ret,jfieldID_codecId,frame->getCodecId()); + env->SetIntField(ret, jfieldID_dts, frame->dts()); + env->SetIntField(ret, jfieldID_pts, frame->pts()); + env->SetIntField(ret, jfieldID_prefixSize, frame->prefixSize()); + env->SetBooleanField(ret, jfieldID_keyFrame, frame->keyFrame()); + env->SetObjectField(ret, jfieldID_data, jbyteArrayFromString(env, frame->data(), frame->size())); + env->SetIntField(ret, jfieldID_trackType, frame->getTrackType()); + env->SetIntField(ret, jfieldID_codecId, frame->getCodecId()); return ret; } @@ -160,7 +162,8 @@ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved){ } extern int start_main(int argc,char *argv[]); -JNI_API(jboolean,startDemo,jstring ini_dir){ + +JNI_API(jboolean, startDemo, jstring ini_dir){ string sd_path = stringFromJstring(env,ini_dir); string ini_file = sd_path + "/zlmediakit.ini"; @@ -185,9 +188,9 @@ JNI_API(jboolean,startDemo,jstring ini_dir){ mINI::Instance()["rtsp.port"] = 8554; mINI::Instance()["rtsp.sslport"] = 8332; mINI::Instance()["general.enableVhost"] = 0; - for(auto &pr : mINI::Instance()){ + for (auto &pr : mINI::Instance()) { //替换hook默认地址 - replace(pr.second,"https://127.0.0.1/","http://127.0.0.1:8080/"); + replace(pr.second, "https://127.0.0.1/", "http://127.0.0.1:8080/"); } //默认打开hook mINI::Instance()["hook.enable"] = 0; @@ -195,10 +198,9 @@ JNI_API(jboolean,startDemo,jstring ini_dir){ mINI::Instance()["api.apiDebug"] = 1; int argc = 5; - const char *argv[] = {"","-c",ini_file.data(),"-s",pem_file.data()}; - - start_main(argc,(char **)argv); - }catch (std::exception &ex){ + const char *argv[] = {"", "-c", ini_file.data(), "-s", pem_file.data()}; + start_main(argc, (char **) argv); + } catch (std::exception &ex) { WarnL << ex.what(); } }); @@ -210,7 +212,7 @@ JNI_API(jboolean,startDemo,jstring ini_dir){ return true; }; -JNI_API(jlong,createMediaPlayer,jstring url,jobject callback){ +JNI_API(jlong, createMediaPlayer, jstring url, jobject callback){ static auto loadFrameClass = makeJavaFrame(env,nullptr); MediaPlayer::Ptr *ret = new MediaPlayer::Ptr(new MediaPlayer()); MediaPlayer::Ptr &player = *ret; @@ -260,8 +262,6 @@ JNI_API(jlong,createMediaPlayer,jstring url,jobject callback){ return (jlong)(ret); } - - JNI_API(void,releaseMediaPlayer,jlong ptr){ MediaPlayer::Ptr *player = (MediaPlayer::Ptr *)ptr; delete player; diff --git a/CMakeLists.txt b/CMakeLists.txt index 92e0df66..eb193431 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,6 +98,7 @@ option(ENABLE_API "Enable C API SDK" true) option(ENABLE_CXX_API "Enable C++ API SDK" false) option(ENABLE_TESTS "Enable Tests" true) option(ENABLE_SERVER "Enable Server" true) +option(ENABLE_SERVER_LIB "Enable server as android static library" false) option(ENABLE_MEM_DEBUG "Enable Memory Debug" false) option(ENABLE_ASAN "Enable Address Sanitize" false) option(ENABLE_WEBRTC "Enable WebRTC" true) @@ -307,7 +308,7 @@ if (JEMALLOC_FOUND) endif () #查找openssl是否安装 -find_package(OpenSSL QUIET) +find_package(OPENSSL QUIET) if (OPENSSL_FOUND AND ENABLE_OPENSSL) message(STATUS "found library:${OPENSSL_LIBRARIES},ENABLE_OPENSSL defined") include_directories(${OPENSSL_INCLUDE_DIR}) @@ -521,3 +522,7 @@ endif () if (ENABLE_PLAYER) add_subdirectory(player) endif () + +if (ENABLE_SERVER_LIB) + set(LINK_LIB_LIST ${LINK_LIB_LIST} PARENT_SCOPE) +endif () diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 37735b55..a94654a2 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -3,6 +3,14 @@ file(GLOB jsoncpp_src_list ../3rdpart/jsoncpp/*.cpp ../3rdpart/jsoncpp/*.h ) add_library(jsoncpp STATIC ${jsoncpp_src_list}) file(GLOB MediaServer_src_list ./*.cpp ./*.h) +if (ENABLE_SERVER_LIB) + add_definitions(-DDISABLE_MAIN) + add_library(MediaServer STATIC ${MediaServer_src_list}) + list(APPEND LINK_LIB_LIST MediaServer jsoncpp) + set(LINK_LIB_LIST ${LINK_LIB_LIST} PARENT_SCOPE) + return() +endif () + add_executable(MediaServer ${MediaServer_src_list}) if(MSVC)