live555音视频同步

本文介绍了如何利用live555的testOnDemandRTSPServer.cpp进行音视频同步,强调了每个源的fPresentationTime值与挂钟时间对齐的重要性。提到了测试时应从同一mp4文件中提取h264和mp3,以确保同步,并提供了已提取文件的链接。此外,还分享了代码修改和Windows下VLC接收rtsp流的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

live555音视频同步

通过testOnDemandRTSPServer.cpp实现,仅需修改部分代码即可,

相关类图

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

具体思路:

流式传输音频+视频很简单:只需调用“addSubsession()”两次 - 一次用于视频源,另一次用于音频源。(这样你的“ServerMediaSession”对象包含两个“ServerMediaSubsession”对象 - 一个用于视频,一个用于音频。)

但是,为了音频/视频同步正常工作,每个源(视频和音频)必须生成正确的“每个帧的“fPresentationTime”值,并且这些“必须”与“挂钟”时间对齐 - 即,与调用“gettimeofday()”时获得的时间相同。

注意

测试用的h264和mp3尽量从同一个mp4上进行提取。以验证同步问题。

提取具体操作:

Mp4文件提取详细H.264和MP3文件_泷fyk的博客-优快云博客

现成的我已提取好的文件:

音视频同步h264-live555(水龙吟)-直播技术文档类资源-优快云文库

音视频同步测试mp3-live555(水龙吟)资源-优快云文库

具体代码(对testOnDemandRTSPServer.cpp进行修改)

#include "liveMedia.hh"

#include "BasicUsageEnvironment.hh"
#include "announceURL.hh"

UsageEnvironment* env;

// To make the second and subsequent client for each stream reuse the same
// input stream as the first client (rather than playing the file from the
// start for each client), change the following "False" to "True":
//单播、组播开关,false为单播,true为组播,单播每个链接接入时都会重新播放,组播的话会随着上一个接入流的位置进行播放
//经过实测,组播模式各链接同步流畅,延迟很小。
Boolean reuseFirstSource = false;

// To stream *only* MPEG-1 or 2 video "I" frames
// (e.g., to reduce network bandwidth),
// change the following "False" to "True":
Boolean iFramesOnly = False;

static void announceStream(RTSPServer* rtspServer, ServerMediaSession* sms,
			   char const* streamName, char const* inputFileName); // forward

int main(int argc, char** argv) {
  // Begin by setting up our usage environment:
  TaskScheduler* scheduler = BasicTaskScheduler::createNew();
  env = BasicUsageEnvironment::createNew(*scheduler);

  UserAuthenticationDatabase* authDB = NULL;
#ifdef ACCESS_CONTROL
  // To implement client access control to the RTSP server, do the following:
  authDB = new UserAuthenticationDatabase;
  authDB->addUserRecord("username1", "password1"); // replace these with real strings
  // Repeat the above with each <username>, <password> that you wish to allow
  // access to the server.
#endif

  // Create the RTSP server:
#ifdef SERVER_USE_TLS
  // Serve RTSPS: RTSP over a TLS connection:
  RTSPServer* rtspServer = RTSPServer::createNew(*env, 322, authDB);
#else
  // Serve regular RTSP (over a TCP connection):
  RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554, authDB);
#endif
  if (rtspServer == NULL) {
    *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
    exit(1);
  }
#ifdef SERVER_USE_TLS
#ifndef STREAM_USING_SRTP
#define STREAM_USING_SRTP True
#endif
  rtspServer->setTLSState(PATHNAME_TO_CERTIFICATE_FILE, PATHNAME_TO_PRIVATE_KEY_FILE,
			  STREAM_USING_SRTP);
#endif

  char const* descriptionString
    = "Session streamed by \"testOnDemandRTSPServer\"";

  // Set up each of the possible streams that can be served by the
  // RTSP server.  Each such stream is implemented using a
  // "ServerMediaSession" object, plus one or more
  // "ServerMediaSubsession" objects for each audio/video substream.

  // A H.264 video elementary stream:
  //在此处进行修改
  {
    //输出文件名称,按需求修改
    char const* streamName = "h264ESVideoTest";
    //h264输入文件所在位置,按实际修改
    char const* inputFileName = "./test/output_video.264";
    //mp3输入文件名称所在位置,按实际修改
    char const* inputFileNameAdus = "./test/output_audio.mp3";
    //创建ServerMediaSession
    //下面这几行定义了两个变量,useADUs 和 interleaving,用于配置MP3音频流的传输方式。useADUs 设置为False 表示不使用ADUs(Audio Data Units),即不进行分组音频数据的传输。interleaving 初始化为NULL,表示不进行数据交错。
    ServerMediaSession* sms
      = ServerMediaSession::createNew(*env, streamName, streamName,
				      descriptionString);
              Boolean useADUs = False;
    Interleaving* interleaving = NULL;
#ifdef STREAM_USING_ADUS
    useADUs = True;
#ifdef INTERLEAVE_ADUS
    unsigned char interleaveCycle[] = {0,2,1,3}; // or choose your own...
    unsigned const interleaveCycleSize
      = (sizeof interleaveCycle)/(sizeof (unsigned char));
    interleaving = new Interleaving(interleaveCycleSize, interleaveCycle);
#endif
#endif
    //添加音频子会话
    sms->addSubsession(MP3AudioFileServerMediaSubsession
		       ::createNew(*env, inputFileNameAdus, reuseFirstSource,
				   useADUs, interleaving));
    //添加视频子会话
    sms->addSubsession(H264VideoFileServerMediaSubsession
		       ::createNew(*env, inputFileName, reuseFirstSource));
    //将创建的ServerMediaSession* sms添加到rtsp服务器。
    rtspServer->addServerMediaSession(sms);
	//
    announceStream(rtspServer, sms, streamName, inputFileName);
  }
	
  env->taskScheduler().doEventLoop(); // does not return

  return 0; // only to prevent compiler warning
}

static void announceStream(RTSPServer* rtspServer, ServerMediaSession* sms,
			   char const* streamName, char const* inputFileName) {
  UsageEnvironment& env = rtspServer->envir();

  env << "\n\"" << streamName << "\" stream, from the file \""
      << inputFileName << "\"\n";
  announceURL(rtspServer, sms);
}

修改之后成功在所在目录下直接分步执行以下命令

make
./testOnDemandRTSPServer

image-20230907163045651

windowsVLC接到rtsp流

image-20230907161902394

image-20230907161654505

点赞收藏加关注,追求技术不迷路!!!欢迎评论区互动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泷fyk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值