转:使用Live555类库实现的网络直播系统

Live555主要有四个类库:

libUsageEnvironment.lib;libliveMedia.lib;libgroupsock.lib;libBasicUsageEnvironment.lib

将这四个类库以及相关的头文件导入VC++2010之后,可以轻松实现网络直播系统。

在这里直接贴上完整代码,粘贴到VC里面就可以运行。

注:程序运行后,使用播放器软件(VLC Media Player,FFplay等),打开URL:rtp://239.255.42.42:1234,即可收看直播的视频。

[cpp] view plaincopy

  1. // 网络直播系统.cpp : 定义控制台应用程序的入口点。
  2. // 雷霄骅
  3. // 中国传媒大学/数字电视技术
  4. // [email protected]
  5. #include "stdafx.h"
  6. #include "liveMedia.hh"
  7. #include "BasicUsageEnvironment.hh"
  8. #include "GroupsockHelper.hh"
  9. //#define IMPLEMENT_RTSP_SERVER
  10. //#define USE_SSM 1
  11. #ifdef USE_SSM
  12. Boolean const isSSM = True;
  13. #else
  14. Boolean const isSSM = False;
  15. #endif
  16. #define TRANSPORT_PACKET_SIZE 188
  17. #define TRANSPORT_PACKETS_PER_NETWORK_PACKET 7
  18. UsageEnvironment* env;
  19. char const* inputFileName = "test.ts";
  20. FramedSource* videoSource;
  21. RTPSink* videoSink;
  22. void play(); // forward
  23. int main(int argc, char** argv) {
  24. // 首先建立使用环境:
  25. TaskScheduler* scheduler = BasicTaskScheduler::createNew();
  26. env = BasicUsageEnvironment::createNew(*scheduler);
  27. // 创建 ‘groupsocks‘ for RTP and RTCP:
  28. char const* destinationAddressStr
  29. #ifdef USE_SSM
  30. = "232.255.42.42";
  31. #else
  32. = "239.255.42.42";
  33. // Note: 这是一个多播地址。如果你希望流使用单播地址,然后替换这个字符串与单播地址
  34. #endif
  35. const unsigned short rtpPortNum = 1234;
  36. const unsigned short rtcpPortNum = rtpPortNum+1;
  37. const unsigned char ttl = 7; //
  38. struct in_addr destinationAddress;
  39. destinationAddress.s_addr = our_inet_addr(destinationAddressStr);
  40. const Port rtpPort(rtpPortNum);
  41. const Port rtcpPort(rtcpPortNum);
  42. Groupsock rtpGroupsock(*env, destinationAddress, rtpPort, ttl);
  43. Groupsock rtcpGroupsock(*env, destinationAddress, rtcpPort, ttl);
  44. #ifdef USE_SSM
  45. rtpGroupsock.multicastSendOnly();
  46. rtcpGroupsock.multicastSendOnly();
  47. #endif
  48. // 创建一个适当的“RTPSink”:
  49. videoSink =
  50. SimpleRTPSink::createNew(*env, &rtpGroupsock, 33, 90000, "video", "mp2t",
  51. 1, True, False /*no ‘M‘ bit*/);
  52. const unsigned estimatedSessionBandwidth = 5000; // in kbps; for RTCP b/w share
  53. const unsigned maxCNAMElen = 100;
  54. unsigned char CNAME[maxCNAMElen+1];
  55. gethostname((char*)CNAME, maxCNAMElen);
  56. CNAME[maxCNAMElen] = ‘\0‘;
  57. #ifdef IMPLEMENT_RTSP_SERVER
  58. RTCPInstance* rtcp =
  59. #endif
  60. RTCPInstance::createNew(*env, &rtcpGroupsock,
  61. estimatedSessionBandwidth, CNAME,
  62. videoSink, NULL /* we‘re a server */, isSSM);
  63. // 开始自动运行的媒体
  64. #ifdef IMPLEMENT_RTSP_SERVER
  65. RTSPServer* rtspServer = RTSPServer::createNew(*env);
  66. if (rtspServer == NULL) {
  67. *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
  68. exit(1);
  69. }
  70. ServerMediaSession* sms
  71. = ServerMediaSession::createNew(*env, "testStream", inputFileName,
  72. "Session streamed by \"testMPEG2TransportStreamer\"",
  73. isSSM);
  74. sms->addSubsession(PassiveServerMediaSubsession::createNew(*videoSink, rtcp));
  75. rtspServer->addServerMediaSession(sms);
  76. char* url = rtspServer->rtspURL(sms);
  77. *env << "Play this stream using the URL \"" << url << "\"\n";
  78. delete[] url;
  79. #endif
  80. *env << "开始发送流媒体...\n";
  81. play();
  82. env->taskScheduler().doEventLoop();
  83. return 0; // 只是为了防止编译器警告
  84. }
  85. void afterPlaying(void* /*clientData*/) {
  86. *env << "...从文件中读取完毕\n";
  87. Medium::close(videoSource);
  88. // 将关闭从源读取的输入文件
  89. play();
  90. }
  91. void play() {
  92. unsigned const inputDataChunkSize
  93. = TRANSPORT_PACKETS_PER_NETWORK_PACKET*TRANSPORT_PACKET_SIZE;
  94. // 打开输入文件作为一个“ByteStreamFileSource":
  95. ByteStreamFileSource* fileSource
  96. = ByteStreamFileSource::createNew(*env, inputFileName, inputDataChunkSize);
  97. if (fileSource == NULL) {
  98. *env << "无法打开文件 \"" << inputFileName
  99. << "\" 作为 file source\n";
  100. exit(1);
  101. }
  102. videoSource = MPEG2TransportStreamFramer::createNew(*env, fileSource);
  103. *env << "Beginning to read from file...\n";
  104. videoSink->startPlaying(*videoSource, afterPlaying, videoSink);
  105. }

