首页 > 编程语言 >LIVE555再学习 -- testH264VideoStreamer 源码分析

LIVE555再学习 -- testH264VideoStreamer 源码分析

时间:2023-04-03 20:06:21浏览次数:50  
标签:LIVE555 rtspServer -- sms inputFileName char 源码 env


上一篇文章我们已经讲了一部分:

testH264VideoStreamer 重复从 H.264 基本流视频文件(名为“test.264”)中读取,并使用 RTP 多播进行流式传输。 该程序还具有内置的 RTSP 服务器。
Apple 的“QuickTime 播放器”可用于接收和播放此音频流。 要使用它,让玩家打开会话的“rtsp://”URL(程序在开始流式传输时打印出来)。
开源“VLC”和“MPlayer”媒体播放器也可以使用。

因为都有英文注释的,所以源码分析也简单

一、源码分析

首先我要说明一下,testH264VideoStreamer 我执行了完,然后一直不出现视频

LIVE555再学习 -- testH264VideoStreamer 源码分析_单播


尝试了好几个版本的live555,但是都不成功,很影响心情啊。然后看到一篇文章。

参看:live555编译、播放示例

这里的源码我试了一下,人家的是可以的,好伤心。为什么呢?先看一下它的源码,讲解的很明白了。

/** 
本程序同时提供单播、组播功能。基于testH264VideoStreamer程序修改,另参考testOnDemandRTSPServer。 
注: 
单播:重开VLC连接,会重新读文件。无马赛克 
组播:重开VLC连接,会继续上一次的位置往下读文件。每次连接时,出现马赛克,VLC出现: 
      main error: pictures leaked, trying to workaround 
 
*/  
#include <liveMedia.hh>  
#include <BasicUsageEnvironment.hh>  
#include <GroupsockHelper.hh>  
  
UsageEnvironment* env;  
char inputFileName[128] = {0};  // 输入的视频文件  
H264VideoStreamFramer* videoSource;  
RTPSink* videoSink;  
  
Boolean reuseFirstSource = False;  
  
void play(); // forward  
  
void announceStream(RTSPServer* rtspServer, ServerMediaSession* sms,  
               char const* streamName, char const* inputFileName);  
  
int main(int argc, char** argv) {  
  strcpy(inputFileName, "test.264"); // 默认值  
  if (argc == 2) {  
    strcpy(inputFileName, argv[1]);  
  }  
  printf("Using file: %s\n", inputFileName);  
    
  // Begin by setting up our usage environment:  
  TaskScheduler* scheduler = BasicTaskScheduler::createNew();  
  env = BasicUsageEnvironment::createNew(*scheduler);  
  
  // 描述信息  
  char const* descriptionString  
    = "Session streamed by \"testH264VideoStreamer\"";  
  
  // RTSP服务器,端口为8554  
  RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554);  
  if (rtspServer == NULL) {  
    *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";  
    exit(1);  
  }  
  
  // 组播  
  // Create 'groupsocks' for RTP and RTCP:  
  struct in_addr destinationAddress;  
  destinationAddress.s_addr = chooseRandomIPv4SSMAddress(*env);  
  
  const unsigned short rtpPortNum = 18888;  
  const unsigned short rtcpPortNum = rtpPortNum+1;  
  const unsigned char ttl = 255;  
  
  const Port rtpPort(rtpPortNum);  
  const Port rtcpPort(rtcpPortNum);  
  
  Groupsock rtpGroupsock(*env, destinationAddress, rtpPort, ttl);  
  rtpGroupsock.multicastSendOnly(); // we're a SSM source  
  Groupsock rtcpGroupsock(*env, destinationAddress, rtcpPort, ttl);  
  rtcpGroupsock.multicastSendOnly(); // we're a SSM source  
  
  // Create a 'H264 Video RTP' sink from the RTP 'groupsock':  
  OutPacketBuffer::maxSize = 200000;  
  videoSink = H264VideoRTPSink::createNew(*env, &rtpGroupsock, 96);  
  
  // Create (and start) a 'RTCP instance' for this RTP sink:  
  const unsigned estimatedSessionBandwidth = 500; // in kbps; for RTCP b/w share  
  const unsigned maxCNAMElen = 100;  
  unsigned char CNAME[maxCNAMElen+1];  
  gethostname((char*)CNAME, maxCNAMElen);  
  CNAME[maxCNAMElen] = '\0'; // just in case  
  RTCPInstance* rtcp  
  = RTCPInstance::createNew(*env, &rtcpGroupsock,  
                estimatedSessionBandwidth, CNAME,  
                videoSink, NULL /* we're a server */,  
                True /* we're a SSM source */);  
  // Note: This starts RTCP running automatically  
  
  char const* streamName = "h264ESVideoMulticast";  
  ServerMediaSession* sms  
    = ServerMediaSession::createNew(*env, streamName, inputFileName,  
           descriptionString, True /*SSM*/);  
  sms->addSubsession(PassiveServerMediaSubsession::createNew(*videoSink, rtcp));  
  rtspServer->addServerMediaSession(sms);  
  
  announceStream(rtspServer, sms, streamName, inputFileName);  
  
  // Start the streaming:  
  *env << "Beginning streaming...\n";  
  play(); // 播放  
  
    
  
  // 单播  
  {  
    char const* streamName = "h264ESVideo";  
    ServerMediaSession* sms  
      = ServerMediaSession::createNew(*env, streamName, streamName,  
                      descriptionString);  
    sms->addSubsession(H264VideoFileServerMediaSubsession  
               ::createNew(*env, inputFileName, reuseFirstSource));  
    rtspServer->addServerMediaSession(sms);  
  
    announceStream(rtspServer, sms, streamName, inputFileName);  
  }  
  
  env->taskScheduler().doEventLoop(); // does not return  
  
  return 0; // only to prevent compiler warning  
}  
  
