RTMP介绍
RTMP是Real Time Messaging Protocol(实时消息传输协议)的首字母缩写。该协议基于TCP,是一个协议族,包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMP是一种设计用来进行实时数据通信的网络协议,主要用来在Flash/AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。支持该协议的软件包括Adobe Media Server/Ultrant Media Server/red5等。
Android的RTMP方案
Android上常用的RTMP工程可以用juv-rtmp-client,这是一款收费的软件,但是可以在网上找破解版作为学习了解使用,可以参考该示例。使用起来就是调用API,底层基本上都不要处理接触,比较方便。
同时还有一个开源工程rmtpdump,完全开源C语言代码,我们可以自己根据需要编译和定制,例如要修改rtmp协议时(rtmp内容修改添加部分字段),则rtmpdump则体现出它的优势了。
RtmpDump使用
下载RtmpDump
可以在RtmpDump网站上下载源码编译(编译方法可以网上搜索),或者使用官网已经编译好的rtmpdump-2.3-android.zip库
rtmp native实现
native代码添加
图1
按照Android jni代码方式实现添加,不清楚百度或者参考demo,可以看到代码结构里面包含了librtmp.a和librtmp.so两个文件,其实只是链接方式的不同而已,最后JNI结构如图1所示,Android.mk根据librtmp目标文件是否静态而选在PREBUILT_SHARED_LIBRARY还是PREBUILT_STATIC_LIBRARY
Android.mk按如下编写
<code class="language-ruby hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># Android.mk for rtmp</span> <span class="hljs-constant" style="box-sizing: border-box;">LOCAL_PATH</span> <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span>= <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span>call my-dir) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># rtmp library</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">CLEAR_VARS</span>) <span class="hljs-constant" style="box-sizing: border-box;">LOCAL_MODULE</span> <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span>= rtmp <span class="hljs-constant" style="box-sizing: border-box;">LOCAL_SRC_FILES</span> <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span>= librtmp.so <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">PREBUILT_SHARED_LIBRARY</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#动态库</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#include $(PREBUILT_STATIC_LIBRARY)</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># Program</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">CLEAR_VARS</span>) <span class="hljs-constant" style="box-sizing: border-box;">LOCAL_MODULE</span> <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span>= nativeRtmp <span class="hljs-constant" style="box-sizing: border-box;">LOCAL_SRC_FILES</span> <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span>= nativeRtmp.c <span class="hljs-constant" style="box-sizing: border-box;">LOCAL_C_INCLUDES</span> += <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">LOCAL_PATH</span>)/<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span> <span class="hljs-constant" style="box-sizing: border-box;">LOCAL_LDLIBS</span> <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span>= -llog -lz <span class="hljs-constant" style="box-sizing: border-box;">LOCAL_SHARED_LIBRARIES</span> <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span>= rtmp <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">include</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$(</span><span class="hljs-constant" style="box-sizing: border-box;">BUILD_SHARED_LIBRARY</span>)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li></ul>
Application.mk编写
<code class="language-ruby hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#APP_ABI := all</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#APP_ABI := armeabi armeabi-v7a x86</span> <span class="hljs-constant" style="box-sizing: border-box;">APP_ABI</span> <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">:</span>=armeabi</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>
rtmpdump jni使用
编写nativeRtmp.c,分别编写初始化,销毁和发送函数,来测试使用librtmp.so
发送函数
<code class="language-ruby hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">void send_pkt(char* buf, int buflen, int type, unsigned int timestamp) { int ret; <span class="hljs-constant" style="box-sizing: border-box;">RTMPPacket</span> rtmp_pakt; <span class="hljs-constant" style="box-sizing: border-box;">RTMPPacket_Reset</span>(&rtmp_pakt); <span class="hljs-constant" style="box-sizing: border-box;">RTMPPacket_Alloc</span>(&rtmp_pakt, buflen); rtmp_pakt.m_packetType = type; rtmp_pakt.m_nBodySize = buflen; rtmp_pakt.m_nTimeStamp = timestamp; rtmp_pakt.m_nChannel = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>; rtmp_pakt.m_headerType = <span class="hljs-constant" style="box-sizing: border-box;">RTMP_PACKET_SIZE_LARGE</span>; rtmp_pakt.m_nInfoField2 = pubRtmp->m_stream_id; memcpy(rtmp_pakt.m_body, buf, buflen); ret = <span class="hljs-constant" style="box-sizing: border-box;">RTMP_SendPacket</span>(pubRtmp, &rtmp_pakt, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); <span class="hljs-constant" style="box-sizing: border-box;">RTMPPacket_Free</span>(&rtmp_pakt); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>
初始化
<code class="language-ruby hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">void my_Native_rtmpInit(<span class="hljs-constant" style="box-sizing: border-box;">JNIEnv</span> *env, jobject jobj,jstring jRtmpUrl){ const char* rtmpUrl = (*env)-><span class="hljs-constant" style="box-sizing: border-box;">GetStringUTFChars</span>(env, jRtmpUrl, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); pubRtmpUrl = malloc(strlen(rtmpUrl) + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>); memset(pubRtmpUrl, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, strlen(rtmpUrl) + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>); strcpy(pubRtmpUrl, rtmpUrl); pubRtmp = <span class="hljs-constant" style="box-sizing: border-box;">RTMP_Alloc</span>(); <span class="hljs-constant" style="box-sizing: border-box;">RTMP_Init</span>(pubRtmp); <span class="hljs-constant" style="box-sizing: border-box;">LOGI</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"RTMP_Init %s"</span>, pubRtmpUrl); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!<span class="hljs-constant" style="box-sizing: border-box;">RTMP_SetupURL</span>(pubRtmp, pubRtmpUrl)) { <span class="hljs-constant" style="box-sizing: border-box;">LOGE</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"RTMP_SetupURL error"</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!<span class="hljs-constant" style="box-sizing: border-box;">RTMP_Connect</span>(pubRtmp, <span class="hljs-constant" style="box-sizing: border-box;">NULL</span>) ) { <span class="hljs-constant" style="box-sizing: border-box;">LOGE</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"RTMP_Connect error"</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; } /* <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!<span class="hljs-constant" style="box-sizing: border-box;">RTMP_ConnectStream</span>(pubRtmp, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)) { <span class="hljs-constant" style="box-sizing: border-box;">LOGE</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"RTMP_ConnectStream error"</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; }*<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">/ LOGI("RTMP Connect ok"); send_pkt("aa", 20, RTMP_PACKET_TYPE_AUDIO, 20); }</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>
销毁
<code class="language-ruby hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">void my_Native_rtmpDeInit(<span class="hljs-constant" style="box-sizing: border-box;">JNIEnv</span> *env, jobject jobj) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-constant" style="box-sizing: border-box;">RTMP_IsConnected</span>(pubRtmp)) { <span class="hljs-constant" style="box-sizing: border-box;">RTMP_Close</span>(pubRtmp); } <span class="hljs-constant" style="box-sizing: border-box;">RTMP_Free</span>(pubRtmp); free(pubRtmpUrl); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>
jni动态加载
这里采用JNI_OnLoad函数来加载jni的方法,供给API调用
<code class="language-ruby hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">static <span class="hljs-constant" style="box-sizing: border-box;">JNINativeMethod</span> <span class="hljs-constant" style="box-sizing: border-box;">METHODS</span>[]={ {<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"rtmpInit"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"(Ljava/lang/String;)V"</span>,(void *)my_Native_rtmpInit}, {<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"rtmpDeInit"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"()V"</span>,(void *)my_Native_rtmpDeInit}, }; <span class="hljs-constant" style="box-sizing: border-box;">JNIEXPORT</span> jint <span class="hljs-constant" style="box-sizing: border-box;">JNI_OnLoad</span>(<span class="hljs-constant" style="box-sizing: border-box;">JavaVM</span>* vm, void* reserved) { int retVal = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-constant" style="box-sizing: border-box;">JNIEnv</span> *env; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ( (*vm)-><span class="hljs-constant" style="box-sizing: border-box;">GetEnv</span>(vm,(void **) &env, <span class="hljs-constant" style="box-sizing: border-box;">JNI_VERSION_1_4</span>) == <span class="hljs-constant" style="box-sizing: border-box;">JNI_OK</span> ) { jclass clazz = (*env)-><span class="hljs-constant" style="box-sizing: border-box;">FindClass</span>(env,<span class="hljs-constant" style="box-sizing: border-box;">ClassName</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (clazz != <span class="hljs-constant" style="box-sizing: border-box;">NULL</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ((*env)-><span class="hljs-constant" style="box-sizing: border-box;">RegisterNatives</span>(env,clazz, <span class="hljs-constant" style="box-sizing: border-box;">METHODS</span>,sizeof(<span class="hljs-constant" style="box-sizing: border-box;">METHODS</span>) / sizeof(<span class="hljs-constant" style="box-sizing: border-box;">METHODS</span>[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>])) >= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) { retVal = <span class="hljs-constant" style="box-sizing: border-box;">JNI_VERSION_1_4</span>; }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{ <span class="hljs-constant" style="box-sizing: border-box;">LOGI</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"RegisterNatives Subprocess.create method failed!"</span>); } (*env)-><span class="hljs-constant" style="box-sizing: border-box;">DeleteLocalRef</span>(env,clazz); }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{ <span class="hljs-constant" style="box-sizing: border-box;">LOGI</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"className not found!"</span>); } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> retVal; } <span class="hljs-constant" style="box-sizing: border-box;">JNIEXPORT</span> void <span class="hljs-constant" style="box-sizing: border-box;">JNICALL</span> <span class="hljs-constant" style="box-sizing: border-box;">JNI_OnUnload</span>(<span class="hljs-constant" style="box-sizing: border-box;">JavaVM</span>* vm, void* reserved) { }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li></ul>
ps:这里需要定义ClassName变量,例如demo中
<code class="language-ruby hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">static const char *<span class="hljs-constant" style="box-sizing: border-box;">ClassName</span> = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"org/src/rtmp_get/rtmpJNI"</span>;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
就是说,是org.src.rtmp_get.rtmpJNI类调用了该jni的接口,根据实际调用类的位置和名字来修改该ClassName的名字
rtmp 应用调用
java 类实现
添加需要的libray以及申明Native本地方法,这里需要和JNINativeMethod 中定义的一致,否则会报找不到该接口。
<code class="language-ruby hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">public <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">rtmpJNI</span> {</span> public native void rtmpDeInit(); public native void rtmpInit(<span class="hljs-constant" style="box-sizing: border-box;">String</span> rtmpUrl); static { <span class="hljs-constant" style="box-sizing: border-box;">System</span>.loadLibrary(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"rtmp"</span>); <span class="hljs-constant" style="box-sizing: border-box;">System</span>.loadLibrary(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"nativeRtmp"</span>); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>
应用实现
<code class="language-ruby hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">public <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">MainActivity</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Activity</span> {</span> private rtmpJNI mRtmpClient ; <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@Override</span> protected void onCreate(<span class="hljs-constant" style="box-sizing: border-box;">Bundle</span> savedInstanceState) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onCreate(savedInstanceState); setContentView(<span class="hljs-constant" style="box-sizing: border-box;">R</span>.layout.activity_main); mRtmpClient = new rtmpJNI(); <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span>初始化打开链接rtmp流媒体服务器 mRtmpClient.rtmpInit(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"rtmp://live.hkstv.hk.lxdns.com/live/hks"</span>); <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span>亲测该rtmp地址可用,可以采用rtmp流播放器播放视频 } <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@Override</span> protected void onDestroy() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onDestroy(); mRtmpClient.rtmpDeInit();<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span>销毁断开链接 } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li></ul>
ps一定要记得申明权限,否则会不能正常访问网络
<code class="language-ruby hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <uses-permission <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">android:</span>name=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"android.permission.INTERNET"</span>><<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">/uses-permission></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
测试链接
可以用简易RED5流媒体服务器测试参考Windows环境搭建Red5流媒体服务器指南,执行red5.bat,然后执行上述应用,看是否能够链接上服务器。
总结
上面就是对rtmpDump的使用,可以参考如上操作,附上demo以及相关链接,Q&A。