live555编译、播放示例
最近被安排搞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程序修改,另参考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编译、播放示例相关推荐
- 最简单的视音频播放示例6:OpenGL播放YUV420P(通过Texture,使用Shader)
===================================================== 最简单的视音频播放示例系列文章列表: 最简单的视音频播放示例1:总述 最简单的视音频播放示例 ...
- 最简单的视音频播放示例5:OpenGL播放RGB/YUV
===================================================== 最简单的视音频播放示例系列文章列表: 最简单的视音频播放示例1:总述 最简单的视音频播放示例 ...
- 【流媒體】live555—VS2010/VS2013 下live555编译、使用及测试
[流媒體]live555-VS2010 /VS2013 下live555编译.使用及测试 SkySeraph Apr 11st 2012 Email:skyseraph00@163.com 更多精彩请 ...
- 最简单的视音频播放示例7:SDL2播放RGB/YUV
最简单的视音频播放示例系列文章列表: 最简单的视音频播放示例1:总述 最简单的视音频播放示例2:GDI播放YUV, RGB 最简单的视音频播放示例3:Direct3D播放YUV,RGB(通过Surfa ...
- 最简单的视音频播放示例8:DirectSound播放PCM
===================================================== 最简单的视音频播放示例系列文章列表: 最简单的视音频播放示例1:总述 最简单的视音频播放示例 ...
- 最简单的视音频播放示例2:GDI播放YUV, RGB
===================================================== 最简单的视音频播放示例系列文章列表: 最简单的视音频播放示例1:总述 最简单的视音频播放示例 ...
- 最简单的视音频播放示例1:总述
===================================================== 最简单的视音频播放示例系列文章列表: 最简单的视音频播放示例1:总述 最简单的视音频播放示例 ...
- JRtplib开发笔记(二):JRtplib库编译、示例演示
原博主博客地址:https://blog.csdn.net/qq21497936 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/84 ...
- WebRTC音视频采集和播放示例及MediaStream媒体流解析
WebRTC音视频采集和播放示例及MediaStream媒体流解析 目录 示例代码--同时打开摄像头和麦克风,并在页面显示画面和播放捕获的声音 API解析 mediaDevices MediaStre ...
- 最简单的视音频播放示例3 Direct3D播放YUV,RGB(通过Surface)
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! ==== ...
最新文章
- Q-learning
- WinForm/MIS项目开发之中按钮级权限实践
- 如何停止一个正在运行的java线程
- git 撤销挂起的更改_Timer计时任务因系统时间的修改导致挂起解决方案
- 通过 .NET NativeAOT 实现用户体验升级
- avlib java_fatal error: libavutil/avconfig.h: No such file...
- 如何使用API提交转码任务?
- sql怎么修改服务器角色,sql角色服务器的设置
- 乌班图系统修改服务器时间的命令,ubuntu 修改系统时间无效
- Numpy系列(五)给数组增加一个维度
- python计算器教程vscode_python计算器教程vscode
- 二维 稳态边界层问题MATLAB,第三章 边界层理论.ppt
- 单片机pwm控制基本原理详解
- linux pkg文件,pkg文件结构详细解释(转)
- 视频gif如何制作?试试这个视频制作gif神器
- The server time zone value xxxxxxx is unrecognized or represents more than one time zone.
- 基于SCA(tuscany)的SOA实践之一(发布服务是如此的简单)
- 4399手游事业部,诚聘AS开发主程、C++前端开发工程师、erlang后端开发工程师
- 功能安全 李艳文_李艳文:智能网联全新安全问题凸显相关自动驾驶事故逐年增加...
- sql server(MSSQLSERVER)服务不能启动 解决办法
热门文章
- 网易云音乐被纳入港股通 3月7日起生效
- 苹果因芯片短缺优先生产iPhone 13 常规iPad平均交付时间超7周
- “金嗓子”宣布退市!曾因罗纳尔多代言争议爆红,广告词家喻户晓…
- iPhone 12/13正面对比图曝光:祖传大刘海终于有所改变
- 苏宁易购回复深交所关注函:深国际和鲲鹏资本非一致行动人
- “在格力干到退休,这套房就给你了!”董明珠称将投放3700套人才房…
- 英伟达宣布与GSK AI实验室达成合作,研发药物和疫苗
- 梅耶·马斯克对话邓文迪 直播首秀将上线今日头条、抖音
- 网易云推出“音街”APP 入局免费K歌市场
- 华米科技将推出首款真无线耳机 支持降噪还能检测心率?