// 继续读取文件  
void afterPlaying(void* /*clientData*/) {  
  *env << "...done reading from file\n";  
  videoSink->stopPlaying();  
  Medium::close(videoSource);  
  // Note that this also closes the input file that this source read from.  
  
  // Start playing once again:  
  play();  
}  
  
void play() {  
  // Open the input file as a 'byte-stream file source':  
  ByteStreamFileSource* fileSource  
    = ByteStreamFileSource::createNew(*env, inputFileName);  
  if (fileSource == NULL) {  
    *env << "Unable to open file \"" << inputFileName  
         << "\" as a byte-stream file source\n";  
    exit(1);  
  }  
  
  FramedSource* videoES = fileSource;  
  
  // Create a framer for the Video Elementary Stream:  
  videoSource = H264VideoStreamFramer::createNew(*env, videoES);  
  
  // Finally, start playing:  
  *env << "Beginning to read from file...\n";  
  videoSink->startPlaying(*videoSource, afterPlaying, videoSink);  
}  
  
void announceStream(RTSPServer* rtspServer, ServerMediaSession* sms,  
               char const* streamName, char const* inputFileName) {  
  char* url = rtspServer->rtspURL(sms);  
  UsageEnvironment& env = rtspServer->envir();  
  env << "\n\"" << streamName << "\" stream, from the file \""  
      << inputFileName << "\"\n";  
  env << "Play this stream using the URL \"" << url << "\"\n";  
  delete[] url;  
}

二、概念介绍

然后,源码里有这样一段说明:

// Note: This is a multicast address.  If you wish instead to stream
// using unicast, then you should use the "testOnDemandRTSPServer"
// test program - not this test program - as a model.

翻译一下:

注意:这是多播地址。 如果你想改为流
使用单播,那么你应该使用“testOnDemandRTSPServer”
测试程序 - 不是这个测试程序 - 只是一个模型。

他这里出现了单播和多播的概念?我之前还查考过还有直播和点播,这些都要什么区别?

参看:LIVE555再学习 -- 单播、多播、广播、直播、点播 都是个啥?

三、实例

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

该代码中,指定了多播IP地址和端口号。


标签:LIVE555,rtspServer,--,sms,inputFileName,char,源码,env
From: https://blog.51cto.com/u_15979522/6167164

