我想通過實時555傳輸JPEG圖像或動態JPEG文件。但問題是在實時555 Jpegs實現中不可用。任何人都可以幫忙使用live555進行JPEG流式傳輸
2
A
回答
0
希望你已經做到了,但如果沒有的話 - 看到這個Jpeg Streaming using live555 這和你要求傳輸圖像/ Jpegs的做法是一樣的。 對於MJpegs,您必須執行相同的過程。
2
您可以找到發佈到devel郵件列表http://lists.live555.com/pipermail/live-devel/2012-February/014672.html的實現。 代碼和示例可用,但此修改被live555維護人員拒絕。
首先,我們需要實現一個MJPEGVideoSource
比可以喂JPEGVideoRTPSink
。
#include "liveMedia.hh"
#include "BasicUsageEnvironment.hh"
#include "GroupsockHelper.hh"
#include "MJPEGVideoSource.hh"
char const* inputFileName = "test.mjpeg";
int main(int argc, char** argv) {
// Begin by setting up our usage environment:
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler);
// 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 source
Groupsock rtcpGroupsock(*env, destinationAddress, rtcpPort, ttl);
rtcpGroupsock.multicastSendOnly(); // we're a SSM source
// Create a 'JPEG Video RTP' sink from the RTP 'groupsock':
RTPSink* videoSink = JPEGVideoRTPSink::createNew(*env, &rtpGroupsock);
// Create (and start) a 'RTCP instance' for this RTP sink:
const unsigned estimatedSessionBandwidth = 5000; // in kbps; for RTCP b/w share
const unsigned maxCNAMElen = 100;
unsigned char CNAME[maxCNAMElen+1];
gethostname((char*)CNAME, maxCNAMElen);
CNAME[maxCNAMElen] = '\0'; // just in case
RTCPInstance* rtcp = RTCPInstance::createNew(*env, &rtcpGroupsock,
estimatedSessionBandwidth, CNAME,
videoSink, NULL /* we're a server */,
True /* we're a SSM source */);
// Note: This starts RTCP running automatically
RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554);
if (rtspServer == NULL) {
*env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
exit(1);
}
ServerMediaSession* sms = ServerMediaSession::createNew(*env, "testStream", inputFileName,"Session streamed by \"testMJPEGVideoStreamer\"",
True /*SSM*/);
sms->addSubsession(PassiveServerMediaSubsession::createNew(*videoSink, rtcp));
rtspServer->addServerMediaSession(sms);
char* url = rtspServer->rtspURL(sms);
*env << "Play this stream using the URL \"" << url << "\"\n";
delete[] url;
// Start the streaming:
*env << "Beginning streaming...\n";
// 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);
}
// Create the MJPEG video source:
MJPEGVideoSource* videoSource = MJPEGVideoSource::createNew(*env, fileSource);
// Finally, start playing:
*env << "Beginning to read from file...\n";
videoSink->startPlaying(*videoSource, NULL, NULL);
env->taskScheduler().doEventLoop();
return 0;
}
:
#include "JPEGVideoSource.hh"
class MJPEGVideoSource : public JPEGVideoSource
{
public:
static MJPEGVideoSource* createNew (UsageEnvironment& env, FramedSource* source)
{
return new MJPEGVideoSource(env,source);
}
virtual void doGetNextFrame()
{
if (m_inputSource)
m_inputSource->getNextFrame(fTo, fMaxSize, afterGettingFrameSub, this, FramedSource::handleClosure, this);
}
virtual void doStopGettingFrames()
{
FramedSource::doStopGettingFrames();
if (m_inputSource)
m_inputSource->stopGettingFrames();
}
static void afterGettingFrameSub(void* clientData, unsigned frameSize,unsigned numTruncatedBytes,struct timeval presentationTime,unsigned durationInMicroseconds)
{
MJPEGVideoSource* source = (MJPEGVideoSource*)clientData;
source->afterGettingFrame(frameSize, numTruncatedBytes, presentationTime, durationInMicroseconds);
}
void afterGettingFrame(unsigned frameSize,unsigned numTruncatedBytes,struct timeval presentationTime,unsigned durationInMicroseconds)
{
int headerSize = 0;
bool headerOk = false;
fFrameSize = 0;
for (unsigned int i = 0; i < frameSize ; ++i)
{
// SOF
if ((i+8) < frameSize && fTo[i] == 0xFF && fTo[i+1] == 0xC0)
{
m_height = (fTo[i+5]<<5)|(fTo[i+6]>>3);
m_width = (fTo[i+7]<<5)|(fTo[i+8]>>3);
}
// DQT
if ((i+5+64) < frameSize && fTo[i] == 0xFF && fTo[i+1] == 0xDB)
{
if (fTo[i+4] ==0)
{
memcpy(m_qTable, fTo + i + 5, 64);
m_qTable0Init = true;
}
else if (fTo[i+4] ==1)
{
memcpy(m_qTable + 64, fTo + i + 5, 64);
m_qTable1Init = true;
}
}
// End of header
if ((i+1) < frameSize && fTo[i] == 0x3F && fTo[i+1] == 0x00)
{
headerOk = true;
headerSize = i+2;
break;
}
}
if (headerOk)
{
fFrameSize = frameSize - headerSize;
memmove(fTo, fTo + headerSize, fFrameSize);
}
fNumTruncatedBytes = numTruncatedBytes;
fPresentationTime = presentationTime;
fDurationInMicroseconds = durationInMicroseconds;
afterGetting(this);
}
virtual u_int8_t type() { return 1; };
virtual u_int8_t qFactor() { return 128; };
virtual u_int8_t width() { return m_width; };
virtual u_int8_t height() { return m_height; };
u_int8_t const* quantizationTables(u_int8_t& precision, u_int16_t& length)
{
length = 0;
precision = 0;
if (m_qTable0Init && m_qTable1Init)
{
precision = 8;
length = sizeof(m_qTable);
}
return m_qTable;
}
protected:
MJPEGVideoSource(UsageEnvironment& env, FramedSource* source) : JPEGVideoSource(env),
m_inputSource(source),
m_width(0),
m_height(0),
m_qTable0Init(false),
m_qTable1Init(false)
{
memset(&m_qTable,0,sizeof(m_qTable));
}
virtual ~MJPEGVideoSource()
{
Medium::close(m_inputSource);
}
protected:
FramedSource* m_inputSource;
u_int8_t m_width;
u_int8_t m_height;
u_int8_t m_qTable[128];
bool m_qTable0Init;
bool m_qTable1Init;
};
接下來,我們可以爲了構建一個簡單的RTSP服務器使用它作爲一個視頻源
相關問題
- 1. 流式傳輸JPEG,檢測JPEG結束
- 2. 使用red5進行Http流式傳輸
- 3. 使用RTP進行VLC流式傳輸
- 4. scalikejdbc使用oracle進行流式傳輸
- 5. 使用ffserver進行RTMP流式傳輸
- 6. 使用Amazon S3進行流式傳輸
- 7. 使用GStreamer進行流式傳輸
- 8. 使用Qt進行流式傳輸
- 9. 使用Spring Framework進行流式傳輸
- 10. 使用XProc進行XML流式傳輸
- 11. 使用JavaScript進行流式傳輸
- 12. 使用FFMPEG進行RTP流式傳輸
- 13. 使用Live555流式傳輸多個文件
- 14. 如何使用live555流式傳輸mp3文件音樂?
- 15. 如何使live555服務器通過使用rtsp地址而不是文件流進行流式傳輸
- 16. 用Cassandra進行Java Spark流式傳輸
- 17. 使用Python和Python子流程進行Hadoop流式傳輸
- 18. 使用AS3進行數據流傳輸?
- 19. 通過從Live555到VLC的RTP流式傳輸H.264視頻
- 20. 使用live555將H264傳輸到VLC
- 21. 關於使用gstreamer進行流式傳輸的方式
- 22. 使用TextInputFormat和Python進行Hadoop流式傳輸 - 記錄行號
- 23. 通過http進行RTMP流式傳輸
- 24. 在.Net中進行HTTP流式傳輸
- 25. 使用live555和FFmpeg流H264
- 26. AVPlayer流式傳輸進度
- 27. 用tcp使用opencv和socket進行流式傳輸
- 28. Live555在一個RTSP流中流式傳輸實況視頻和音頻
- 29. 使用Apache進行H.264調整/縮小和流式傳輸
- 30. 在軌道中使用遏制進行流式傳輸