LIVE555学习4:live555MediaServer讲解——如何根据指定文件后缀创建ServerMediaSession

在前面《LIVE555学习1:Linux下live555的编译及测试》中,当我们运行起可执行程序live555MediaServer,在VLC中输入rtsp://192.168.1.100/Titanic.ts, 便可以播放ts流。当我们输入其他格式,如H264、H265、aac等,均可以输出对应流。但是在主函数中,只创建了一个RTSPServer实例,并没有创建这些对应不同格式文件的ServerMediaSession和ServerMediaSubSession.

上一篇中也大致介绍了RTSP服务运行的整个流程,但是没有对代码进行详细的讲解,所以并不清楚ServerMediaSession是如何创建的,什么时候创建的,如何根据不同的文件格式进行创建不同的对象。。。。

在RTSP会话过程中,再DESCRIBE和SETUP中,会来确定ServerMediaSession是否存在。具体实现在DynamicRTSPServer.cpp中,在函数lookupServerMediaSession中,会进行以下检查:

  • ①检查ServerMediaSession是否存在
  ServerMediaSession* sms = RTSPServer::lookupServerMediaSession(streamName);
  Boolean smsExists = sms != NULL;
  • ②判断文件是否存在,如果文件没了,
    ServerMediaSession有,则删除ServerMediaSession
  if (!fileExists) {
    if (smsExists) {
      // "sms" was created for a file that no longer exists. Remove it:
      removeServerMediaSession(sms);
      sms = NULL;
    }
  • ③最终根据判断结果来决定是否创建
ServerMediaSession
    if (sms == NULL) {
      sms = createNewSMS(envir(), streamName, fid);
      addServerMediaSession(sms);
    }

若是需要创建ServerMediaSession,则会调用createNewSMS,在此函数中,也做了几件事:

  • ①确定文件后缀
  char const* extension = strrchr(fileName, '.');
  if (extension == NULL) return NULL;
  • ②根据文件后缀来创建对应的ServerMediaSession和ServerMediaSubSession
    例如H264:
  }else if (strcmp(extension, ".264") == 0) {
    // Assumed to be a H.264 Video Elementary Stream file:
    NEW_SMS("H.264 Video");
    OutPacketBuffer::maxSize = 100000; // allow for some possibly large H.264 frames
    sms->addSubsession(H264VideoFileServerMediaSubsession::createNew(env, fileName, reuseSource));
}

例如H265:

  } else if (strcmp(extension, ".265") == 0) {
    // Assumed to be a H.265 Video Elementary Stream file:
    NEW_SMS("H.265 Video");
    OutPacketBuffer::maxSize = 100000; // allow for some possibly large H.265 frames
    sms->addSubsession(H265VideoFileServerMediaSubsession::createNew(env, fileName, reuseSource));
}

结束。根据以上的分析可以知道,在程序运行时候,会首先创建一个RTSPServer实例,然后会根据RTSP会话传递过来的文件格式来创建对应的ServerMediaSession和ServerMediaSubSession。

非常抱歉,之前的回答中的代码仍然有错误。以下是经过修正的代码,已经将 ServerMediaSession 的名称修改为 "stream",并将 RTSP URL 改为 `rtsp://127.0.0.1:8554/stream`: ```cpp #include <liveMedia/liveMedia.hh> #include <BasicUsageEnvironment/BasicUsageEnvironment.hh> #include <Groupsock/GroupsockHelper.hh> class VideoSource : public FramedSource { public: static VideoSource* createNew(UsageEnvironment& env) { return new VideoSource(env); } void setVideoData(char* data, unsigned int length) { fFrameSize = length; memcpy(fTo, data, length); fFrameCount++; if (fPresentationTime.tv_sec == 0 && fPresentationTime.tv_usec == 0) { gettimeofday(&fPresentationTime, NULL); } } private: VideoSource(UsageEnvironment& env) : FramedSource(env), fFrameSize(0), fFrameCount(0) { gettimeofday(&fPresentationTime, NULL); } virtual ~VideoSource() {} virtual void doGetNextFrame() { if (fFrameSize > 0) { // 创建一个新的帧 if (fFrameCount > 0) { // 计算下一帧的时间戳 fPresentationTime.tv_usec += 33333; // 每帧33毫秒(30帧每秒) if (fPresentationTime.tv_usec >= 1000000) { fPresentationTime.tv_sec++; fPresentationTime.tv_usec -= 1000000; } } // 发送帧数据给客户端 FramedSource::afterGetting(this); } else { // 数据还未准备好,等待100毫秒后再次尝试获取帧数据 envir().taskScheduler().scheduleDelayedTask(100 * 1000, (TaskFunc*)doGetNextFrame, this); } } virtual void doStopGettingFrames() {} private: unsigned int fFrameSize; unsigned int fFrameCount; }; int main(int argc, char** argv) { // 创建一个 RTSP 服务器环境 TaskScheduler* scheduler = BasicTaskScheduler::createNew(); UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler); RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554); // 创建一个 RTSP 流媒体服务器 ServerMediaSession* sms = ServerMediaSession::createNew(*env, "stream", "Live stream"); // 添加视频源 VideoSource* videoSource = VideoSource::createNew(*env); H264VideoStreamFramer* videoStreamFramer = H264VideoStreamFramer::createNew(*env, videoSource); sms->addSubsession(PassiveServerMediaSubsession::createNew(*videoStreamFramer)); rtspServer->addServerMediaSession(sms); // 启动 RTSP 服务器 env->taskScheduler().doEventLoop(); // 清理资源 Medium::close(rtspServer); env->reclaim(); delete scheduler; return 0; } ``` 非常抱歉之前的错误带来的困扰,感谢您的耐心和理解。如果您还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值