这段时间做实时视频的网页直播遇到了很多困难。

    开始时,迫于项目时间的压力,觉得没有足够的时间学习和分析如何将实时视频发送到RTMP流媒体服务器作为实时流,只好使用最粗糙的做法是:先把获取到的 实时视频以RTP包的形式 发送给本机,然后本机程序中调用ffmpeg将接收到的RTP包 以RTMP的形式转发到Red5,最后,从网页上获取播放列表,播放实时视频。

    这种做法中存在很多问题:(1)多了一层rtp包到rtmp服务器的转发,浪费很多处理器的时间。(2)多了一层转发,系统稳定性很有问题。在视频流转发 了一定时间后,ffmpeg会奇怪地停止转发,原因不明。(3)ffmpeg的视频流播放控制难以实现。在网页上停止播放和继续播放视频时,既要控制发送 RTP包,又要控制RTMP包,很麻烦。

    后来,分析了一下ffmpeg的源代码,发现FFmpeg中对RTMP的支持部分就是使用了RTMPDump中的librtmp。于是,我就打算直接使用librtmp与Red5建立rtmp连接,将实时视频直接发到Red5。

    最近过年,在家里闲着,就认真研究一下如何使用librtmp直接将实时视频发送到Red5。我们首先要做的就是编译出librtmp的动态库和静态库。

    RTMPDump项目官方网站在:http://rtmpdump.mplayerhq.hu/ 。对RTMP协议的实现在其中librtmp中。这是一个匈牙利人在2009年,Adobe公司还没有公开RTMP协议的情况下对RTMP协议的实现得。 官方网站中只提供了程序源代码和动态链接库(dll),要在开发中方便地使用RTMPDump,还需要自己编译它的静态库(lib)。

 

    ==> 编译librtmp静态库

    从官方网站http://rtmpdump.mplayerhq.hu/ 下载RTMPDump源代码。

    要编译librtmp,还需要另外3个库:zlib、OpenSSL、PolarSSL。

    zlib是用于数据压缩的函数库,数据压缩效果比较好,早在1995年就发布了第一版,目前仅支持LZ77变种算法、DEFLATE算法。(http://www.zlib.net/)。

    OpenSSL和PolarSSL 是对SSL(Security Socket Layer,加密套接字协议层)的实现。(http://www.openssl.org/  http://polarssl.org/)。

    (1)使用VC++6.0新建一个静态库工程,命名为librtmp,如下图所示:

实时视频在网页直播--windows下编译librtmp、rtmpdump_第1张图片

 

     (2)把RTMPDump源代码目录下的librtmp目录下的所有文件 复制到工程目录librtmp\下,并在VC++6.0中的Source Files和Header Files文件夹中添加librtmp相应的文件,如下图所示:

 

     (3)下载zlib开发包 http://download.csdn.net/source/3013660。把其中的zdll.lib、zlib.def、zlib.h、zconf.h放到新建的工程目录librtmp\下。

     (4)下载openssl开发包 http://download.csdn.net/source/3013684。 把其中的libeay32.lib、ssleay32.lib 及openssl文件夹 复制到工程目录librtmp\下,并在VC++6.0的“工具”->“选项”->“目录”-> “ Include files ”中添加当前的工程目录librtmp\。如下图所示:

 

    (5) 下载PolarSSL源代码 http://download.csdn.net/source/3013696。解压出来,用VC++6.0打开\visualc\polarssl.dsw ,可以编译出静态库(polarssl.lib)。然后将头文件所在的文件夹polarssl\ 和polarssl.lib复制到工程目录librtmp\下。

    (6)编译静态库工程,这时会在多个文件中出现这样一个错误: error C2065: '__FUNCTION__' : undeclared identifier 。解决办法是,在存在这个错误的.c文件的中添加一个宏定义:#define __FUNCTION__ "" 。问题就解决了。再编译工程即可得到librtmp.lib,如下图所示:

     (7)但是,这样编译出来的librtmp.lib在使用的时候会出现很多个外部符号未定义的错误。如下图所示:

    这是librtmp的条件编译导致的问题,解决方法是:在rtmp_sys.h中把代码:

#ifdef _XBOX
#include
#include
#define snprintf _snprintf
#define strcasecmp stricmp
#define strncasecmp strnicmp
#define vsnprintf _vsnprintf

#else /* !_XBOX */
#include
#include
#endif

    改为

#include
#include

#define snprintf _snprintf
#define strcasecmp stricmp
#define strncasecmp strnicmp
#define vsnprintf _vsnprintf

    然后,删除rtmp.c中的如下代码:

#ifdef _DEBUG
  fwrite(buf, 1, len, netstackdump);
#endif

#ifdef _DEBUG
extern FILE *netstackdump;
extern FILE *netstackdump_read;
#endif

#ifdef _DEBUG
      fwrite(ptr, 1, nBytes, netstackdump_read);
#endif

(8)编译rtmp.c即可得到librtmp.lib

 

    我已经将rtmpdump编译好的静态库、动态库以及源代码打成一个包,放到 http://download.csdn.net/source/3033310。如果不想自己编译,可以从这里下载。也可以从javaeye博客中下载:http://c1zhao.javaeye.com/blog/901900。