Live555主要有四個類庫:
libUsageEnvironment.lib;libliveMedia.lib;libgroupsock.lib;libBasicUsageEnvironment.lib
將這四個類庫以及相關的頭文件導入VC++2010之後,可以輕松實現網絡直播系統。
在這裡直接貼上完整代碼,粘貼到VC裡面就可以運行。
注:程序運行後,使用播放器軟件VLC Media Player,FFplay等),打開URL:rtp://239.255.42.42:1234,即可收看直播的視頻。
// 網絡直播系統.cpp : 定義控制台應用程序的入口點。 // 雷霄骅 // 中國傳媒大學/數字電視技術 // [email protected] #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); }
本文出自 “leixiaohua1020視音頻技術” 博客,請務必保留此出處http://leixiaohua1020.blog.51cto.com/3974648/1303876