[cpp] view plaincopy

  1. // 网络直播系统.cpp : 定义控制台应用程序的入口点。
  2. // 雷霄骅
  3. // 中国传媒大学/数字电视技术
  4. // [email protected]
  5. #include "stdafx.h"
  6. #include "liveMedia.hh"
  7. #include "BasicUsageEnvironment.hh"
  8. #include "GroupsockHelper.hh"
  9. //#define IMPLEMENT_RTSP_SERVER
  10. //#define USE_SSM 1
  11. #ifdef USE_SSM
  12. Boolean const isSSM = True;
  13. #else
  14. Boolean const isSSM = False;
  15. #endif
  16. #define TRANSPORT_PACKET_SIZE 188
  17. #define TRANSPORT_PACKETS_PER_NETWORK_PACKET 7
  18. UsageEnvironment* env;
  19. char const* inputFileName = "test.ts";
  20. FramedSource* videoSource;
  21. RTPSink* videoSink;
  22. void play(); // forward
  23. int main(int argc, char** argv) {
  24. // 首先建立使用环境:
  25. TaskScheduler* scheduler = BasicTaskScheduler::createNew();
  26. env = BasicUsageEnvironment::createNew(*scheduler);
  27. // 创建 ‘groupsocks‘ for RTP and RTCP:
  28. char const* destinationAddressStr
  29. #ifdef USE_SSM
  30. = "232.255.42.42";
  31. #else
  32. = "239.255.42.42";
  33. // Note: 这是一个多播地址。如果你希望流使用单播地址,然后替换这个字符串与单播地址
  34. #endif
  35. const unsigned short rtpPortNum = 1234;
  36. const unsigned short rtcpPortNum = rtpPortNum+1;
  37. const unsigned char ttl = 7; //
  38. struct in_addr destinationAddress;
  39. destinationAddress.s_addr = our_inet_addr(destinationAddressStr);
  40. const Port rtpPort(rtpPortNum);
  41. const Port rtcpPort(rtcpPortNum);
  42. Groupsock rtpGroupsock(*env, destinationAddress, rtpPort, ttl);
  43. Groupsock rtcpGroupsock(*env, destinationAddress, rtcpPort, ttl);
  44. #ifdef USE_SSM
  45. rtpGroupsock.multicastSendOnly();
  46. rtcpGroupsock.multicastSendOnly();
  47. #endif
  48. // 创建一个适当的“RTPSink”:
  49. videoSink =
  50. SimpleRTPSink::createNew(*env, &rtpGroupsock, 33, 90000, "video", "mp2t",
  51. 1, True, False /*no ‘M‘ bit*/);
  52. const unsigned estimatedSessionBandwidth = 5000; // in kbps; for RTCP b/w share
  53. const unsigned maxCNAMElen = 100;
  54. unsigned char CNAME[maxCNAMElen+1];
  55. gethostname((char*)CNAME, maxCNAMElen);
  56. CNAME[maxCNAMElen] = ‘\0‘;
  57. #ifdef IMPLEMENT_RTSP_SERVER
  58. RTCPInstance* rtcp =
  59. #endif
  60. RTCPInstance::createNew(*env, &rtcpGroupsock,
  61. estimatedSessionBandwidth, CNAME,
  62. videoSink, NULL /* we‘re a server */, isSSM);
  63. // 开始自动运行的媒体
  64. #ifdef IMPLEMENT_RTSP_SERVER
  65. RTSPServer* rtspServer = RTSPServer::createNew(*env);
  66. if (rtspServer == NULL) {
  67. *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
  68. exit(1);
  69. }
  70. ServerMediaSession* sms
  71. = ServerMediaSession::createNew(*env, "testStream", inputFileName,
  72. "Session streamed by \"testMPEG2TransportStreamer\"",
  73. isSSM);
  74. sms->addSubsession(PassiveServerMediaSubsession::createNew(*videoSink, rtcp));
  75. rtspServer->addServerMediaSession(sms);
  76. char* url = rtspServer->rtspURL(sms);
  77. *env << "Play this stream using the URL \"" << url << "\"\n";
  78. delete[] url;
  79. #endif
  80. *env << "开始发送流媒体...\n";
  81. play();
  82. env->taskScheduler().doEventLoop();
  83. return 0; // 只是为了防止编译器警告
  84. }
  85. void afterPlaying(void* /*clientData*/) {
  86. *env << "...从文件中读取完毕\n";
  87. Medium::close(videoSource);
  88. // 将关闭从源读取的输入文件
  89. play();
  90. }
  91. void play() {
  92. unsigned const inputDataChunkSize
  93. = TRANSPORT_PACKETS_PER_NETWORK_PACKET*TRANSPORT_PACKET_SIZE;
  94. // 打开输入文件作为一个“ByteStreamFileSource":
  95. ByteStreamFileSource* fileSource
  96. = ByteStreamFileSource::createNew(*env, inputFileName, inputDataChunkSize);
  97. if (fileSource == NULL) {
  98. *env << "无法打开文件 \"" << inputFileName
  99. << "\" 作为 file source\n";
  100. exit(1);
  101. }
  102. videoSource = MPEG2TransportStreamFramer::createNew(*env, fileSource);
  103. *env << "Beginning to read from file...\n";
  104. videoSink->startPlaying(*videoSource, afterPlaying, videoSink);
  105. }

