android移植live555

live555是什么就不介绍了,你点进来肯定知道是什么东西了,前段时间折腾了一下rtsp相关的东西,觉得有必要记录一下。

废话不多说,首先下载live555
最新的live555源码下载

在Android Studio3里新建一个工程,记得勾选C++支持
将下载的live555源码解压出来后,放到src/main/cpp的目录下,有的是src/main/jni目录
默认的AS工程是使用CMAKE编译,没学过的可以看下这篇文章CMake 入门实战
然后直接编辑工程根目录的CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

add_definitions(-DSOCKLEN_T=socklen_t)
add_definitions(-DNO_SSTREAM=1)
add_definitions(-DNEWLOCALE_NOT_USED)
#add_definitions(-D_LARGEFILE_SOURCE=1)
#add_definitions(-D_FILE_OFFSET_BITS=64)
add_definitions(-DBSD=1)

include_directories(src/main/cpp/live/UsageEnvironment/include)
include_directories(src/main/cpp/live/BasicUsageEnvironment/include)
include_directories(src/main/cpp/live/groupsock/include)
include_directories(src/main/cpp/live/liveMedia/include)

file(GLOB BasicUsageEnvironmentFiles
    src/main/cpp/live/BasicUsageEnvironment/*.cpp)
add_library(BasicUsageEnvironment
            ${BasicUsageEnvironmentFiles})

file(GLOB groupsockfiles
    src/main/cpp/live/groupsock/*.cpp src/main/cpp/live/groupsock/*.c)
add_library(groupsock ${groupsockfiles})

file(GLOB liveMediaFiles
        src/main/cpp/live/liveMedia/*.hh src/main/cpp/live/liveMedia/*.cpp src/main/cpp/live/liveMedia/*.c)
add_library(liveMedia ${liveMediaFiles})

file(GLOB UsageEnvironmentFiles
    src/main/cpp/live/UsageEnvironment/*.cpp)
add_library(UsageEnvironment ${UsageEnvironmentFiles})

add_library( native-lib
             SHARED
             src/main/cpp/native-lib.cpp )


find_library(log-lib
              log )

target_link_libraries( native-lib
                       ${log-lib}
                       liveMedia
                       groupsock
                       BasicUsageEnvironment
                       UsageEnvironment )

其中的一些编译标志,可以参考下载的live555源码里的config.armlinux

CROSS_COMPILE?=     arm-elf-
COMPILE_OPTS =      $(INCLUDES) -I. -O2 -DSOCKLEN_T=socklen_t -DNO_SSTREAM=1 -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
C =         c
C_COMPILER =        $(CROSS_COMPILE)gcc
C_FLAGS =       $(COMPILE_OPTS)
CPP =           cpp
CPLUSPLUS_COMPILER =    $(CROSS_COMPILE)g++
CPLUSPLUS_FLAGS =   $(COMPILE_OPTS) -Wall -DBSD=1
OBJ =           o
LINK =          $(CROSS_COMPILE)g++ -o
LINK_OPTS =     
CONSOLE_LINK_OPTS = $(LINK_OPTS)
LIBRARY_LINK =      $(CROSS_COMPILE)ar cr 
LIBRARY_LINK_OPTS = $(LINK_OPTS)
LIB_SUFFIX =            a
LIBS_FOR_CONSOLE_APPLICATION =
LIBS_FOR_GUI_APPLICATION =
EXE =

这里有好几个flag,但是添加了 -D_LARGEFILE_SOURCE=1和-D_FILE_OFFSET_BITS=64之后就在Win10上用ndk16就编译不过了,不知道什么原因,直接屏蔽了,好像也没什么影响

然后在build.gradle里设置只编译armeabi-v7a,因为编译其他64位的会编译出错,暂时只用到armeabi-v7a,所以只编译一个就行了。以后有需要再看看什么问题,谁解决了在评论里教我一下

android {
    ...
    defaultConfig {
        ...
        ndk {
            abiFilters 'armeabi-v7a'
        }
        externalNativeBuild {
            cmake {
                cppFlags "-frtti -fexceptions"
            }
        }
    }

然后在AS里点击编译按钮,正常的话就直接编出libnative-lib.so了

接下来就是使用live555了,先在MainActivity.java里定义一个public native String start(String fileName);本地方法,用来启动Rtsp服务器,这里传入一个H264的码流文件,客户端就可以通过rtsp的url来点播视频了

在native-lib.cpp实现我们的start方法,代码可以参看live555里面的样例,注意这里代码会一直阻塞,直到Rtspserver退出才会退出这个方法
可以参考Live555在Android下改造

extern "C" JNIEXPORT jstring JNICALL Java_com_example_live555_MainActivity_start(JNIEnv *env, jobject instance, jstring fileName_) {
    const char *inputFilename = env->GetStringUTFChars(fileName_, 0);
    FILE *file = fopen(inputFilename, "rb");
    if (!file) {
        LOGE("couldn't open %s", inputFilename);
        exit(1);
    }
    fclose(file);

    TaskScheduler* scheduler = BasicTaskScheduler::createNew();
    UsageEnvironment* env_ = BasicUsageEnvironment::createNew(*scheduler);
    UserAuthenticationDatabase* authDB = NULL;
    // Create the RTSP server:
    RTSPServer* rtspServer = RTSPServer::createNew(*env_, 8554, authDB);
    if (rtspServer == NULL) {
        LOGE("Failed to create RTSP server: %s", env_->getResultMsg());
        exit(1);
    }
    char const* descriptionString = "Session streamed by \"testOnDemandRTSPServer\"";
    char const* streamName = "v";
    ServerMediaSession* sms  = ServerMediaSession::createNew(*env_, streamName, streamName, descriptionString);
    sms->addSubsession(H264VideoFileServerMediaSubsession::createNew(*env_, inputFilename, True));
    rtspServer->addServerMediaSession(sms);

    char* url = rtspServer->rtspURL(sms);
    LOGE("%s stream, from the file %s ",streamName, inputFilename);
    LOGE("Play this stream using the URL: %s", url);
    delete[] url;

    env->ReleaseStringUTFChars(fileName_, inputFilename);
    env_->taskScheduler().doEventLoop(); // does not return
}

到这里就可以开启rtsp服务器了,在MainActivity里启动一个线程,在线程里调用start方法,传入H264码流的文件路径就可以了,注意打开读写外部存储的权限

本文示例源码下载

猜你喜欢

转载自blog.csdn.net/abc_1234d/article/details/80229423