【流媒体】RTMPDump—Download(接收流媒体信息)

诗林  金牌会员 | 2024-8-19 18:37:57 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 350|帖子 350|积分 1050

RTMP协议相干:
【流媒体】RTMP协议概述
【流媒体】RTMP协议的数据格式
【流媒体】RTMP协议的消息类型
【流媒体】RTMPDump—主流程简单分析
【流媒体】RTMPDump—RTMP_Connect函数(握手、网络连接)
【流媒体】RTMPDump—RTMP_ConnectStream(创建流连接)
参考雷博的系列文章(可以从一篇链接到其他文章):
RTMPdump 源代码分析 1: main()函数
在举行流连接之后,还可以举行传输过来数据的下载,实行这一功能的函数是Download(),其中使用RTMP_Read()读取数据,随后使用fwrite写入文件。写入文件通常是FLV格式,如果没有指定这个file,则会默认写到stdout
  1. int
  2. Download(RTMP * rtmp,                // connected RTMP object
  3.         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 bRealtimeStream, int bHashes, int bOverrideBufferTime, uint32_t bufferTime, double* percent)        // percentage downloaded [out]
  4. {
  5.         int32_t now, lastUpdate;
  6.         int bufferSize = 64 * 1024;
  7.         char* buffer;
  8.         int nRead = 0;
  9.         off_t size = ftello(file);
  10.         unsigned long lastPercent = 0;
  11.         rtmp->m_read.timestamp = dSeek;
  12.         *percent = 0.0;
  13.         if (rtmp->m_read.timestamp)
  14.         {
  15.                 RTMP_Log(RTMP_LOGDEBUG, "Continuing at TS: %d ms\n", rtmp->m_read.timestamp);
  16.         }
  17.         if (bLiveStream)
  18.         {
  19.                 RTMP_LogPrintf("Starting Live Stream\n");
  20.         }
  21.         else
  22.         {
  23.                 // print initial status
  24.                 // Workaround to exit with 0 if the file is fully (> 99.9%) downloaded
  25.                 if (duration > 0)
  26.                 {
  27.                         if ((double)rtmp->m_read.timestamp >= (double)duration * 999.0)
  28.                         {
  29.                                 RTMP_LogPrintf("Already Completed at: %.3f sec Duration=%.3f sec\n",
  30.                                         (double)rtmp->m_read.timestamp / 1000.0,
  31.                                         (double)duration / 1000.0);
  32.                                 return RD_SUCCESS;
  33.                         }
  34.                         else
  35.                         {
  36.                                 *percent = ((double)rtmp->m_read.timestamp) / (duration * 1000.0) * 100.0;
  37.                                 *percent = ((double)(int)(*percent * 10.0)) / 10.0;
  38.                                 RTMP_LogPrintf("%s download at: %.3f kB / %.3f sec (%.1f%%)\n",
  39.                                         bResume ? "Resuming" : "Starting",
  40.                                         (double)size / 1024.0, (double)rtmp->m_read.timestamp / 1000.0,
  41.                                         *percent);
  42.                         }
  43.                 }
  44.                 else
  45.                 {
  46.                         RTMP_LogPrintf("%s download at: %.3f kB\n",
  47.                                 bResume ? "Resuming" : "Starting",
  48.                                 (double)size / 1024.0);
  49.                 }
  50.                 if (bRealtimeStream)
  51.                         RTMP_LogPrintf("  in approximately realtime (disabled BUFX speedup hack)\n");
  52.         }
  53.         if (dStopOffset > 0)
  54.                 RTMP_LogPrintf("For duration: %.3f sec\n", (double)(dStopOffset - dSeek) / 1000.0);
  55.         if (bResume && nInitialFrameSize > 0)
  56.                 rtmp->m_read.flags |= RTMP_READ_RESUME;
  57.         rtmp->m_read.initialFrameType = initialFrameType;
  58.         rtmp->m_read.nResumeTS = dSeek;
  59.         rtmp->m_read.metaHeader = metaHeader;
  60.         rtmp->m_read.initialFrame = initialFrame;
  61.         rtmp->m_read.nMetaHeaderSize = nMetaHeaderSize;
  62.         rtmp->m_read.nInitialFrameSize = nInitialFrameSize;
  63.         buffer = (char*)malloc(bufferSize);
  64.         now = RTMP_GetTime();
  65.         lastUpdate = now - 1000;
  66.         do
  67.         {
  68.                 // 读取信息
  69.                 nRead = RTMP_Read(rtmp, buffer, bufferSize);
  70.                 //RTMP_LogPrintf("nRead: %d\n", nRead);
  71.                 if (nRead > 0)
  72.                 {
  73.                         // 将数据写入到file当中,FLV格式
  74.                         // 如果这个file没有指定,默认是stdout
  75.                         if (fwrite(buffer, sizeof(unsigned char), nRead, file) !=
  76.                                 (size_t)nRead)
  77.                         {
  78.                                 RTMP_Log(RTMP_LOGERROR, "%s: Failed writing, exiting!", __FUNCTION__);
  79.                                 free(buffer);
  80.                                 return RD_FAILED;
  81.                         }
  82.                         size += nRead;
  83.                         //RTMP_LogPrintf("write %dbytes (%.1f kB)\n", nRead, nRead/1024.0);
  84.                         if (duration <= 0)        // if duration unknown try to get it from the stream (onMetaData)
  85.                                 duration = RTMP_GetDuration(rtmp);
  86.                         if (duration > 0)
  87.                         {
  88.                                 // make sure we claim to have enough buffer time!
  89.                                 if (!bOverrideBufferTime && bufferTime < (duration * 1000.0))
  90.                                 {
  91.                                         bufferTime = (uint32_t)(duration * 1000.0) + 5000;        // extra 5sec to make sure we've got enough
  92.                                         RTMP_Log(RTMP_LOGDEBUG,
  93.                                                 "Detected that buffer time is less than duration, resetting to: %dms",
  94.                                                 bufferTime);
  95.                                         RTMP_SetBufferMS(rtmp, bufferTime);
  96.                                         RTMP_UpdateBufferMS(rtmp);
  97.                                 }
  98.                                 *percent = ((double)rtmp->m_read.timestamp) / (duration * 1000.0) * 100.0;
  99.                                 *percent = ((double)(int)(*percent * 10.0)) / 10.0;
  100.                                 if (bHashes)
  101.                                 {
  102.                                         if (lastPercent + 1 <= *percent)
  103.                                         {
  104.                                                 RTMP_LogStatus("#");
  105.                                                 lastPercent = (unsigned long)* percent;
  106.                                         }
  107.                                 }
  108.                                 else
  109.                                 {
  110.                                         now = RTMP_GetTime();
  111.                                         if (abs(now - lastUpdate) > 200)
  112.                                         {
  113.                                                 RTMP_LogStatus("\r%.3f kB / %.2f sec (%.1f%%)",
  114.                                                         (double)size / 1024.0,
  115.                                                         (double)(rtmp->m_read.timestamp) / 1000.0, *percent);
  116.                                                 lastUpdate = now;
  117.                                         }
  118.                                 }
  119.                         }
  120.                         else
  121.                         {
  122.                                 now = RTMP_GetTime();
  123.                                 if (abs(now - lastUpdate) > 200)
  124.                                 {
  125.                                         if (bHashes)
  126.                                                 RTMP_LogStatus("#");
  127.                                         else
  128.                                                 RTMP_LogStatus("\r%.3f kB / %.2f sec", (double)size / 1024.0,
  129.                                                 (double)(rtmp->m_read.timestamp) / 1000.0);
  130.                                         lastUpdate = now;
  131.                                 }
  132.                         }
  133.                 }
  134.                 else
  135.                 {
  136. #ifdef _DEBUG
  137.                         RTMP_Log(RTMP_LOGDEBUG, "zero read!");
  138. #endif
  139.                         if (rtmp->m_read.status == RTMP_READ_EOF)
  140.                                 break;
  141.                 }
  142.         } while (!RTMP_ctrlC && nRead > -1 && RTMP_IsConnected(rtmp) && !RTMP_IsTimedout(rtmp));
  143.         free(buffer);
  144.         if (nRead < 0)
  145.                 nRead = rtmp->m_read.status;
  146.         /* Final status update */
  147.         if (!bHashes)
  148.         {
  149.                 if (duration > 0)
  150.                 {
  151.                         *percent = ((double)rtmp->m_read.timestamp) / (duration * 1000.0) * 100.0;
  152.                         *percent = ((double)(int)(*percent * 10.0)) / 10.0;
  153.                         RTMP_LogStatus("\r%.3f kB / %.2f sec (%.1f%%)",
  154.                                 (double)size / 1024.0,
  155.                                 (double)(rtmp->m_read.timestamp) / 1000.0, *percent);
  156.                 }
  157.                 else
  158.                 {
  159.                         RTMP_LogStatus("\r%.3f kB / %.2f sec", (double)size / 1024.0,
  160.                                 (double)(rtmp->m_read.timestamp) / 1000.0);
  161.                 }
  162.         }
  163.         RTMP_Log(RTMP_LOGDEBUG, "RTMP_Read returned: %d", nRead);
  164.         if (bResume && nRead == -2)
  165.         {
  166.                 RTMP_LogPrintf("Couldn't resume FLV file, try --skip %d\n\n",
  167.                         nSkipKeyFrames + 1);
  168.                 return RD_FAILED;
  169.         }
  170.         if (nRead == -3)
  171.                 return RD_SUCCESS;
  172.         if ((duration > 0 && *percent < 99.9) || RTMP_ctrlC || nRead < 0
  173.                 || RTMP_IsTimedout(rtmp))
  174.         {
  175.                 return RD_INCOMPLETE;
  176.         }
  177.         return RD_SUCCESS;
  178. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

诗林

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表