live555中testProgs文件有兩個測試程序可以用來保存文件,分別是playCommon.cpp和testRTSPclient.cpp。
先來看testRTSPclient.cpp保存264文件的代碼
void DummySink::afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes,
struct timeval presentationTime, unsigned /*durationInMicroseconds*/) {
// We've just received a frame of data. (Optionally) print out information about it:
#ifdef DEBUG_PRINT_EACH_RECEIVED_FRAME
if (fStreamId != NULL) envir() << "Stream \"" << fStreamId << "\"; ";
envir() << fSubsession.mediumName() << "/" << fSubsession.codecName() << ":\tReceived " << frameSize << " bytes";
// envir() << fSubsession.rtpPayloadFormat() << "******";
if (numTruncatedBytes > 0) envir() << " (with " << numTruncatedBytes << " bytes truncated)";
char uSecsStr[6+1]; // used to output the 'microseconds' part of the presentation time
sprintf(uSecsStr, "%06u", (unsigned)presentationTime.tv_usec);
envir() << ".\tPresentation time: " << (int)presentationTime.tv_sec << "." << uSecsStr;
if (fSubsession.rtpSource() != NULL && !fSubsession.rtpSource()->hasBeenSynchronizedUsingRTCP()) {
envir() << "!"; // mark the debugging output to indicate that this presentation time is not RTCP-synchronized
}
#ifdef DEBUG_PRINT_NPT
envir() << "\tNPT: " << fSubsession.getNormalPlayTime(presentationTime);
#endif
envir() << "\n";
#endif
#if 1 //nhh
if ( 0 == strcmp(fSubsession.mediumName(),"video"))
{
if (firstFrame)
{
unsigned int num = 2;
SPropRecord *sps = parseSPropParameterSets(fSubsession.fmtp_spropparametersets(), num);
// For H.264 video stream, we use a special sink that insert start_codes:
struct timeval tv = { 0,0 };
unsigned char start_code[4] = { 0x00, 0x00, 0x00, 0x01 };
FILE *fp = fopen("test.264", "a+b");
if (fp)
{
fwrite(start_code, 4, 1, fp);
fwrite(sps[0].sPropBytes, sps[0].sPropLength, 1, fp);
fwrite(start_code, 4, 1, fp);
fwrite(sps[1].sPropBytes, sps[1].sPropLength, 1, fp);
fclose(fp);
fp = NULL;
}
delete[] sps;
firstFrame = False;
}
char *pbuf = (char *)fReceiveBuffer;
char head[4] = { 0x00, 0x00, 0x00, 0x01 };
FILE *fp = fopen("test.264", "a+b");
if (fp)
{
fwrite(head, 4, 1, fp);
fwrite(fReceiveBuffer, frameSize, 1, fp);
fclose(fp);
fp = NULL;
}
}
#endif
// Then continue, to request the next frame of data:
continuePlaying();
}
這套代碼可以用來保存後綴264文件,但是不穩定,有的rtsp生成的文件用vlc打開不了,原因不明。
playCommon.cpp這套代碼可以生成vlc播放的264文件,但是關鍵點在於你要自己修改保存文件的名字且要有後綴名(列如video.264),不然用vlc也是播不出來的。