【视频开发】【Live555】摄像头采集,264编码,live555直播(0)
参看 有关live555
1.首先需要修改live555,定义从 内存中直接获取source而不是从文件读取source的类。
自己实现的类命名为 H264FramedLiveSource

/*
* Filename: H264FramedLiveSource.hh
* Auther: chenbin
* Create date: 2013/ 1/22
*/ #ifndef _H264FRAMEDLIVESOURCE_HH
#define _H264FRAMEDLIVESOURCE_HH #include <FramedSource.hh> class H264FramedLiveSource : public FramedSource
{
public:
static H264FramedLiveSource* createNew(UsageEnvironment& env,
char const* fileName,
unsigned preferredFrameSize = 0,
unsigned playTimePerFrame = 0); protected:
H264FramedLiveSource(UsageEnvironment& env,
char const* fileName,
unsigned preferredFrameSize,
unsigned playTimePerFrame);
// called only by createNew()
~H264FramedLiveSource(); private:
// redefined virtual functions:
virtual void doGetNextFrame();
int TransportData( unsigned char* to, unsigned maxSize ); protected:
FILE *fp;
}; #endif


/*
* Filename: H264FramedLiveSource.cpp
* Auther: mlj
* Create date: 2013/ 1/22
*/ #include "H264FramedLiveSource.hh" H264FramedLiveSource::H264FramedLiveSource( UsageEnvironment& env,
char const* fileName,
unsigned preferredFrameSize,
unsigned playTimePerFrame )
: FramedSource(env)
{
fp = fopen( fileName, "rb" );
} H264FramedLiveSource* H264FramedLiveSource::createNew( UsageEnvironment& env,
char const* fileName,
unsigned preferredFrameSize /*= 0*/,
unsigned playTimePerFrame /*= 0*/ )
{
H264FramedLiveSource* newSource = new H264FramedLiveSource(env, fileName, preferredFrameSize, playTimePerFrame); return newSource;
} H264FramedLiveSource::~H264FramedLiveSource()
{
fclose(fp);
} long filesize(FILE *stream)
{
long curpos, length;
curpos = ftell(stream);
fseek(stream, 0L, SEEK_END);
length = ftell(stream);
fseek(stream, curpos, SEEK_SET);
return length;
} void H264FramedLiveSource::doGetNextFrame()
{ if( filesize(fp) > fMaxSize)
fFrameSize = fread(fTo,1,fMaxSize,fp);
else
{
fFrameSize = fread(fTo,1,filesize(fp),fp);
fseek(fp, 0, SEEK_SET);
}
//fFrameSize = fMaxSize;
nextTask() = envir().taskScheduler().scheduleDelayedTask( 0,
(TaskFunc*)FramedSource::afterGetting, this);//表示延迟0秒后再执行 afterGetting 函数
return;
}

在 H264FramedLiveSource::doGetNextFrame() 中,将要发送的内容复制到 fTo,最大为fMaxSize,fFrameSize指示实际发送的内容是多少字节。这里暂时还是从文件读作为测试。
2、定义自己的ServerMedia

/*
* Filename: H264LiveVideoServerMediaSubssion.hh
* Auther: mlj
* Create date: 2013/ 1/22
*/
#ifndef _H264_LIVE_VIDEO_SERVER_MEDIA_SUBSESSION_HH
#define _H264_LIVE_VIDEO_SERVER_MEDIA_SUBSESSION_HH
#include "H264VideoFileServerMediaSubsession.hh" class H264LiveVideoServerMediaSubssion: public H264VideoFileServerMediaSubsession { public:
static H264LiveVideoServerMediaSubssion*
createNew( UsageEnvironment& env,
char const* fileName,
Boolean reuseFirstSource ); protected: // we're a virtual base class
H264LiveVideoServerMediaSubssion( UsageEnvironment& env, char const* fileName, Boolean reuseFirstSource );
~H264LiveVideoServerMediaSubssion(); protected: // redefined virtual functions
FramedSource* createNewStreamSource(unsigned clientSessionId,
unsigned& estBitrate);
public:
char fFileName[100]; }; #endif


