当前位置: 首页 > news >正文

邢台网站制作怎么样前端是做网站的吗

邢台网站制作怎么样,前端是做网站的吗,住房和城乡建设部网站造价,深圳工程交易中心网http://blog.csdn.net/leixiaohua1020/article/details/12952977 rtmpdump 是一个用来处理 RTMP 流媒体的工具包#xff0c;支持 rtmp://, rtmpt://, rtmpe://, rtmpte://, and rtmps:// 等。之前在学习RTMP协议的时候#xff0c;发现没有讲它源代码的#xff0c;只好自己分…http://blog.csdn.net/leixiaohua1020/article/details/12952977 rtmpdump 是一个用来处理 RTMP 流媒体的工具包支持 rtmp://, rtmpt://, rtmpe://, rtmpte://, and rtmps:// 等。之前在学习RTMP协议的时候发现没有讲它源代码的只好自己分析现在打算把自己学习的成果写出来可能结果不一定都对先暂且记录一下。 函数调用结构图 RTMPDump (libRTMP)的整体的函数调用结构图如下图所示。 单击查看大图 详细分析 使用RTMPdump下载一个流媒体的大致流程是这样的 [cpp] view plaincopy RTMP_Init();//初始化结构体   InitSockets();//初始化Socket   RTMP_ParseURL();//解析输入URL   RTMP_SetupStream();//一些设置   fopen();//打开文件准备写入   RTMP_Connect();//建立NetConnection   RTMP_ConnectStream()//建立NetStream   Download();//下载函数   RTMP_Close();//关闭连接   fclose();//关闭文件   CleanupSockets();//清理Socket   其中Download()主要是使用RTMP_Read()进行下载的。 注可以参考RTMP流媒体播放过程 下面贴上自己注释的RTMPDump源代码。注意以下几点 1.此RTMPDump已经被移植进VC 2010 的 MFC的工程所以main()函数已经被改名为rtmpdump()而且参数也改了传进来一个MFC窗口的句柄。不过功能没怎么改控制台程序移植到MFC以后main()就不是程序的入口了所以main()名字改成什么是无所谓的 2.里面有很多提取信息的代码形如rtmp.dlg-AppendCInfo(开始初始化Socket...);这些代码是我为了获取RTMP信息而自己加的并不影响程序的执行。 [cpp] view plaincopy int rtmpdump(LPVOID lpParam,int argc,char **argv)   {            extern char *optarg;     //一定要设置否则只能运行一次     extern int optind;     optind0;     int nStatus  RD_SUCCESS;     double percent  0;     double duration  0.0;        int nSkipKeyFrames  DEF_SKIPFRM; // skip this number of keyframes when resuming        int bOverrideBufferTime  FALSE;  // if the user specifies a buffer time override this is true     int bStdoutMode  TRUE;   // if true print the stream directly to stdout, messages go to stderr     int bResume  FALSE;      // true in resume mode     uint32_t dSeek  0;       // seek position in resume mode, 0 otherwise     uint32_t bufferTime  DEF_BUFTIME;        // meta header and initial frame for the resume mode (they are read from the file and compared with     // the stream we are trying to continue     char *metaHeader  0;     uint32_t nMetaHeaderSize  0;        // video keyframe for matching     char *initialFrame  0;     uint32_t nInitialFrameSize  0;     int initialFrameType  0; // tye: audio or video        AVal hostname  { 0, 0 };     AVal playpath  { 0, 0 };     AVal subscribepath  { 0, 0 };     int port  -1;     int protocol  RTMP_PROTOCOL_UNDEFINED;     int retries  0;     int bLiveStream  FALSE;  // 是直播流吗? then we cant seek/resume     int bHashes  FALSE;      // display byte counters not hashes by default        long int timeout  DEF_TIMEOUT;   // timeout connection after 120 seconds     uint32_t dStartOffset  0;    // 非直播流搜寻点seek position in non-live mode     uint32_t dStopOffset  0;     RTMP rtmp  { 0 };        AVal swfUrl  { 0, 0 };     AVal tcUrl  { 0, 0 };     AVal pageUrl  { 0, 0 };     AVal app  { 0, 0 };     AVal auth  { 0, 0 };     AVal swfHash  { 0, 0 };     uint32_t swfSize  0;     AVal flashVer  { 0, 0 };     AVal sockshost  { 0, 0 };      #ifdef CRYPTO     int swfAge  30;  /* 30 days for SWF cache by default */     int swfVfy  0;     unsigned char hash[RTMP_SWF_HASHLEN];   #endif        char *flvFile  0;        signal(SIGINT, sigIntHandler);     signal(SIGTERM, sigIntHandler);   #ifndef WIN32     signal(SIGHUP, sigIntHandler);     signal(SIGPIPE, sigIntHandler);     signal(SIGQUIT, sigIntHandler);   #endif        RTMP_debuglevel  RTMP_LOGINFO;        //首先搜寻“ --quiet”选项     int index  0;     while (index  argc)       {         if (strcmp(argv[index], --quiet)  0         || strcmp(argv[index], -q)  0)       RTMP_debuglevel  RTMP_LOGCRIT;         index;       }   #define RTMPDUMP_VERSION 1.0     RTMP_LogPrintf(RTMP流媒体下载 %s\n, RTMPDUMP_VERSION);     RTMP_LogPrintf       (2012 雷霄骅 中国传媒大学/信息工程学院/通信与信息系统/数字电视技术\n);     //RTMP_LogPrintf(输入 -h 获取命令选项\n);       RTMP_Init(rtmp);       //句柄-----------------------------       rtmp.dlg(CSpecialPRTMPDlg *)lpParam;       //---------------------------------       //----------------------       rtmp.dlg-AppendCInfo(开始初始化Socket...);       //-----------------------------       if (!InitSockets())       {           //----------------------           rtmp.dlg-AppendCInfo(初始化Socket失败);           //-----------------------------           RTMP_Log(RTMP_LOGERROR,               Couldnt load sockets support on your platform, exiting!);           return RD_FAILED;       }     //----------------------     rtmp.dlg-AppendCInfo(成功初始化Socket);     //-----------------------------     /* sleep(30); */              int opt;   /*  struct option longopts[]  {      {help, 0, NULL, h},      {host, 1, NULL, n},      {port, 1, NULL, c},      {socks, 1, NULL, S},      {protocol, 1, NULL, l},      {playpath, 1, NULL, y},      {playlist, 0, NULL, Y},      {rtmp, 1, NULL, r},      {swfUrl, 1, NULL, s},      {tcUrl, 1, NULL, t},      {pageUrl, 1, NULL, p},      {app, 1, NULL, a},      {auth, 1, NULL, u},      {conn, 1, NULL, C},  #ifdef CRYPTO      {swfhash, 1, NULL, w},      {swfsize, 1, NULL, x},      {swfVfy, 1, NULL, W},      {swfAge, 1, NULL, X},  #endif      {flashVer, 1, NULL, f},      {live, 0, NULL, v},      {flv, 1, NULL, o},      {resume, 0, NULL, e},      {timeout, 1, NULL, m},      {buffer, 1, NULL, b},      {skip, 1, NULL, k},      {subscribe, 1, NULL, d},      {start, 1, NULL, A},      {stop, 1, NULL, B},      {token, 1, NULL, T},      {hashes, 0, NULL, #},      {debug, 0, NULL, z},      {quiet, 0, NULL, q},      {verbose, 0, NULL, V},      {0, 0, 0, 0}    };*/     //分析命令行参数注意用法。     //选项都是一个字母后面有冒号的代表该选项还有相关参数     //一直循环直到获取所有的opt     while ((opt          getopt/*_long*/(argc, argv,                 hVveqzr:s:t:p:a:b:f:o:u:C:n:c:l:y:Ym:k:d:A:B:T:w:x:W:X:S:#/*,                longopts, NULL*/)) ! -1)       {       //不同的选项做不同的处理         switch (opt)       {       case h:         usage(argv[0]);         return RD_SUCCESS;   #ifdef CRYPTO       case w:         {           int res  hex2bin(optarg, swfHash.av_val);           if (res ! RTMP_SWF_HASHLEN)             {           swfHash.av_val  NULL;           RTMP_Log(RTMP_LOGWARNING,               Couldnt parse swf hash hex string, not hexstring or not %d bytes, ignoring!, RTMP_SWF_HASHLEN);             }           swfHash.av_len  RTMP_SWF_HASHLEN;           break;         }       case x:         {           int size  atoi(optarg);           if (size  0)             {           RTMP_Log(RTMP_LOGERROR, SWF Size must be at least 1, ignoring\n);             }           else             {           swfSize  size;             }           break;         }           case W:         STR2AVAL(swfUrl, optarg);         swfVfy  1;             break;           case X:         {           int num  atoi(optarg);           if (num  0)             {           RTMP_Log(RTMP_LOGERROR, SWF Age must be non-negative, ignoring\n);             }           else             {           swfAge  num;             }         }             break;   #endif       case k:         nSkipKeyFrames  atoi(optarg);         if (nSkipKeyFrames  0)           {             RTMP_Log(RTMP_LOGERROR,             Number of keyframes skipped must be greater or equal zero, using zero!);             nSkipKeyFrames  0;           }         else           {             RTMP_Log(RTMP_LOGDEBUG, Number of skipped key frames for resume: %d,             nSkipKeyFrames);           }         break;       case b:         {           int32_t bt  atol(optarg);           if (bt  0)             {           RTMP_Log(RTMP_LOGERROR,               Buffer time must be greater than zero, ignoring the specified value %d!,               bt);             }           else             {           bufferTime  bt;           bOverrideBufferTime  TRUE;             }           break;         }       //直播流       case v:           //----------------           rtmp.dlg-AppendCInfo(该RTMP的URL是一个直播流);           //----------------         bLiveStream  TRUE;   // no seeking or resuming possible!         break;       case d:         STR2AVAL(subscribepath, optarg);         break;       case n:         STR2AVAL(hostname, optarg);         break;       case c:         port  atoi(optarg);         break;       case l:         protocol  atoi(optarg);         if (protocol  RTMP_PROTOCOL_RTMP || protocol  RTMP_PROTOCOL_RTMPTS)           {             RTMP_Log(RTMP_LOGERROR, Unknown protocol specified: %d, protocol);             return RD_FAILED;           }         break;       case y:         STR2AVAL(playpath, optarg);         break;       case Y:         RTMP_SetOpt(rtmp, av_playlist, (AVal *)av_true);         break;         //路径参数-r       case r:         {           AVal parsedHost, parsedApp, parsedPlaypath;           unsigned int parsedPort  0;           int parsedProtocol  RTMP_PROTOCOL_UNDEFINED;           //解析URL。注optarg指向参数URL           RTMP_LogPrintf(RTMP URL : %s\n,optarg);           //----------------           rtmp.dlg-AppendCInfo(解析RTMP的URL...);           //----------------           if (!RTMP_ParseURL           (optarg, parsedProtocol, parsedHost, parsedPort,            parsedPlaypath, parsedApp))             {               //----------------               rtmp.dlg-AppendCInfo(解析RTMP的URL失败);               //----------------           RTMP_Log(RTMP_LOGWARNING, 无法解析 url (%s)!,               optarg);             }           else             {               //----------------               rtmp.dlg-AppendCInfo(解析RTMP的URL成功);               //----------------           //把解析出来的数据赋值           if (!hostname.av_len)             hostname  parsedHost;           if (port  -1)             port  parsedPort;           if (playpath.av_len  0  parsedPlaypath.av_len)             {               playpath  parsedPlaypath;             }           if (protocol  RTMP_PROTOCOL_UNDEFINED)             protocol  parsedProtocol;           if (app.av_len  0  parsedApp.av_len)             {               app  parsedApp;             }             }             break;         }       case s:         STR2AVAL(swfUrl, optarg);         break;       case t:         STR2AVAL(tcUrl, optarg);         break;       case p:         STR2AVAL(pageUrl, optarg);         break;       case a:         STR2AVAL(app, optarg);         break;       case f:         STR2AVAL(flashVer, optarg);         break;       //指定输出文件       case o:         flvFile  optarg;         if (strcmp(flvFile, -))           bStdoutMode  FALSE;            break;       case e:         bResume  TRUE;         break;       case u:         STR2AVAL(auth, optarg);         break;       case C: {         AVal av;         STR2AVAL(av, optarg);         if (!RTMP_SetOpt(rtmp, av_conn, av))           {             RTMP_Log(RTMP_LOGERROR, Invalid AMF parameter: %s, optarg);             return RD_FAILED;           }         }         break;       case m:         timeout  atoi(optarg);         break;       case A:         dStartOffset  (int) (atof(optarg) * 1000.0);         break;       case B:         dStopOffset  (int) (atof(optarg) * 1000.0);         break;       case T: {         AVal token;         STR2AVAL(token, optarg);         RTMP_SetOpt(rtmp, av_token, token);         }         break;       case #:         bHashes  TRUE;         break;       case q:         RTMP_debuglevel  RTMP_LOGCRIT;         break;       case V:         RTMP_debuglevel  RTMP_LOGDEBUG;         break;       case z:         RTMP_debuglevel  RTMP_LOGALL;         break;       case S:         STR2AVAL(sockshost, optarg);         break;       default:         RTMP_LogPrintf(unknown option: %c\n, opt);         usage(argv[0]);         return RD_FAILED;         break;       }       }        if (!hostname.av_len)       {         RTMP_Log(RTMP_LOGERROR,         您必须指定 主机名(hostname) (--host) 或 url (-r \rtmp://host[:port]/playpath\) 包含 a hostname);         return RD_FAILED;       }     if (playpath.av_len  0)       {         RTMP_Log(RTMP_LOGERROR,         您必须指定 播放路径(playpath) (--playpath) 或 url (-r \rtmp://host[:port]/playpath\) 包含 a playpath);         return RD_FAILED;       }        if (protocol  RTMP_PROTOCOL_UNDEFINED)       {         RTMP_Log(RTMP_LOGWARNING,         您没有指定 协议(protocol) (--protocol) 或 rtmp url (-r), 默认协议 RTMP);         protocol  RTMP_PROTOCOL_RTMP;       }     if (port  -1)       {         RTMP_Log(RTMP_LOGWARNING,         您没有指定 端口(port) (--port) 或 rtmp url (-r), 默认端口 1935);         port  0;       }     if (port  0)       {         if (protocol  RTMP_FEATURE_SSL)       port  443;         else if (protocol  RTMP_FEATURE_HTTP)       port  80;         else       port  1935;       }        if (flvFile  0)       {         RTMP_Log(RTMP_LOGWARNING,         请指定一个输出文件 (-o filename), using stdout);         bStdoutMode  TRUE;       }        if (bStdoutMode  bResume)       {         RTMP_Log(RTMP_LOGWARNING,         Cant resume in stdout mode, ignoring --resume option);         bResume  FALSE;       }        if (bLiveStream  bResume)       {         RTMP_Log(RTMP_LOGWARNING, Cant resume live stream, ignoring --resume option);         bResume  FALSE;       }      #ifdef CRYPTO     if (swfVfy)       {         if (RTMP_HashSWF(swfUrl.av_val, (unsigned int *)swfSize, hash, swfAge)  0)           {             swfHash.av_val  (char *)hash;             swfHash.av_len  RTMP_SWF_HASHLEN;           }       }        if (swfHash.av_len  0  swfSize  0)       {         RTMP_Log(RTMP_LOGWARNING,         Ignoring SWF size, supply also the hash with --swfhash);         swfSize  0;       }        if (swfHash.av_len ! 0  swfSize  0)       {         RTMP_Log(RTMP_LOGWARNING,         Ignoring SWF hash, supply also the swf size  with --swfsize);         swfHash.av_len  0;         swfHash.av_val  NULL;       }   #endif        if (tcUrl.av_len  0)       {         char str[512]  { 0 };            tcUrl.av_len  snprintf(str, 511, %s://%.*s:%d/%.*s,              RTMPProtocolStringsLower[protocol], hostname.av_len,              hostname.av_val, port, app.av_len, app.av_val);         tcUrl.av_val  (char *) malloc(tcUrl.av_len  1);         strcpy(tcUrl.av_val, str);       }        int first  1;        // User defined seek offset     if (dStartOffset  0)       {         //直播流         if (bLiveStream)       {         RTMP_Log(RTMP_LOGWARNING,             Cant seek in a live stream, ignoring --start option);         dStartOffset  0;       }       }     //----------------     rtmp.dlg-AppendCInfo(开始初始化RTMP连接的参数...);     //----------------     //设置     RTMP_SetupStream(rtmp, protocol, hostname, port, sockshost, playpath,              tcUrl, swfUrl, pageUrl, app, auth, swfHash, swfSize,              flashVer, subscribepath, dSeek, dStopOffset, bLiveStream, timeout);     //此处设置参数-----------------     rtmp.dlg-AppendCInfo(成功初始化RTMP连接的参数);     //-----------------------------     char *temp(char *)malloc(MAX_URL_LENGTH);        memcpy(temp,rtmp.Link.hostname.av_val,rtmp.Link.hostname.av_len);     temp[rtmp.Link.hostname.av_len]\0;     rtmp.dlg-AppendB_R_L_Info(主机名,temp);        itoa(rtmp.Link.port,temp,10);     rtmp.dlg-AppendB_R_L_Info(端口号,temp);        memcpy(temp,rtmp.Link.app.av_val,rtmp.Link.app.av_len);     temp[rtmp.Link.app.av_len]\0;     rtmp.dlg-AppendB_R_L_Info(应用程序,temp);        memcpy(temp,rtmp.Link.playpath.av_val,rtmp.Link.playpath.av_len);     temp[rtmp.Link.playpath.av_len]\0;     rtmp.dlg-AppendB_R_L_Info(路径,temp);           //-----------------------------        /* Try to keep the stream moving if it pauses on us */     if (!bLiveStream  !(protocol  RTMP_FEATURE_HTTP))       rtmp.Link.lFlags | RTMP_LF_BUFX;        off_t size  0;        // ok,我们必须获得timestamp of the last keyframe (only keyframes are seekable) / last audio frame (audio only streams)     if (bResume)       {       //打开文件输出的文件(Resume)         nStatus        OpenResumeFile(flvFile, file, size, metaHeader, nMetaHeaderSize,                  duration);         if (nStatus  RD_FAILED)       goto clean;            if (!file)       {         // file does not exist, so go back into normal mode         bResume  FALSE;  // we are back in fresh file mode (otherwise finalizing file wont be done)       }         else       {       //获取最后一个关键帧         nStatus  GetLastKeyframe(file, nSkipKeyFrames,                       dSeek, initialFrame,                       initialFrameType, nInitialFrameSize);         if (nStatus  RD_FAILED)           {             RTMP_Log(RTMP_LOGDEBUG, Failed to get last keyframe.);             goto clean;           }            if (dSeek  0)           {             RTMP_Log(RTMP_LOGDEBUG,             Last keyframe is first frame in stream, switching from resume to normal mode!);             bResume  FALSE;           }       }       }     //如果输出文件不存在     if (!file)       {         if (bStdoutMode)       {       //直接输出到stdout         file  stdout;         SET_BINMODE(file);       }         else       {       //打开一个文件       //wb 读写打开或建立一个二进制文件允许读和写。           //-----------------           rtmp.dlg-AppendCInfo(创建输出文件...);           //-----------------------------         file  fopen(flvFile, wb);         if (file  0)           {               //-----------------               rtmp.dlg-AppendCInfo(创建输出文件失败);               //-----------------------------             RTMP_LogPrintf(Failed to open file! %s\n, flvFile);             return RD_FAILED;           }         rtmp.dlg-AppendCInfo(成功创建输出文件);       }       }      #ifdef _DEBUG     netstackdump  fopen(netstackdump, wb);     netstackdump_read  fopen(netstackdump_read, wb);   #endif        while (!RTMP_ctrlC)       {         RTMP_Log(RTMP_LOGDEBUG, Setting buffer time to: %dms, bufferTime);         //设置Buffer时间         //-----------------         rtmp.dlg-AppendCInfo(设置缓冲(Buffer)的时间);         //-----------------------------         RTMP_SetBufferMS(rtmp, bufferTime);         //第一次执行         if (first)       {         first  0;         RTMP_LogPrintf(开始建立连接\n);         //-----------------         rtmp.dlg-AppendCInfo(开始建立连接NetConnection...);         //-----------------------------         //建立连接(Connect)         if (!RTMP_Connect(rtmp, NULL))           {               //-----------------               rtmp.dlg-AppendCInfo(建立连接NetConnection失败);               //-----------------------------             nStatus  RD_FAILED;             break;           }         //-----------------         rtmp.dlg-AppendCInfo(成功建立连接NetConnection);         //-----------------------------         //RTMP_Log(RTMP_LOGINFO, 已链接...);            // User defined seek offset         if (dStartOffset  0)           {             // Dont need the start offset if resuming an existing file             if (bResume)           {             RTMP_Log(RTMP_LOGWARNING,                 Cant seek a resumed stream, ignoring --start option);             dStartOffset  0;           }             else           {             dSeek  dStartOffset;           }           }            // Calculate the length of the stream to still play         if (dStopOffset  0)           {             // Quit if start seek is past required stop offset             if (dStopOffset  dSeek)           {             RTMP_LogPrintf(Already Completed\n);             nStatus  RD_SUCCESS;             break;           }           }         //创建流(Stream)发送connect命令消息后处理传来的数据         itoa(rtmp.m_inChunkSize,temp,10);         rtmp.dlg-AppendB_R_Info(输入Chunk大小,temp);         itoa(rtmp.m_outChunkSize,temp,10);         rtmp.dlg-AppendB_R_Info(输出Chunk大小,temp);         itoa(rtmp.m_stream_id,temp,10);         rtmp.dlg-AppendB_R_Info(Stream ID,temp);         itoa(rtmp.m_nBufferMS,temp,10);         rtmp.dlg-AppendB_R_Info(Buffer时长ms,temp);         itoa(rtmp.m_nServerBW,temp,10);         rtmp.dlg-AppendB_R_Info(ServerBW,temp);         itoa(rtmp.m_nClientBW,temp,10);         rtmp.dlg-AppendB_R_Info(ClientBW,temp);         itoa((int)rtmp.m_fEncoding,temp,10);         rtmp.dlg-AppendB_R_Info(命令消息编码方法,temp);         itoa((int)rtmp.m_fDuration,temp,10);         rtmp.dlg-AppendB_R_Info(时长s,temp);            rtmp.dlg-ShowBInfo();         free(temp);         //-----------------         rtmp.dlg-AppendCInfo(开始建立网络流NetStream);         //-----------------------------         if (!RTMP_ConnectStream(rtmp, dSeek))           {           //-----------------           rtmp.dlg-AppendCInfo(建立网络流NetStream失败);           //-----------------             nStatus  RD_FAILED;             break;           }         //-----------------         rtmp.dlg-AppendCInfo(成功建立网络流NetStream);         //-----------------       }         else       {         nInitialFrameSize  0;                if (retries)               {             RTMP_Log(RTMP_LOGERROR, Failed to resume the stream\n\n);             if (!RTMP_IsTimedout(rtmp))               nStatus  RD_FAILED;             else               nStatus  RD_INCOMPLETE;             break;               }         RTMP_Log(RTMP_LOGINFO, Connection timed out, trying to resume.\n\n);             /* Did we already try pausing, and it still didnt work? */             if (rtmp.m_pausing  3)               {                 /* Only one try at reconnecting... */                 retries  1;                 dSeek  rtmp.m_pauseStamp;                 if (dStopOffset  0)                   {                     if (dStopOffset  dSeek)                       {                         RTMP_LogPrintf(Already Completed\n);                 nStatus  RD_SUCCESS;                 break;                       }                   }                 if (!RTMP_ReconnectStream(rtmp, dSeek))                   {                 RTMP_Log(RTMP_LOGERROR, Failed to resume the stream\n\n);                 if (!RTMP_IsTimedout(rtmp))               nStatus  RD_FAILED;                 else               nStatus  RD_INCOMPLETE;                 break;                   }               }         else if (!RTMP_ToggleStream(rtmp))           {             RTMP_Log(RTMP_LOGERROR, Failed to resume the stream\n\n);             if (!RTMP_IsTimedout(rtmp))           nStatus  RD_FAILED;             else           nStatus  RD_INCOMPLETE;             break;           }         bResume  TRUE;       }       //-----------------              //-----------------       rtmp.dlg-AppendCInfo(开始将媒体数据写入文件);       //-----------------         //下载,写入文件         nStatus  Download(rtmp, file, dSeek, dStopOffset, duration, bResume,                metaHeader, nMetaHeaderSize, initialFrame,                initialFrameType, nInitialFrameSize,                nSkipKeyFrames, bStdoutMode, bLiveStream, bHashes,                bOverrideBufferTime, bufferTime, percent);         free(initialFrame);         initialFrame  NULL;            /* If we succeeded, were done.         */         if (nStatus ! RD_INCOMPLETE || !RTMP_IsTimedout(rtmp) || bLiveStream)       break;       }       //当下载完的时候     if (nStatus  RD_SUCCESS)       {           //-----------------           rtmp.dlg-AppendCInfo(写入文件完成);           //-----------------         RTMP_LogPrintf(Download complete\n);       }       //没下载完的时候     else if (nStatus  RD_INCOMPLETE)       {           //-----------------           rtmp.dlg-AppendCInfo(写入文件可能不完整);           //-----------------         RTMP_LogPrintf       (Download may be incomplete (downloaded about %.2f%%), try resuming\n,        percent);       }     //后续清理工作   clean:     //-----------------     rtmp.dlg-AppendCInfo(关闭连接);     //-----------------     RTMP_Log(RTMP_LOGDEBUG, Closing connection.\n);     RTMP_Close(rtmp);     rtmp.dlg-AppendCInfo(关闭文件);     if (file ! 0)       fclose(file);     rtmp.dlg-AppendCInfo(关闭Socket);     CleanupSockets();      #ifdef _DEBUG     if (netstackdump ! 0)       fclose(netstackdump);     if (netstackdump_read ! 0)       fclose(netstackdump_read);   #endif     return nStatus;   }   其中InitSocket()代码很简单初始化了Socket如下 [cpp] view plaincopy // 初始化 sockets   int   InitSockets()   {   #ifdef WIN32     WORD version;     WSADATA wsaData;        version  MAKEWORD(1, 1);     return (WSAStartup(version, wsaData)  0);   #else     return TRUE;   #endif   }   CleanupSockets()则更简单[cpp] view plaincopy inline void   CleanupSockets()   {   #ifdef WIN32     WSACleanup();   #endif   }   Download()函数则比较复杂 [cpp] view plaincopy int   Download(RTMP * rtmp,       // connected RTMP object        FILE * file, uint32_t dSeek, uint32_t dStopOffset, double duration, int bResume, char *metaHeader, uint32_t nMetaHeaderSize, char *initialFrame, int initialFrameType, uint32_t nInitialFrameSize, int nSkipKeyFrames, int bStdoutMode, int bLiveStream, int bHashes, int bOverrideBufferTime, uint32_t bufferTime, double *percent)   // percentage downloaded [out]   {     int32_t now, lastUpdate;     int bufferSize  64 * 1024;     char *buffer  (char *) malloc(bufferSize);     int nRead  0;        //long ftell(FILE *stream);     //返回当前文件指针     RTMP_LogPrintf(开始下载\n);     off_t size  ftello(file);     unsigned long lastPercent  0;     //时间戳     rtmp-m_read.timestamp  dSeek;        *percent  0.0;        if (rtmp-m_read.timestamp)       {         RTMP_Log(RTMP_LOGDEBUG, Continuing at TS: %d ms\n, rtmp-m_read.timestamp);       }     //是直播     if (bLiveStream)       {         RTMP_LogPrintf(直播流\n);       }     else       {         // print initial status         // Workaround to exit with 0 if the file is fully ( 99.9%) downloaded         if (duration  0)       {         if ((double) rtmp-m_read.timestamp  (double) duration * 999.0)           {             RTMP_LogPrintf(Already Completed at: %.3f sec Duration%.3f sec\n,               (double) rtmp-m_read.timestamp / 1000.0,               (double) duration / 1000.0);             return RD_SUCCESS;           }         else           {             *percent  ((double) rtmp-m_read.timestamp) / (duration * 1000.0) * 100.0;             *percent  ((double) (int) (*percent * 10.0)) / 10.0;             RTMP_LogPrintf(%s download at: %.3f kB / %.3f sec (%.1f%%)\n,               bResume ? Resuming : Starting,               (double) size / 1024.0, (double) rtmp-m_read.timestamp / 1000.0,               *percent);           }       }         else       {         RTMP_LogPrintf(%s download at: %.3f kB\n,               bResume ? Resuming : Starting,               (double) size / 1024.0);       }       }        if (dStopOffset  0)       RTMP_LogPrintf(For duration: %.3f sec\n, (double) (dStopOffset - dSeek) / 1000.0);        //各种设置参数到rtmp连接     if (bResume  nInitialFrameSize  0)     rtmp-m_read.flags | RTMP_READ_RESUME;     rtmp-m_read.initialFrameType  initialFrameType;     rtmp-m_read.nResumeTS  dSeek;     rtmp-m_read.metaHeader  metaHeader;     rtmp-m_read.initialFrame  initialFrame;     rtmp-m_read.nMetaHeaderSize  nMetaHeaderSize;     rtmp-m_read.nInitialFrameSize  nInitialFrameSize;        now  RTMP_GetTime();     lastUpdate  now - 1000;     do       {       //从rtmp中把bufferSize64k个数据读入buffer         nRead  RTMP_Read(rtmp, buffer, bufferSize);         //RTMP_LogPrintf(nRead: %d\n, nRead);         if (nRead  0)       {       //函数size_t fwrite(const void* buffer,size_t size,size_t count,FILE* stream);       //向文件读入写入一个数据块。返回值返回实际写入的数据块数目       //1buffer是一个指针对fwrite来说是要输出数据的地址。       //2size要写入内容的单字节数          //3count:要进行写入size字节的数据项的个数          //4stream:目标文件指针。          //5返回实际写入的数据项个数count。       //关键。把buffer里面的数据写成文件           if (fwrite(buffer, sizeof(unsigned char), nRead, file) !             (size_t) nRead)           {             RTMP_Log(RTMP_LOGERROR, %s: Failed writing, exiting!, __FUNCTION__);             free(buffer);             return RD_FAILED;           }           //记录已经写入的字节数         size  nRead;            //RTMP_LogPrintf(write %dbytes (%.1f kB)\n, nRead, nRead/1024.0);         if (duration  0) // if duration unknown try to get it from the stream (onMetaData)           duration  RTMP_GetDuration(rtmp);            if (duration  0)           {             // make sure we claim to have enough buffer time!             if (!bOverrideBufferTime  bufferTime  (duration * 1000.0))           {             bufferTime  (uint32_t) (duration * 1000.0)  5000;   // 再加5s以确保buffertime足够长                RTMP_Log(RTMP_LOGDEBUG,                 Detected that buffer time is less than duration, resetting to: %dms,                 bufferTime);             //重设Buffer长度             RTMP_SetBufferMS(rtmp, bufferTime);             //给服务器发送UserControl消息通知Buffer改变             RTMP_UpdateBufferMS(rtmp);           }             //计算百分比             *percent  ((double) rtmp-m_read.timestamp) / (duration * 1000.0) * 100.0;             *percent  ((double) (int) (*percent * 10.0)) / 10.0;             if (bHashes)           {             if (lastPercent  1  *percent)               {                 RTMP_LogStatus(#);                 lastPercent  (unsigned long) *percent;               }           }             else           {               //设置显示数据的更新间隔200ms             now  RTMP_GetTime();             if (abs(now - lastUpdate)  200)               {                 RTMP_LogStatus(\r%.3f kB / %.2f sec (%.1f%%),                   (double) size / 1024.0,                   (double) (rtmp-m_read.timestamp) / 1000.0, *percent);                 lastUpdate  now;               }           }           }         else           {           //现在距离开机的毫秒数             now  RTMP_GetTime();             //每间隔200ms刷新一次数据             if (abs(now - lastUpdate)  200)           {             if (bHashes)               RTMP_LogStatus(#);             else               //size为已写入文件的字节数               RTMP_LogStatus(\r%.3f kB / %.2f sec, (double) size / 1024.0,                     (double) (rtmp-m_read.timestamp) / 1000.0);             lastUpdate  now;           }           }       }   #ifdef _DEBUG         else       {         RTMP_Log(RTMP_LOGDEBUG, zero read!);       }   #endif          }     while (!RTMP_ctrlC  nRead  -1  RTMP_IsConnected(rtmp)  !RTMP_IsTimedout(rtmp));     free(buffer);     if (nRead  0)       //nRead是读取情况       nRead  rtmp-m_read.status;        /* Final status update */     if (!bHashes)       {         if (duration  0)       {         *percent  ((double) rtmp-m_read.timestamp) / (duration * 1000.0) * 100.0;         *percent  ((double) (int) (*percent * 10.0)) / 10.0;         //输出         RTMP_LogStatus(\r%.3f kB / %.2f sec (%.1f%%),           (double) size / 1024.0,           (double) (rtmp-m_read.timestamp) / 1000.0, *percent);       }         else       {         RTMP_LogStatus(\r%.3f kB / %.2f sec, (double) size / 1024.0,           (double) (rtmp-m_read.timestamp) / 1000.0);       }       }        RTMP_Log(RTMP_LOGDEBUG, RTMP_Read returned: %d, nRead);     //读取错误     if (bResume  nRead  -2)       {         RTMP_LogPrintf(Couldnt resume FLV file, try --skip %d\n\n,           nSkipKeyFrames  1);         return RD_FAILED;       }     //读取正确     if (nRead  -3)       return RD_SUCCESS;     //没读完...     if ((duration  0  *percent  99.9) || RTMP_ctrlC || nRead  0         || RTMP_IsTimedout(rtmp))       {         return RD_INCOMPLETE;       }        return RD_SUCCESS;   }   以上内容是我能理解到的rtmpdump.c里面的内容。
http://www.ihoyoo.com/news/44100.html