完整工程下载地址:http://download.csdn.net/detail/leixiaohua1020/6272839

[cpp] view plaincopy

  1. <pre code_snippet_id="149063" snippet_file_name="blog_20140109_2_4549023"></pre>
  2. <pre></pre>
  3. <pre></pre>

[cpp] view plaincopy

  1. <pre code_snippet_id="149063" snippet_file_name="blog_20140109_2_4549023"></pre>
  2. <pre></pre>
时间: 2024-10-16 18:39:07

转:使用Live555类库实现的网络直播系统的相关文章

洋铭 NVS-25 网络编码器推送RTMP直播流至流媒体系统进行网络直播

"三网融合"已成趋势. 网络电视直播在广电业大力鼓起,各广电媒体.新闻媒体都逐渐开始树立自个的网络电视直播体系.那么如何搭建网络电视台呢? 今天给大家介绍通过洋铭 NVS-25 网络编码器采集电视信号推送标准的RTMP流到流媒体服务器直播系统进行网络分发. 1.  确认电视设备输出接口 ü  HDMI或SDI输出 ü  网络直播流输出 2.  确认洋铭 NVS-25 网络编码器输出形式 NVS-25 为 Datavideo 设计的小尺寸网络直播编码器 , Plug&Play产品

使用广播级别的Matrox Monarch HD硬件编码如何进行网络直播

加拿大硬件编码器品牌MATROX主要提供互联网视频解决方案中直播和录制产品.MATROX 公司是加拿大为广播电视和互联网视频提供硬件和软件的供应商,为互联网行业研发的Monarch HD和Monarch HDX 非常适用于互联网视频.教育.医疗手术.法院庭审和宗教活动等直播和录制应用. 配合国内专业的流媒体服务器系统形成完整的网络直播系统解决方案.无论是用作直播流媒体编码器还是视频录制设备,Monarch HDX都可以无缝地集成到几乎任何标清和高清系统中. Matrox Monarch HD是一

如何推送RTMP直播流至流媒体系统进行网络直播