/*
* Filename: H264LiveVideoServerMediaSubssion.cpp
* Auther: chenbin
* Create date: 2012/11/29
*/ #include "H264LiveVideoServerMediaSubssion.hh"
#include "H264FramedLiveSource.hh"
#include "H264VideoStreamFramer.hh" H264LiveVideoServerMediaSubssion*
H264LiveVideoServerMediaSubssion::createNew( UsageEnvironment& env,
char const* fileName,
Boolean reuseFirstSource )
{
return new H264LiveVideoServerMediaSubssion( env, fileName, reuseFirstSource );
} H264LiveVideoServerMediaSubssion::H264LiveVideoServerMediaSubssion( UsageEnvironment& env, char const* fileName, Boolean reuseFirstSource )
: H264VideoFileServerMediaSubsession( env, fileName, reuseFirstSource )
{
strcpy(fFileName,fileName);
} H264LiveVideoServerMediaSubssion::~H264LiveVideoServerMediaSubssion()
{
} FramedSource* H264LiveVideoServerMediaSubssion::createNewStreamSource( unsigned clientSessionId, unsigned& estBitrate )
{
/* Remain to do : assign estBitrate */
estBitrate = 1000; // kbps, estimate // Create the video source:
H264FramedLiveSource* liveSource = H264FramedLiveSource::createNew(envir(), fFileName);
if (liveSource == NULL)
{
return NULL;
} // Create a framer for the Video Elementary Stream:
return H264VideoStreamFramer::createNew(envir(), liveSource);
}

3、主函数

/**********
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.) This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more details. You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
**********/
// Copyright (c) 1996-2012, Live Networks, Inc. All rights reserved
// A test program that demonstrates how to stream - via unicast RTP
// - various kinds of file on demand, using a built-in RTSP server.
// main program
#include "H264LiveVideoServerMediaSubssion.hh"
#include "H264FramedLiveSource.hh"
#include "liveMedia.hh"
#include "BasicUsageEnvironment.hh" #pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "BasicUsageEnvironment.lib")
#pragma comment (lib, "groupsock.lib")
#pragma comment (lib, "liveMedia.lib")
#pragma comment (lib, "UsageEnvironment.lib")
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":
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); // fwd static char newMatroskaDemuxWatchVariable;
static MatroskaFileServerDemux* demux;
static void onMatroskaDemuxCreation(MatroskaFileServerDemux* newDemux, void* /*clientData*/) {
demux = newDemux;
newMatroskaDemuxWatchVariable = 1;
} 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:
RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554, authDB);
if (rtspServer == NULL) {
*env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
exit(1);
} 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";
char const* inputFileName = "test.264";
ServerMediaSession* sms
= ServerMediaSession::createNew(*env, streamName, streamName,
descriptionString);
sms->addSubsession(H264LiveVideoServerMediaSubssion
::createNew(*env, inputFileName, reuseFirstSource));//修改为自己实现的servermedia H264LiveVideoServerMediaSubssion
rtspServer->addServerMediaSession(sms); announceStream(rtspServer, sms, streamName, inputFileName);
} // Also, attempt to create a HTTP server for RTSP-over-HTTP tunneling.
// Try first with the default HTTP port (80), and then with the alternative HTTP
// port numbers (8000 and 8080). //if (rtspServer->setUpTunnelingOverHTTP(80) || rtspServer->setUpTunnelingOverHTTP(8000) || rtspServer->setUpTunnelingOverHTTP(8080)) {
// *env << "\n(We use port " << rtspServer->httpServerPortNum() << " for optional RTSP-over-HTTP tunneling.)\n";
//} else {
// *env << "\n(RTSP-over-HTTP tunneling is not available.)\n";
//} 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) {
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;
}