相关文章

  • LIVE555再学习 -- testRTSPClient 源码分析
    现在开讲 testRTSPClient。在官网这这样一段介绍,参看:RTSPclient翻译下来就是:testRTSPClient是一个命令行程序,显示如何打开和接收由RTSPURL指定的媒体流,即以rtsp://开头的URL在这个演示应用中,接收到的音频/视频数据什么也没有。但是,您可以在自己的应用程序中使用和调整此代码(......
  • LIVE555再学习 -- Windows 下编译
    然后开始下载编译,其中包含,Windows、Linux和交叉编译三种形式。首先来讲Windows下编译参看:Live555研究之一源代码编译一、下载源码下载:Indexof/liveMedia/public参看:LIVE555StreamingMedia选择下载live555-latest.tar.gz二、文件介绍我的开发环境为win1064位+VS2017将上面......
  • RTSP再学习 -- RTSP协议分析(转载)
    最近一直在看RTSP,但是RTSP协议是个啥?还没有搞清楚。首先流媒体百度百科上有这样一段,从基本的名字上或多或少可以理解一下这些传输协议的区别。这很重要!!传输协议1、RSVP:资源预留协议2、RTP:实时传输协议3、RTCP:实时传输控制协议4、MMS:微软流媒体服务协议5、RTSP:实时流传输协议6、MIM......
  • mysql多实例配置
    实现在一台服务器上开两个数据库服务。配置:[mysqld_multi]user=rootmysqld=/usr/local/mysql/bin/mysqld_safemysqladmin=/usr/local/mysql/bin/mysqladmin[mysqld1]datadir=/dir1port=3307pid-file=/dir1/mysqld1.pidlog-error=/dir1/mysqld1.errsocket=/dir1/mysqld1.sock[mysqld......
  • MQTT再学习 -- 安装MQTT客户端及测试
    上一篇文章我们已经讲了MQTT服务器的搭建,参看:MQTT再学习--搭建MQTT服务器及测试接下来我们看一下MQTT客户端。一、客户端下载首先,客户端也有多种,我们需要面临选择了。参看:基于mqtt的消息推送(三)客户端实现现有客户端sdk分析,基本分为两大类:一类移植自C类库,如Mosquitto,一类是用o......
  • FFmpeg再学习 -- FFmpeg+SDL+MFC实现图形界面视频播放器
    继续看雷霄骅的课程资料-基于FFmpeg+SDL的视频播放器的制作最后一篇,主要是想学一下MFC创建和配置。一、创建MFC工程文件->新建->项目->VisualC++->MFC应用程序应用程序类型,选择基于对话框生成效果如下:二、设置控件找到“工具箱”,就可以将相应的控件拖拽至应用程序对话框......
  • 图像和流媒体 -- Sapera 安装遇到的问题
    一、下载安装包参看:GenieNanoM1930-NIR点击软件及例程下载二、安装遇到的问题(1)Installationdirectorymustbeonalocalharddrive解决方法:clsicacls%temp%/reset/T/Q/Cpause以上文件复制到txt中将后缀名修改为bat以管理员执行即可。windows自身权限的的问题。(2)安......
  • Problem B. Harvest of Apples 组合数求和(莫队没怎么看懂)
    ProblemB.HarvestofApplesTimeLimit:4000/2000MS(Java/Others)    MemoryLimit:262144/262144K(Java/Others)TotalSubmission(s):3775    AcceptedSubmission(s):1450 ProblemDescriptionTherearenapplesonatree,numberedfrom1ton.Count......
  • MQTT再学习 -- 漫谈MQTT协议
    MQTT服务器搭建我们已经完成了,现在回过头来看协议。参看:MQTT官网参看:MQTT_V3.1_Protocol_Specific参看:MQTT协议中文版参看:MQTT协议中文版上面这几篇文章,已经说明了一切。下面着重讲一下MQTT的消息格式和主要特征。一、什么是MQTT首先你要知道什么是MQTT。额,这个很重要。官网是......
  • 日常生活小技巧 -- 惠普 Windows10 进入安全模式
    今天手贱,是真的很贱。将用户模式从管理员组改为标准用户方法是:WIN+R打开controluserpasswords2然后出现了用户账户控制,你要允许此应用对你的设备进行更改吗?最关键的是没有“是”选项。试了各种方法都不成功。比如网上说的进入命令提示符(管理员)或者更改用户账户控制设置,都会弹出......