Live555主要有四个类库:
libUsageEnvironment.lib;libliveMedia.lib;libgroupsock.lib;libBasicUsageEnvironment.lib
将这四个类库以及相关的头文件导入VC++2010之后,可以轻松实现网络直播系统。
在这里直接贴上完整代码,粘贴到VC里面就可以运行。
注:程序运行后,使用播放器软件(VLC Media Player,FFplay等),打开URL:rtp://239.255.42.42:1234,即可收看直播的视频。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | // 网络直播系统.cpp : 定义控制台应用程序的入口点。 // 雷霄骅 // 中国传媒大学/数字电视技术 // leixiaohua1020@126.com #include "stdafx.h" #include "liveMedia.hh" #include "BasicUsageEnvironment.hh" #include "GroupsockHelper.hh" //#define IMPLEMENT_RTSP_SERVER //#define USE_SSM 1 #ifdef USE_SSM Boolean const isSSM = True; #else Boolean const isSSM = False; #endif #define TRANSPORT_PACKET_SIZE 188 #define TRANSPORT_PACKETS_PER_NETWORK_PACKET 7 UsageEnvironment* env; char const * inputFileName = "test.ts" ; FramedSource* videoSource; RTPSink* videoSink; void play(); // forward int main( int argc, char ** argv) { // 首先建立使用环境: TaskScheduler* scheduler = BasicTaskScheduler::createNew(); env = BasicUsageEnvironment::createNew(*scheduler); // 创建 'groupsocks' for RTP and RTCP: char const * destinationAddressStr #ifdef USE_SSM = "232.255.42.42" ; #else = "239.255.42.42" ; // Note: 这是一个多播地址。如果你希望流使用单播地址,然后替换这个字符串与单播地址 #endif const unsigned short rtpPortNum = 1234; const unsigned short rtcpPortNum = rtpPortNum+1; const unsigned char ttl = 7; // struct in_addr destinationAddress; destinationAddress.s_addr = our_inet_addr(destinationAddressStr); const Port rtpPort(rtpPortNum); const Port rtcpPort(rtcpPortNum); Groupsock rtpGroupsock(*env, destinationAddress, rtpPort, ttl); Groupsock rtcpGroupsock(*env, destinationAddress, rtcpPort, ttl); #ifdef USE_SSM rtpGroupsock.multicastSendOnly(); rtcpGroupsock.multicastSendOnly(); #endif // 创建一个适当的“RTPSink”: videoSink = SimpleRTPSink::createNew(*env, &rtpGroupsock, 33, 90000, "video" , "mp2t" , 1, True, False /*no 'M' bit*/ ); const unsigned estimatedSessionBandwidth = 5000; // in kbps; for RTCP b/w share const unsigned maxCNAMElen = 100; unsigned char CNAME[maxCNAMElen+1]; gethostname(( char *)CNAME, maxCNAMElen); CNAME[maxCNAMElen] = '\0' ; #ifdef IMPLEMENT_RTSP_SERVER RTCPInstance* rtcp = #endif RTCPInstance::createNew(*env, &rtcpGroupsock, estimatedSessionBandwidth, CNAME, videoSink, NULL /* we're a server */ , isSSM); // 开始自动运行的媒体 #ifdef IMPLEMENT_RTSP_SERVER RTSPServer* rtspServer = RTSPServer::createNew(*env); if (rtspServer == NULL) { *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n" ; exit (1); } ServerMediaSession* sms = ServerMediaSession::createNew(*env, "testStream" , inputFileName, "Session streamed by \"testMPEG2TransportStreamer\"" , isSSM); sms->addSubsession(PassiveServerMediaSubsession::createNew(*videoSink, rtcp)); rtspServer->addServerMediaSession(sms); char * url = rtspServer->rtspURL(sms); *env << "Play this stream using the URL \"" << url << "\"\n" ; delete [] url; #endif *env << "开始发送流媒体...\n" ; play(); env->taskScheduler().doEventLoop(); return 0; // 只是为了防止编译器警告 } void afterPlaying( void * /*clientData*/ ) { *env << "...从文件中读取完毕\n" ; Medium::close(videoSource); // 将关闭从源读取的输入文件 play(); } void play() { unsigned const inputDataChunkSize = TRANSPORT_PACKETS_PER_NETWORK_PACKET*TRANSPORT_PACKET_SIZE; // 打开输入文件作为一个“ByteStreamFileSource": ByteStreamFileSource* fileSource = ByteStreamFileSource::createNew(*env, inputFileName, inputDataChunkSize); if (fileSource == NULL) { *env << "无法打开文件 \"" << inputFileName << "\" 作为 file source\n" ; exit (1); } videoSource = MPEG2TransportStreamFramer::createNew(*env, fileSource); *env << "Beginning to read from file...\n" ; videoSink->startPlaying(*videoSource, afterPlaying, videoSink); } |
完整工程下载地址: http://download.csdn.net/detail/leixiaohua1020/6272839
联系客服