最近被安排搞onvif,onvif的视频传输,就是使用live555做服务器,使用其提供的URL。所以live555也得去了解学习。本文简单介绍live555的编译,然后在原有例程上给出一个示例。

1、编译

live555官网为http://www.live555.com/,源码下载地址:http://www.live555.com/liveMedia/public/。live555支持很多平台,如mac ox,linux,还有mingw。每种平台都带有配置文件,编译方法也较简单。在mingw环境编译方法如下:

$ ./genMakefiles mingw 
$  export CC=gcc 
$  make

类似地,在linux编译方法如下:
$ ./genMakefiles linux
$ make

编译完成后,testProgs目录会生成很多测试程序,在不修改任何代码情况下,可运行这些程序进行测试。以testH264VideoStreamer为例,将H264视频文件放到该目录,改名为test.264,运行testH264VideoStreamer(在mingw环境编译得到的名称是testH264VideoStreamer.exe)。再在VLC打开网络串流,输入地址rtsp://ip/testStream,如:rtsp://192.168.1.100:8554/testStream。
默认情况,该示例程序就是使用test.264文件。如需要修改播放的文件,则要修改源代码文件testH264VideoStreamer.cpp。如果需要再次编译,直接在testProgs输入make即可。

2、示例

下面在testH264VideoStreamer.cpp工程基础上添加单播功能,该功能模块参考testOnDemandRTSPServer工程。代码如下:
/**
本程序同时提供单播、组播功能。基于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(); // forwardvoid 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服务器,端口为8554RTSPServer* 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 sourceGroupsock 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 shareconst unsigned maxCNAMElen = 100;unsigned char CNAME[maxCNAMElen+1];gethostname((char*)CNAME, maxCNAMElen);CNAME[maxCNAMElen] = '\0'; // just in caseRTCPInstance* rtcp= RTCPInstance::createNew(*env, &rtcpGroupsock,estimatedSessionBandwidth, CNAME,videoSink, NULL /* we're a server */,True /* we're a SSM source */);// Note: This starts RTCP running automaticallychar 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 returnreturn 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;
}
为了便于学习,将live555源码放到github上,地址为https://github.com/latelee/my_live555.git。
李迟2015.12.20 周六 晚

live555编译、播放示例相关推荐

  1. 最简单的视音频播放示例6:OpenGL播放YUV420P(通过Texture,使用Shader)

    ===================================================== 最简单的视音频播放示例系列文章列表: 最简单的视音频播放示例1:总述 最简单的视音频播放示例 ...

  2. 最简单的视音频播放示例5:OpenGL播放RGB/YUV

    ===================================================== 最简单的视音频播放示例系列文章列表: 最简单的视音频播放示例1:总述 最简单的视音频播放示例 ...

  3. 【流媒體】live555—VS2010/VS2013 下live555编译、使用及测试

    [流媒體]live555-VS2010 /VS2013 下live555编译.使用及测试 SkySeraph Apr 11st 2012 Email:skyseraph00@163.com 更多精彩请 ...

  4. 最简单的视音频播放示例7:SDL2播放RGB/YUV

    最简单的视音频播放示例系列文章列表: 最简单的视音频播放示例1:总述 最简单的视音频播放示例2:GDI播放YUV, RGB 最简单的视音频播放示例3:Direct3D播放YUV,RGB(通过Surfa ...

  5. 最简单的视音频播放示例8:DirectSound播放PCM

    ===================================================== 最简单的视音频播放示例系列文章列表: 最简单的视音频播放示例1:总述 最简单的视音频播放示例 ...

  6. 最简单的视音频播放示例2:GDI播放YUV, RGB

    ===================================================== 最简单的视音频播放示例系列文章列表: 最简单的视音频播放示例1:总述 最简单的视音频播放示例 ...

  7. 最简单的视音频播放示例1:总述

    ===================================================== 最简单的视音频播放示例系列文章列表: 最简单的视音频播放示例1:总述 最简单的视音频播放示例 ...

  8. JRtplib开发笔记(二):JRtplib库编译、示例演示

    原博主博客地址:https://blog.csdn.net/qq21497936 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/84 ...

  9. WebRTC音视频采集和播放示例及MediaStream媒体流解析

    WebRTC音视频采集和播放示例及MediaStream媒体流解析 目录 示例代码--同时打开摄像头和麦克风,并在页面显示画面和播放捕获的声音 API解析 mediaDevices MediaStre ...

  10. 最简单的视音频播放示例3 Direct3D播放YUV,RGB(通过Surface)

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! ==== ...

最新文章

  1. Q-learning
  2. WinForm/MIS项目开发之中按钮级权限实践
  3. 如何停止一个正在运行的java线程
  4. git 撤销挂起的更改_Timer计时任务因系统时间的修改导致挂起解决方案
  5. 通过 .NET NativeAOT 实现用户体验升级
  6. avlib java_fatal error: libavutil/avconfig.h: No such file...
  7. 如何使用API提交转码任务?
  8. sql怎么修改服务器角色,sql角色服务器的设置
  9. 乌班图系统修改服务器时间的命令,ubuntu 修改系统时间无效
  10. Numpy系列(五)给数组增加一个维度
  11. python计算器教程vscode_python计算器教程vscode
  12. 二维 稳态边界层问题MATLAB,第三章 边界层理论.ppt
  13. 单片机pwm控制基本原理详解
  14. linux pkg文件,pkg文件结构详细解释(转)
  15. 视频gif如何制作?试试这个视频制作gif神器
  16. The server time zone value xxxxxxx is unrecognized or represents more than one time zone.
  17. 基于SCA(tuscany)的SOA实践之一(发布服务是如此的简单)
  18. 4399手游事业部,诚聘AS开发主程、C++前端开发工程师、erlang后端开发工程师
  19. 功能安全 李艳文_李艳文:智能网联全新安全问题凸显相关自动驾驶事故逐年增加...
  20. sql server(MSSQLSERVER)服务不能启动 解决办法

热门文章

  1. 网易云音乐被纳入港股通 3月7日起生效
  2. 苹果因芯片短缺优先生产iPhone 13 常规iPad平均交付时间超7周
  3. “金嗓子”宣布退市!曾因罗纳尔多代言争议爆红,广告词家喻户晓…
  4. iPhone 12/13正面对比图曝光:祖传大刘海终于有所改变
  5. 苏宁易购回复深交所关注函:深国际和鲲鹏资本非一致行动人
  6. “在格力干到退休,这套房就给你了!”董明珠称将投放3700套人才房…
  7. 英伟达宣布与GSK AI实验室达成合作,研发药物和疫苗
  8. 梅耶·马斯克对话邓文迪 直播首秀将上线今日头条、抖音
  9. 网易云推出“音街”APP 入局免费K歌市场
  10. 华米科技将推出首款真无线耳机 支持降噪还能检测心率?