<html dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style id="owaTempEditStyle"></style><style title="owaParaStyle"><!--P {
MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px
}
--></style>
</head>
<body ocsi="x">
<div style="FONT-FAMILY: Tahoma; DIRECTION: ltr; COLOR: #000000; FONT-SIZE: 13px">
<div></div>
<div dir="ltr"><font color="#000000" size="2" face="Tahoma">Hi All,</font></div>
<div dir="ltr"><font size="2" face="tahoma">I am trying to perform multicast live streaming from a web camera.
</font></div>
<div dir="ltr"><font size="2" face="tahoma">The web camera is continuously generating mpeg 4 stream (single file with extension as .m4e). I am performing the streaming using testMPEG4VideoStreamer.</font></div>
<div dir="ltr"><font size="2" face="tahoma">The way I do it is that I initialize the current position to 0, and start the testMPEG4VideoStreamer.exe</font></div>
<div dir="ltr"><font size="2" face="tahoma">AS soon as the "afterPlaying" callback gets called, I again call the play() method with the new value of the current position .</font></div>
<div dir="ltr"><font size="2" face="tahoma">Please refer to the below code:</font></div>
<div dir="ltr"> </div>
<div dir="ltr">#include "liveMedia.hh"<br>
#include "BasicUsageEnvironment.hh"<br>
#include "GroupsockHelper.hh"</div>
<div dir="ltr">UsageEnvironment* env;<br>
char const* inputFileName = "test.m4e";<br>
MPEG4VideoStreamFramer* videoSource;<br>
RTPSink* videoSink;<br>
long currentPos = 0;<br>
void play(long); // forward</div>
<div dir="ltr">int main(int argc, char** argv) {<br>
// Begin by setting up our usage environment:<br>
TaskScheduler* scheduler = BasicTaskScheduler::createNew();<br>
env = BasicUsageEnvironment::createNew(*scheduler);</div>
<div dir="ltr"> // Create 'groupsocks' for RTP and RTCP:<br>
struct in_addr destinationAddress;<br>
destinationAddress.s_addr = chooseRandomIPv4SSMAddress(*env);<br>
// Note: This is a multicast address. If you wish instead to stream<br>
// using unicast, then you should use the "testOnDemandRTSPServer"<br>
// test program - not this test program - as a model.</div>
<div dir="ltr"> const unsigned short rtpPortNum = 18888;<br>
const unsigned short rtcpPortNum = rtpPortNum+1;<br>
const unsigned char ttl = 255;</div>
<div dir="ltr"> const Port rtpPort(rtpPortNum);<br>
const Port rtcpPort(rtcpPortNum);</div>
<div dir="ltr"> Groupsock rtpGroupsock(*env, destinationAddress, rtpPort, ttl);<br>
rtpGroupsock.multicastSendOnly(); // we're a SSM source<br>
Groupsock rtcpGroupsock(*env, destinationAddress, rtcpPort, ttl);<br>
rtcpGroupsock.multicastSendOnly(); // we're a SSM source</div>
<div dir="ltr"> // Create a 'MPEG-4 Video RTP' sink from the RTP 'groupsock':<br>
videoSink = MPEG4ESVideoRTPSink::createNew(*env, &rtpGroupsock, 96);</div>
<div dir="ltr"> // Create (and start) a 'RTCP instance' for this RTP sink:<br>
const unsigned estimatedSessionBandwidth = 500; // in kbps; for RTCP b/w share<br>
const unsigned maxCNAMElen = 100;<br>
unsigned char CNAME[maxCNAMElen+1];<br>
gethostname((char*)CNAME, maxCNAMElen);<br>
CNAME[maxCNAMElen] = '\0'; // just in case<br>
RTCPInstance* rtcp<br>
= RTCPInstance::createNew(*env, &rtcpGroupsock,<br>
estimatedSessionBandwidth, CNAME,<br>
videoSink, NULL /* we're a server */,<br>
True /* we're a SSM source */);<br>
// Note: This starts RTCP running automatically</div>
<div dir="ltr"> RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554);<br>
if (rtspServer == NULL) {<br>
*env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";<br>
exit(1);<br>
}<br>
ServerMediaSession* sms<br>
= ServerMediaSession::createNew(*env, inputFileName, inputFileName,<br>
"Session streamed by \"testMPEG4VideoStreamer\"",<br>
True /*SSM*/);<br>
sms->addSubsession(PassiveServerMediaSubsession::createNew(*videoSink, rtcp));<br>
rtspServer->addServerMediaSession(sms);</div>
<div dir="ltr"> char* url = rtspServer->rtspURL(sms);<br>
*env << "Play this stream using the URL \"" << url << "\"\n";<br>
delete[] url;</div>
<div dir="ltr"> // Start the streaming:<br>
*env << "Beginning streaming...\n";<br>
*env << "Playing with currentPosition as " << currentPos << "\n";<br>
play(currentPos);</div>
<div dir="ltr"> env->taskScheduler().doEventLoop(); // does not return</div>
<div dir="ltr"> return 0; // only to prevent compiler warning<br>
}</div>
<div dir="ltr">void afterPlaying(void* /*clientData*/) {<br>
*env << "...done reading from file\n";</div>
<div dir="ltr"> Medium::close(videoSource);<br>
// Note that this also closes the input file that this source read from.<br>
// Start playing once again:<br>
<br>
*env << "Playing with currentPosition as " << currentPos << "\n";<br>
play(currentPos);<br>
<br>
}</div>
<div dir="ltr">void play(long currentPosition) {<br>
// Open the input file as a 'byte-stream file source':<br>
ByteStreamFileSource* fileSource<br>
= ByteStreamFileSource::createNew(*env, inputFileName);<br>
if (fileSource == NULL) {<br>
*env << "Unable to open file \"" << inputFileName<br>
<< "\" as a byte-stream file source\n";<br>
exit(1);<br>
}<br>
long currentFileSize = (long)(fileSource->fileSize());<br>
*env << "Current File Size ...." << currentFileSize << "\n";<br>
*env << "Seeking to position ...." << currentPosition << "\n";<br>
fileSource->seekToByteAbsolute(currentPosition);</div>
<div dir="ltr"> FramedSource* videoES = fileSource;</div>
<div dir="ltr"> // Create a framer for the Video Elementary Stream:<br>
videoSource = MPEG4VideoStreamFramer::createNew(*env, videoES);<br>
videoSource->flushInput();<br>
// Finally, start playing:<br>
*env << "Beginning to read from file...\n";<br>
//currentPos += (currentFileSize-currentPosition);<br>
currentPos = currentFileSize;<br>
videoSink->startPlaying(*videoSource, afterPlaying, videoSink); <br>
}</div>
<p><font size="2" face="tahoma"></font> </p>
<p><font size="2" face="tahoma"></font> </p>
<p><font size="2" face="tahoma">However, on opening the rtsp url from VLC player, although no error is reported. However, VLC player does not show any video. Please help me in identifying my mistake</font></p>
<div dir="ltr"><br>
</div>
<div dir="ltr"><font size="2" face="tahoma"></font> </div>
</div>
<br>
<hr>
<font face="Arial" color="Gray" size="1">::DISCLAIMER::<br>
-----------------------------------------------------------------------------------------------------------------------<br>
<br>
The contents of this e-mail and any attachment(s) are confidential and intended for the named recipient(s) only.<br>
It shall not attach any liability on the originator or HCL or its affiliates. Any views or opinions presented in<br>
this email are solely those of the author and may not necessarily reflect the opinions of HCL or its affiliates.<br>
Any form of reproduction, dissemination, copying, disclosure, modification, distribution and / or publication of<br>
this message without the prior written consent of the author of this e-mail is strictly prohibited. If you have<br>
received this email in error please delete it and notify the sender immediately. Before opening any mail and<br>
attachments please check them for viruses and defect.<br>
<br>
-----------------------------------------------------------------------------------------------------------------------<br>
</font>
</body>
</html>