使用 ffplay.exe rtsp://115.156.164.19:8554/h264ESVideoTest 可以播放test.264的视频.
相关配置:live555的四个库放在lib文件夹下。
库目录:G:\workspace\avs\live555test\live555test\lib
包含目录:G:\workspace\avs\live555test\live555test\BasicUsageEnvironment\include;G:\workspace\avs\live555test\live555test\UsageEnvironment\include;G:\workspace\avs\live555test\live555test\liveMedia\include;G:\workspace\avs\live555test\live555test\groupsock\include
源代码 :
live555-send-test-read-only
FROM: http://www.cnblogs.com/mlj318/archive/2013/01/23/2872932.html
【视频开发】【Live555】摄像头采集,264编码,live555直播(0)的更多相关文章
- 【视频开发】RTSP SERVER(基于live555)详细设计
/* *本文基于LIVE555的嵌入式的RTSP流媒体服务器一个设计文档,个中细节现剖于此,有需者可参考指正,同时也方便后期自己查阅.(本版本是基于2011年的live555) 作者:llf_17@q ...
- ffmpeg摄像头采集h264编码RTP发送
一. 相关API说明 1. av_register_all 2. avformat_network_init 不管是流媒体发送还是流媒体接收, 需要先执行该函数. 3. avformat_alloc_ ...
- Android IOS WebRTC 音视频开发总结(七六)-- 探讨直播低延迟低流量的粉丝连麦技术
本文主要探讨基于WebRTC的P2P直播粉丝连麦技术 (作者:郝飞,亲加云CTO,编辑:dora),最早发表在[这里] 支持原创,转载必须注明出处,欢迎关注微信公众号blacker(微信ID:blac ...
- WebRTC 音视频开发
WebRTC 音视频开发 webrtc Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译 ...
- 转:Android IOS WebRTC 音视频开发总结 (系列文章集合)
随笔分类 - webrtc Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译 ...
- 【视频开发】【Live555】摄像头采集,264编码,live555直播
加入 摄像头采集和264编码,再使用live555直播 1.摄像头采集和264编码 将x264改成编码一帧的接口,码流不写入文件而是直接写入内存中(int Encode_frame 函数中). /* ...
- (转)C++实现RTMP协议发送H.264编码及AAC编码的音视频,摄像头直播
转:http://www.cnblogs.com/haibindev/archive/2011/12/29/2305712.html C++实现RTMP协议发送H.264编码及AAC编码的音视频 RT ...
- 【秒懂音视频开发】23_H.264编码
本文主要介绍一种非常流行的视频编码:H.264. 计算一下:10秒钟1080p(1920x1080).30fps的YUV420P原始视频,需要占用多大的存储空间? (10 * 30) * (1920 ...
- Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)
本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...
- C++实现RTMP协议发送H.264编码及AAC编码的音视频
http://www.cnblogs.com/haibindev/archive/2011/12/29/2305712.html C++实现RTMP协议发送H.264编码及AAC编码的音视频 RTMP ...
随机推荐
- Java动态代理演变之路
1.什么是代理? 代理,英文成文Proxy.意思是你不用去做,别人代替你去处理.比如有人想找明星周董去唱歌,他需要做签约.讨论.唱歌和付款等等过程,但真正周董擅长的事情是唱歌,其他的事情可以交代给他的 ...
- ThinkPHP远程调用模块的操作方法 URL 参数格式
* 远程调用模块的操作方法 URL 参数格式 [项目://][分组/]模块/操作 * @param string $url 调用地址 * @param string|array $vars 调用参数 ...
- less-5
首先输入id=1和id=1’未报错,均显示You are in.....(如下图所示) 由上图可以看到,如果运行返回结果正确的时候只返回you are in...,不会返回数据库当中的信息了,所以我们 ...
- python中的glob模块的使用
最近常常用到glob模块,这里做一个简单小结: 用它可以查找符合特定规则的文件路径名.跟使用windows下的文件搜索差不多.查找文件只用到三个匹配符:”*”, “?”, “[]”.”*”匹配0个或多 ...
- STM32 IAP程序 源码 和测试代码 有详细的中文注释
http://bbs.21ic.com/forum.php?mod=viewthread&tid=588265&reltid=624002&pre_pos=2&ext= ...
- Vue --- 项目创建
目录 创建Vue项目之前的准备 创建Vue项目 重新构建项目 项目目录介绍 项目的生命周期 Vue文件式组件 配置自定义全局样式 路由逻辑跳转 生命周期钩子 路由传参的两种方式 创建Vue项目之前的准 ...
- linux 查看某个目录下文件的数量
今日思语:时间是个庸医,却自称能包治百病~ 在linux环境下,经常需要查看某个文件目录下的文件数有多少,除了进入当前目录下查看,还可以使用命令: ls -l | grep "^-" ...
- 2019.12.10 break 标记
class Demo01{ public static void main(String[] args) { int i=0; a:for(i=0;i<3;i++){ for(int j=0;j ...
- WinDbg常用命令系列---!htrace
!htrace 简介 !htrace扩展显示一个或多个句柄的堆栈跟踪信息. 使用形式 用户模式!htrace [Handle [Max_Traces]] !htrace -enable [Max_Tr ...
- P3746 【[六省联考2017]组合数问题】
题目是要我们求出如下柿子: \[\sum_{i=0}^{n}C_{nk}^{ik+r}\] 考虑k和r非常小,我们能不能从这里切入呢? 如果你注意到,所有组合数上方的数\(\%k==r\),那么是不是 ...