"三网融合"已成趋势. 网络电视直播在广电业大力鼓起,各广电媒体.新闻媒体都逐渐开始树立自个的网络电视直播体系.那么如何搭建网络电视台呢? 今天给大家介绍通过洋铭 NVS-25 网络编码器采集电视信号推送标准的RTMP流到流媒体服务器直播系统进行网络分发. 1. 确认电视设备输出接口 ü HDMI或SDI输出 ü 网络直播流输出 2. 确认洋铭 NVS-25 网络编码器输出形式 NVS-25 为 Datavideo 设计的小尺寸网络直播编码器 , Plug&Play产品概念使操

直播系统推拉流端技术

想要搭建网络视频直播系统就要明白视频直播的过程是什么样的,而直播流程可以分为采集.前处理.压缩编码.推流.拉流.解码.渲染播放这几个环节,其中涉及到推流端.拉流端和服务器三端的知识点,服务器方面的知识点很多,拓幻科技这里先简单说下推流端和拉流端的一些知识点,服务器方面可以先看我以前写的文章. 一. 推流端的四个环节1. 首先是采集环节:采集是指对图像和声音的采集,简单说就是能让网络视频直播系统和主播摄像头连起来,软件能获取到外界的音视频信息.然后是前处理阶段:这里也是俗称美颜的阶段,这要求我们在

直播APP源码搭建简易直播平台及个人开发直播系统的难点

如何用直播APP源码搭建一个简易的直播平台 一.前端推流1.推流可以采用命令: ffmpeg -i input -vcodec copy -acodec copy -f flv rtmp://127.0.0.1/live/cgstream0input 可以是实时流,也可以是文件,如果是文件 需要加上-re.运用中需要将127.0.0.1换成rtmp所在机器的ip地址. 用命令推流时间戳信息不能任意修改,想要达到一个满意的结果还是要用代码实现. 主要方法代码如下: 1.打开视频流,filename

互联网影音Steam流式传输-网络直播点播

什么是stream流式传输 流式传输定义很广泛,现在主要指通过网络传送流媒体(如视频.音频)的技术总称.其特定含义为通过Internet 将影视节目传送到PC机,移动端Pad,安卓手机,苹果手机及网络机顶盒(OTT-TV或IPTV的具体应用). 我们也常见一个词"串流",也就是流式传输的一种形象说法.就是指一连串的影像资料压缩后,经过网络分析分段传送资料,在网络上即时传输影音以供观赏的一种技术和过程:串流传输可传送现场live影音或预存与服务器上的影片,当观看者在收看这些影音档时,影音

Android仿网络直播弹幕功能的实现

现在网络直播越来越火,网络主播也逐渐成为一种新兴职业,对于网络直播,弹幕功能是必须要有的,如下图: 首先来分析一下,这个弹幕功能是怎么实现的,首先在最下面肯定是一个游戏界面View,然后游戏界面上有弹幕View,弹幕的View必须要做成完全透明的,这样即使覆盖在游戏界面的上方也不会影响到游戏的正常观看,只有当有人发弹幕消息时,再将消息绘制到弹幕的View上面就可以了,下方肯定还有有操作界面View,可以让用户来发弹幕和送礼物的功能,原理示意图如下所示: 参照原理图,下面一步一步来实现这个功能.

golang ffmpeg 做网络直播

最近在公司做在线视频转码的工作,研究了下ffmpeg 最后直接研究了下网络直播,我是在我自己的mac 上面测试的,效果,还可以,先看看效果图吧 ffmpeg 我是通过brew安装 的,这步就略了 VLC这个播放器怎么安装的也略了 我先是在github上面找了一个开源的直播流工具 https://github.com/gwuhaolin/livego 然后把它run 起来,最后看几个直播流参数吧: 桌面成功: ffmpeg -f avfoundation -pixel_format uyvy422

岂能止步于网红 网络直播探索内容创业的正确姿势有多难?

如果要评今年最火爆的社会现象,网络直播应该算作一个.花椒直播.斗鱼直播.虎牙直播.一直播等众多直播平台迅速走进网友的生活,网红.网络主播等成为热词.但是网络直播在制造热门话题吸引眼球之时也面临着诸多问题,如内容有待创新.行业急需规范等,要想从激烈的竞争中脱颖而出走向更远,网络直播平台已经不能只靠网红了. 文/张书乐 刊载于<中国文化报>2016年11月16日网络文化版,刊载时有删节 刚从湖南某高校毕业,就奔赴国外独自旅拍的王欢最近开始尝试直播创业每天用一个小时的时间,把自己的"世界真