FLVReader.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #include "FLVReader.h"
  2. #include "FLVHeader.h"
  3. #include "FLVStreamheader.h"
  4. #include "BackgroundDownloader.h"
  5. #include "../nu/AutoChar.h"
  6. #include "FileProcessor.h"
  7. #include "ProgressiveProcessor.h"
  8. #include "StreamProcessor.h"
  9. #include "../../..\Components\wac_network\wac_network_http_receiver_api.h"
  10. #include <shlwapi.h>
  11. FLVReader::FLVReader(const wchar_t *_url)
  12. {
  13. processor = 0;
  14. url = _wcsdup(_url);
  15. end_of_stream=false;
  16. killswitch=false;
  17. DWORD threadId;
  18. flvThread=CreateThread(NULL, NULL, ParserThreadStub, this, 0, &threadId);
  19. SetThreadPriority(flvThread, THREAD_PRIORITY_BELOW_NORMAL);
  20. }
  21. FLVReader::~FLVReader()
  22. {
  23. free(url);
  24. delete processor;
  25. }
  26. uint64_t FLVReader::Seek(uint64_t position)
  27. {
  28. if (processor)
  29. return processor->Seek(position);
  30. else
  31. return -1;
  32. }
  33. size_t FLVReader::Read(void *data, size_t bytes)
  34. {
  35. if (processor)
  36. return processor->Read(data, bytes);
  37. else
  38. return 0;
  39. }
  40. uint64_t FLVReader::GetProcessedPosition()
  41. {
  42. if (processor)
  43. return processor->GetProcessedPosition();
  44. else
  45. return 0;
  46. }
  47. void FLVReader::ProcessFile()
  48. {
  49. if (!processor)
  50. return;
  51. while (processor->Process() == FLV_OK)
  52. {
  53. if (killswitch)
  54. return ;
  55. }
  56. }
  57. int FLVReader::OnConnect(api_httpreceiver *http)
  58. {
  59. if (http->content_length())
  60. processor = new ProgressiveProcessor;
  61. else
  62. processor = new StreamProcessor;
  63. return 0;
  64. }
  65. int FLVReader::OnData(void *data, size_t datalen)
  66. {
  67. if (!processor)
  68. return 1;
  69. bool needSleep=false;
  70. while (datalen)
  71. {
  72. if (killswitch)
  73. return 1;
  74. if (needSleep)
  75. {
  76. Sleep(10);
  77. needSleep=false;
  78. }
  79. size_t written=0;
  80. switch (processor->Write(data, datalen, &written))
  81. {
  82. case FLVPROCESSOR_WRITE_ERROR:
  83. return 1;
  84. case FLVPROCESSOR_WRITE_WAIT:
  85. needSleep=true;
  86. break;
  87. }
  88. datalen -= written;
  89. if (written)
  90. {
  91. while (1)
  92. {
  93. if (killswitch)
  94. return 1;
  95. int ret = processor->Process();
  96. if (ret == FLV_OK)
  97. continue;
  98. if (ret == FLV_NEED_MORE_DATA)
  99. break;
  100. if (ret == FLV_ERROR)
  101. return 1;
  102. }
  103. }
  104. }
  105. return !!killswitch;
  106. }
  107. bool FLVReader::GetFrame(size_t frameIndex, FrameData &frameData)
  108. {
  109. if (processor)
  110. return processor->GetFrame(frameIndex, frameData);
  111. else
  112. return false;
  113. }
  114. /*
  115. Test URLs (valid of as oct 23 2007)
  116. http://pdl.stream.aol.com/aol/us/aolmusic/artists/astralwerks/2220s/2220s_shootyourgun_hakjfh_700_dl.flv
  117. http://pdl.stream.aol.com/aol/us/aolmusic/sessions/2007/amberpacific/suc_amberpacific_fallbackintomylife_700_dl.flv
  118. http://pdl.stream.aol.com/aol/us/aolmusic/sessions/2007/amberpacific/suc_amberpacific_gonesoyoung_700_dl.flv
  119. http://pdl.stream.aol.com/aol/us/aolmusic/sessions/2007/amberpacific/suc_amberpacific_soyesterday_700_dl.flv
  120. http://pdl.stream.aol.com/aol/us/aolmusic/sessions/2007/amberpacific/suc_amberpacific_watchingoverme_700_dl.flv
  121. a potential crasher:
  122. http://pdl.stream.aol.com/aol/us/aolcomvideo/TVGuide/johncmcginley_6346/johncmcginley_6346_460_700_dl.flv
  123. FLV streams:
  124. http://208.80.52.96/CBS_R20_452P_F128?ext=.flv
  125. http://208.80.54.37/KROQFM?ext=.flv
  126. http://208.80.52.96/CBS_R20_568P_F128?ext=.flv
  127. */
  128. DWORD FLVReader::ParserThread()
  129. {
  130. if (PathIsURL(url))
  131. {
  132. Downloader downloader;
  133. downloader.Download(AutoChar(url), this);
  134. }
  135. else
  136. {
  137. processor = new FileProcessor(url);
  138. ProcessFile();
  139. }
  140. end_of_stream=true;
  141. return 0;
  142. }
  143. void FLVReader::Kill()
  144. {
  145. killswitch=true;
  146. WaitForSingleObject(flvThread, INFINITE);
  147. CloseHandle(flvThread);
  148. }
  149. void FLVReader::SignalKill()
  150. {
  151. killswitch=true;
  152. }
  153. bool FLVReader::IsEOF()
  154. {
  155. return end_of_stream;
  156. }
  157. bool FLVReader::GetPosition(int time_in_ms, size_t *frameIndex, bool needVideoKeyFrame)
  158. {
  159. if (processor)
  160. return processor->GetPosition(time_in_ms, frameIndex, needVideoKeyFrame);
  161. else
  162. return false;
  163. }
  164. uint32_t FLVReader::GetMaxTimestamp()
  165. {
  166. if (processor)
  167. return processor->GetMaxTimestamp();
  168. else
  169. return 0;
  170. }
  171. bool FLVReader::IsStreaming()
  172. {
  173. if (processor)
  174. return processor->IsStreaming();
  175. else
  176. return true;
  177. }
  178. FLVHeader *FLVReader::GetHeader()
  179. {
  180. if (processor)
  181. return processor->GetHeader();
  182. else
  183. return 0;
  184. }