最近在做一个QT的项目,实现流媒体的在线播放,是基于RTSP协议的。我们只做客户端,服务器采用的是利live555。对于音频的播放,我一开始采用的播放器是madplay,它支持音频流的在线播放。既然是播放器那么它也得要能播放视频,但是madplay是不能作为视频播放器的,所以我采用了一个linux下使用率很高的开源的播放器MPlayer。它的界面很友好,现在最新的已经是1.1版了,可以到它的官网上下载(http://www.mplayerhq.hu/design7/dload.html)。下载之后,我们对他进行编译,和普通的源码文件的编译方式一样,大体有4步,我在这里简单的说下。1.解压源码 。2.进行配置 。3.执行make。4.执行make install。当然,在这个过程中会出现一些错误,你把这些错误码复制一下,在网上都可以找到相对应的解决方法。其中可能有一个错误很棘手,我在这里也是卡了很久,就是编译时出现:
libavcodec/flashsv.c: In function 'calc_deflate_block_size':
libavcodec/flashsv.c:224:5: error: implicit declaration of function 'deflateBound' [-Werror=implicit-function-declaration]
cc1: some warnings being treated as errors
make[1]: *** [libavcodec/flashsv.o] Error 1
make[1]: Leaving directory `/home/chenyu/chenyu/MPlayer-1.1/ffmpeg'
make: *** [ffmpeg/libavcodec/libavcodec.a] 错误 2
在函数calc_deflate_block_size中,出现了deflateBound这个函数,我在flashsv.c这个文件里找到了deflateBound()这个函数,但是没有找到它的函数体,我在整个MPlayer里都没有找到,但是你会注意到flashsv.c这个文件有个头文件#include<zlib.h>,我想它应该在这个头文件中定义的,我的是zlib1.1.4,但是我在这个库里没有找到它,后来看到了一篇文章外文:
Porting to old zlib (deflateBound) & old mktemp (e.g., Red Hat Linux 9)
This message: [ Message body ] [ Respond ] [ More options ]
Related messages: [ Next message ] [ Previous message ] [ In reply to ]
From: David A. Wheeler <dwheeler@dwheeler.com>
Date: 2005-04-22 09:27:57
On Thu, 21 Apr 2005 12:19:32 -0500 Joel Schopp wrote:
>| I downloaded git-pasky 0.6.2. I cannot compile it because my zlib
>| version is 1.1.4 and git-pasky relies on functiondeflateBound()which
>| wasn't introduced until zlib version 1.2.x Is there a patch out there
>| to work around this and maybe conditionally compile based on the zlib
>| version?
>
>
Here's a quick (read: nasty, dreadful) hack to port git
to older systems like Red Hat Linux 9 which have old versions
of zlib & mktemp. Someone who actually spent two seconds
on this can no doubt give you a better solution, but it "worked for me".
Edit sha1_file.c, and change the line:
size = deflateBound(&stream, len); //既然没有它,我们可以可以用其他的语句代替它,我试了一下,可以,但是你
to //会发现这样不方便,因为下面还有很多用到的它,这样一个一个该很不方便,
size = len + 1024; /* 1024=emergency extra space */ //我们要从中找到本质的原因,这样就不会这么麻烦。我在上
//面的红色标出来了,可以看出来这是因为版本的原因,查一 //下我的zlib版本是1.1.4的,我换了一下zlib,换成了zlib1.2.7
//然后编译就不会出现上面那样的问题了。
The "deflateBound" call just finds out the maximum amount of allocation
space.
The documentation says that "deflateBound() may return a
conservative value that may be larger than /sourceLen/" in certain cases,
which worried me. So to be safe I just added a big pile of excess space
to "len";
I suspect that "size = len" is sufficient but I didn't investigate it.
If you're trying to get this to work on Red Hat Linux 9, you'll
have another problem too: old versions of "mktemp"
don't support the "-t" option. Other old distributions will
have the same problem. To find these cases, do:
grep "mktemp.*-t" *
and edit all the files to remove the "-t" option from mktemp.
That's the bare minimum to make it work; a much
cleaner solution would to specify the tempdir, e.g.,:
mktemp ${TMPDIR:-/tmp/}gitci.XXXXX
or even more portably, write the shell code to set TMPDIR to "/tmp"
locally if it's not set, then use $TMPDIR everywhere.
Not a good final solution, but enough to get started in the interim.
In long term, this should be made more portable, but it's
only ~2 weeks old after all. Some people are trying to fly this plane
to transport a buffalo herd, while others are working to attach the
wings :-).
--- David A. Wheeler
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
编译好之后生成的mplayer就可以播放视频和音频文件了,但是播放的这个视频或者音频文件是完整的在本地磁盘的。而这个QT项目的要求是实现远程数据流的播放,按照上述方法编译出来的mplay是播放不了流媒体的。你如果让他去播放live555服务器发送的媒体流,会出现 “MPEG: Missing video stream!? Contact the author, it may be a bug :( ” 这样的错误。但是前辈们为我们想到了这一点,我们可以在mplayer的官网上看到(http://www.live555.com/mplayer/)
RTSP/RTP streaming support for MPlayer
Please do the following steps, in order:
- Download and build the "LIVE555 Streaming Media" libraries. You may wish to move the resulting "live/" directory to "/usr/local/", "/usr/local/lib/", or "/usr/lib/". (Note: If you do this, you must move the entire "live/" directory - not just the library files.)
- Download the newest version of the MPlayer source code.
- If, in Step 1, you moved the "live/" directory to "/usr/local/", "/usr/local/lib/", or "/usr/lib/", run
cd MPlayer* ; ./configure
and check to see whether the "live555" library was automaticaly detected. Otherwise, runcd MPlayer* ; ./configure --extracflags=-I <path-to-LIVE555-Streaming-Media-library-directory>
- Now, build and install MPlayer as usual - i.e.,
make ; make install
(Note that you must build MPlayer with the same version of "gcc" that you used to build the LIVE555 Streaming Media code.)
How to configure and build the code on Unix (including Linux, Mac OS X, QNX, and other Posix-compliant systems)
The source code package can be found (as a ".tar.gz" file) here . Use "tar -x" and "gunzip" (or "tar -xz", if available) to extract the package; then cd to the "live" directory. Then run./genMakefiles <os-platform> //os-platform指你的平台,我这里是写的linuxwhere <os-platform> is your target platform - e.g., "linux" or "solaris" - defined by a "config. <os-platform> " file. This will generate a Makefile in the "live" directory and each subdirectory.Then run "make".
- If the "make" fails, you may need to make small modifications to the appropriate "config.<os-platform>" file, and then re-run "genMakefiles <os-platform>". (E.g., you may need to add another "-I<dir>" flag to the COMPILE_OPTS definition.)
- Some people (in particular, FreeBSD users) have reported that the GNU version of "make" - often called "gmake" - works better than their default, pre-installed version of "make". (In particular, you should try using "gmake" if you encounter linking problems with the "ar" command.)
- If you're using "gcc" version 3.0 or greater: You may also wish to add the -Wno-deprecated flag to CPLUSPLUS_FLAGS.
- If no "config.<os-platform>" file exists for your target platform, then try using one of the existing files as a template.
-I /usr/local/lib/live/UsageEnvironment/include
-I /usr/local/lib/live/BasicUsageEnvironment/include
-I /usr/local/lib/live/groupsock/include"
--extra-ldflags="-L /usr/local/lib/live/liveMedia/libliveMedia.a
-L /usr/local/lib/live/UsageEnvironment/libUsageEnvironment.a
-L /usr/local/lib/live/BasicUsageEnvironment/libBasicUsageEnvironment.a
-L /usr/local/lib/live/groupsock/libgroupsock.a"
demux_rtp.cpp:(.text+0xd6): undefined reference to `RTSPClient::teardownMediaSession(MediaSession&)'
demux_rtp.cpp:(.text+0xef): undefined reference to `Medium::close(Medium*)'
demux_rtp.cpp:(.text+0xfa): undefined reference to `Medium::close(Medium*)'
demux_rtp.cpp:(.text+0x105): undefined reference to `Medium::close(Medium*)'
demux_rtp.cpp:(.text+0x131): undefined reference to `operator delete[](void*)'
demux_rtp.cpp:(.text+0x139): undefined reference to `operator delete(void*)'
demux_rtp.cpp:(.text+0x14d): undefined reference to `UsageEnvironment::reclaim()'
demux_rtp.cpp:(.text+0x18f): undefined reference to `SIPClient::sendBYE()'
libmpdemux/demux_rtp.o: In function `demux_open_rtp':
demux_rtp.cpp:(.text+0x4df): undefined reference to `BasicTaskScheduler::createNew(unsigned int)'
demux_rtp.cpp:(.text+0x4ef): undefined reference to `BasicUsageEnvironment::createNew(TaskScheduler&)'
demux_rtp.cpp:(.text+0x548): undefined reference to `MediaSession::createNew(UsageEnvironment&, char const*)'
demux_rtp.cpp:(.text+0x560): undefined reference to `operator new(unsigned int)'
demux_rtp.cpp:(.text+0x5b8): undefined reference to `MediaSubsessionIterator::MediaSubsessionIterator(MediaSession const&)'
demux_rtp.cpp:(.text+0x5d8): undefined reference to `MediaSubsessionIterator::next()'
demux_rtp.cpp:(.text+0x624): undefined reference to `MediaSubsession::setClientPortNum(unsigned short)'
demux_rtp.cpp:(.text+0x634): undefined reference to `MediaSubsession::initiate(int)'
demux_rtp.cpp:(.text+0x73f): undefined reference to `increaseReceiveBufferTo(UsageEnvironment&, int, unsigned int)'
demux_rtp.cpp:(.text+0x7a8): undefined reference to `RTSPClient::setupMediaSubsession(MediaSubsession&, unsigned char, unsigned char, unsigned char)'
demux_rtp.cpp:(.text+0x862): undefined reference to `RTSPClient::playMediaSession(MediaSession&, double, double, float)'
demux_rtp.cpp:(.text+0x876): undefined reference to `MediaSubsessionIterator::reset()'
demux_rtp.cpp:(.text+0x8bd): undefined reference to `MediaSubsessionIterator::next()'
demux_rtp.cpp:(.text+0x8f8): undefined reference to `operator new(unsigned int)'
demux_rtp.cpp:(.text+0x990): undefined reference to `operator new(unsigned int)'
demux_rtp.cpp:(.text+0xa28): undefined reference to `MediaSubsessionIterator::~MediaSubsessionIterator()'
demux_rtp.cpp:(.text+0xab9): undefined reference to `SIPClient::sendACK()'
demux_rtp.cpp:(.text+0xaca): undefined reference to `MediaSubsessionIterator::~MediaSubsessionIterator()'
demux_rtp.cpp:(.text+0xb2b): undefined reference to `RTSPClient::createNew(UsageEnvironment&, int, char const*, unsigned short)'
demux_rtp.cpp:(.text+0xb7c): undefined reference to `RTSPClient::describeWithPassword(char const*, char const*, char const*, unsigned char, int)'
demux_rtp.cpp:(.text+0xbf8): undefined reference to `SIPClient::createNew(UsageEnvironment&, unsigned char, char const*, int, char const*)'
demux_rtp.cpp:(.text+0xc42): undefined reference to `SIPClient::inviteWithPassword(char const*, char const*, char const*)'
demux_rtp.cpp:(.text+0xcc2): undefined reference to `RTSPClient::describeURL(char const*, Authenticator*, unsigned char, int)'
demux_rtp.cpp:(.text+0xce5): undefined reference to `SIPClient::invite(char const*, Authenticator*)'
demux_rtp.cpp:(.text+0xd16): undefined reference to `MediaSubsessionIterator::~MediaSubsessionIterator()'
libmpdemux/demux_rtp.o: In function `getBuffer(demuxer*, demux_stream_t*, unsigned char, float&)':
demux_rtp.cpp:(.text+0x1666): undefined reference to `FramedSource::getNextFrame(unsigned char*, unsigned int, void (*)(void*, unsigned int, unsigned int, timeval, unsigned int), void*, void (*)(void*), void*)'
demux_rtp.cpp:(.text+0x1917): undefined reference to `FramedSource::getNextFrame(unsigned char*, unsigned int, void (*)(void*, unsigned int, unsigned int, timeval, unsigned int), void*, void (*)(void*), void*)'
libmpdemux/demux_rtp.o: In function `ReadBufferQueue::~ReadBufferQueue()':
demux_rtp.cpp:(.text+0x112b): undefined reference to `operator delete(void*)'
libmpdemux/demux_rtp.o: In function `_GLOBAL__sub_I_rtsp_transport_tcp':
demux_rtp.cpp:(.text.startup+0x7): undefined reference to `DELAY_SECOND'
demux_rtp.cpp:(.text.startup+0x1b): undefined reference to `operator*(short, DelayInterval const&)'
demux_rtp.cpp:(.text.startup+0x3a): undefined reference to `operator*(short, DelayInterval const&)'
demux_rtp.cpp:(.text.startup+0x59): undefined reference to `operator*(short, DelayInterval const&)'
libmpdemux/demux_rtp.o:(.rodata._ZTI15ReadBufferQueue[typeinfo for ReadBufferQueue]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
libmpdemux/demux_rtp.o:(.eh_frame+0xf3): undefined reference to `__gxx_personality_v0'
libmpdemux/demux_rtp_codec.o: In function `rtpCodecInitialize_video(demuxer*, MediaSubsession*, unsigned int&)':
demux_rtp_codec.cpp:(.text+0x61b): undefined reference to `operator new[](unsigned int)'
demux_rtp_codec.cpp:(.text+0x6f9): undefined reference to `operator delete[](void*)'
demux_rtp_codec.cpp:(.text+0x7a4): undefined reference to `parseGeneralConfigStr(char const*, unsigned int&)'
libmpdemux/demux_rtp_codec.o: In function `rtpCodecInitialize_audio(demuxer*, MediaSubsession*, unsigned int&)':
demux_rtp_codec.cpp:(.text+0xe77): undefined reference to `parseStreamMuxConfigStr(char const*, unsigned int&)'
demux_rtp_codec.cpp:(.text+0xe99): undefined reference to `MPEG4LATMAudioRTPSource::omitLATMDataLengthField()'
demux_rtp_codec.cpp:(.text+0xec0): undefined reference to `parseGeneralConfigStr(char const*, unsigned int&)'
collect2: ld returned 1 exit status
make: *** [mplayer] 错误 1
--disable-live
wget http://live555sourcecontrol.googlecode.com/files/live.2011.12.23.tar.gz
如果你用的是最新的live555,你在配置MPlayer的时候,在./config 后加上--disable-live,也可以换成其他的旧版本的live,如:
http://live555sourcecontrol.googlecode.com/files/live.2011.12.23.tar.gz
但是这个又有个问题出来了,把参数改成--disable-live后,在编译MPlayer的时候,它就不会把live555的支持加入里面了,也就是说,编译出来的MPlayer还是不支持RTSP媒体流的播放,所以这个方法不行。
还有的是这样解释的,live555服务器是用C++写的,而MPlayer是用C写的,我们在编译到最后的时候,也就是出现 ”gcc -o mplayer ...... (后面的省略,如果你的出现错误,你会看到的,嘎嘎)“。我们把用C++写的文件包含到C写的Mplayer里,然后用gcc去编译,它是无法识别的,所以会出现那样的错误,网友提供的方法是把”gcc -o mplayer ...... ”这段编译代码复制下来,把gcc换成g++ 重新编译,可惜的是我这样试了,可是还是不行,搞得头都大了,现在把问题贴出来,求大神指教啊!!!