相关文章:

  • 百度海外视频网站建设三d全景网站建设
  • 阿里云做影视网站天津网站推广优化
  • 国外网站推广如何做机关单位不得建设网站
  • 阿里云 发布网站 教程设置wordpress
  • 网站用什么切版园林公司网站模板
  • 郑州餐饮网站建设公司排名下载app赚钱的平台
  • 网站子站怎么建设网络营销的效果是什么
  • 一些网站只能在微信打开怎么做的德州网络
  • 网站优化如何提高排名狮山建网站
  • 网站内部链接导向网站开发jsp需要什么jar包
  • 德网站建设个体工商户如何注销
  • 美橙网站建设经典案例郫都区网站建设
  • 免费网站建设浩森宇特红旗网站建设
  • 网站开发单子商洛市住户和城乡建设局网站信息价
  • 做装修哪个网站推广好工作纪律心得体会
  • 公司注销的网站备案食品包装设计展开图片
  • wordpress数据爬虫上海建站seo
  • 加盟网站建设印团网网站是哪家做的
  • 网站建设是基础服务吗实验室网站建设的调查报告
  • 建设门户网站申请报告关于网站建设的职位
  • 马鞍山建设工程监督站建管处网站桂林网站建设科技有限公司
  • 徐汇网站推广window2008r2网站建设
  • 个别网站网速慢怎么做温州专业手机网站制作哪家便宜
  • wordpress网站数据单位邮箱怎么注册
  • 网站开发需要注册几类商标wap网站建设设计
  • 上传网站页面打不开怎么办铜仁市建设招投标网站
  • 翡翠原石网站首页怎么做玉田县建设工程招标网站
  • 杭州建站模板wordpress重复评论
  • 网站开发费属于无形资产那部分广州网站建设互广
  • 绍兴网站开发名费网站制作视频教程