Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

133 строки
3.4KB

  1. #include "sockutil.h"
  2. #include "rtmp-server.h"
  3. #include "flv-reader.h"
  4. #include "flv-proto.h"
  5. #include "sys/thread.h"
  6. #include "sys/system.h"
  7. #include <string.h>
  8. #include <assert.h>
  9. static pthread_t t;
  10. static rtmp_server_t* s_rtmp;
  11. static const char* s_file;
  12. static int STDCALL rtmp_server_worker(void* param)
  13. {
  14. int r, type;
  15. size_t taglen;
  16. uint32_t timestamp;
  17. static uint64_t clock0 = system_clock() - 200; // send more data, open fast
  18. void* f = flv_reader_create(s_file);
  19. static unsigned char packet[8 * 1024 * 1024];
  20. while (1 == flv_reader_read(f, &type, &timestamp, &taglen, packet, sizeof(packet)))
  21. {
  22. assert(taglen < sizeof(packet));
  23. uint64_t t = system_clock();
  24. if (clock0 + timestamp > t && clock0 + timestamp < t + 3 * 1000)
  25. system_sleep(clock0 + timestamp - t);
  26. else if (clock0 + timestamp > t + 3 * 1000)
  27. clock0 = t - timestamp;
  28. if (FLV_TYPE_AUDIO == type)
  29. {
  30. r = rtmp_server_send_audio(s_rtmp, packet, taglen, timestamp);
  31. }
  32. else if (FLV_TYPE_VIDEO == type)
  33. {
  34. r = rtmp_server_send_video(s_rtmp, packet, taglen, timestamp);
  35. }
  36. else if (FLV_TYPE_SCRIPT == type)
  37. {
  38. r = rtmp_server_send_script(s_rtmp, packet, taglen, timestamp);
  39. }
  40. else
  41. {
  42. assert(0);
  43. r = 0;
  44. }
  45. if (0 != r)
  46. {
  47. assert(0);
  48. break; // TODO: handle send failed
  49. }
  50. }
  51. flv_reader_destroy(f);
  52. thread_destroy(t);
  53. return 0;
  54. }
  55. static int rtmp_server_send(void* param, const void* header, size_t len, const void* data, size_t bytes)
  56. {
  57. socket_t* socket = (socket_t*)param;
  58. socket_bufvec_t vec[2];
  59. socket_setbufvec(vec, 0, (void*)header, len);
  60. socket_setbufvec(vec, 1, (void*)data, bytes);
  61. return socket_send_v_all_by_time(*socket, vec, bytes > 0 ? 2 : 1, 0, 20000);
  62. }
  63. static int rtmp_server_onplay(void* param, const char* app, const char* stream, double start, double duration, uint8_t reset)
  64. {
  65. printf("rtmp_server_onplay(%s, %s, %f, %f, %d)\n", app, stream, start, duration, (int)reset);
  66. return thread_create(&t, rtmp_server_worker, param);
  67. }
  68. static int rtmp_server_onpause(void* param, int pause, uint32_t ms)
  69. {
  70. printf("rtmp_server_onpause(%d, %u)\n", pause, (unsigned int)ms);
  71. return 0;
  72. }
  73. static int rtmp_server_onseek(void* param, uint32_t ms)
  74. {
  75. printf("rtmp_server_onseek(%u)\n", (unsigned int)ms);
  76. return 0;
  77. }
  78. static int rtmp_server_ongetduration(void* param, const char* app, const char* stream, double* duration)
  79. {
  80. *duration = 30 * 60;
  81. return 0;
  82. }
  83. void rtmp_server_vod_test(const char* flv)
  84. {
  85. int r;
  86. struct rtmp_server_handler_t handler;
  87. memset(&handler, 0, sizeof(handler));
  88. handler.send = rtmp_server_send;
  89. //handler.oncreate_stream = rtmp_server_oncreate_stream;
  90. //handler.ondelete_stream = rtmp_server_ondelete_stream;
  91. handler.onplay = rtmp_server_onplay;
  92. handler.onpause = rtmp_server_onpause;
  93. handler.onseek = rtmp_server_onseek;
  94. //handler.onpublish = rtmp_server_onpublish;
  95. //handler.onvideo = rtmp_server_onvideo;
  96. //handler.onaudio = rtmp_server_onaudio;
  97. handler.ongetduration = rtmp_server_ongetduration;
  98. socket_init();
  99. socklen_t n;
  100. struct sockaddr_storage ss;
  101. socket_t s = socket_tcp_listen_ipv4(NULL, 1935, SOMAXCONN);
  102. socket_t c = socket_accept(s, &ss, &n);
  103. s_file = flv;
  104. s_rtmp = rtmp_server_create(&c, &handler);
  105. static unsigned char packet[2 * 1024 * 1024];
  106. while ((r = socket_recv(c, packet, sizeof(packet), 0)) > 0)
  107. {
  108. assert(0 == rtmp_server_input(s_rtmp, packet, r));
  109. }
  110. rtmp_server_destroy(s_rtmp);
  111. socket_close(c);
  112. socket_close(s);
  113. socket_cleanup();
  114. }