You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

207 lines
4.8KB

  1. /*
  2. * RTMP network protocol
  3. * Copyright (c) 2010 Howard Chu
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. /**
  22. * @file libavformat/librtmp.c
  23. * RTMP protocol based on http://rtmpdump.mplayerhq.hu librtmp
  24. */
  25. #include "avformat.h"
  26. #include <librtmp/rtmp.h>
  27. #include <librtmp/log.h>
  28. static int rtmp_close(URLContext *s)
  29. {
  30. RTMP *r = s->priv_data;
  31. RTMP_Close(r);
  32. av_free(r);
  33. return 0;
  34. }
  35. /**
  36. * Opens RTMP connection and verifies that the stream can be played.
  37. *
  38. * URL syntax: rtmp://server[:port][/app][/playpath][ keyword=value]...
  39. * where 'app' is first one or two directories in the path
  40. * (e.g. /ondemand/, /flash/live/, etc.)
  41. * and 'playpath' is a file name (the rest of the path,
  42. * may be prefixed with "mp4:")
  43. *
  44. * Additional RTMP library options may be appended as
  45. * space-separated key-value pairs.
  46. */
  47. static int rtmp_open(URLContext *s, const char *uri, int flags)
  48. {
  49. RTMP *r;
  50. int rc;
  51. r = av_mallocz(sizeof(RTMP));
  52. if (!r)
  53. return AVERROR(ENOMEM);
  54. switch(av_log_get_level()) {
  55. default:
  56. case AV_LOG_FATAL: rc = RTMP_LOGCRIT; break;
  57. case AV_LOG_ERROR: rc = RTMP_LOGERROR; break;
  58. case AV_LOG_WARNING: rc = RTMP_LOGWARNING; break;
  59. case AV_LOG_INFO: rc = RTMP_LOGINFO; break;
  60. case AV_LOG_VERBOSE: rc = RTMP_LOGDEBUG; break;
  61. case AV_LOG_DEBUG: rc = RTMP_LOGDEBUG2; break;
  62. }
  63. RTMP_LogSetLevel(rc);
  64. RTMP_Init(r);
  65. if (!RTMP_SetupURL(r, s->filename)) {
  66. rc = -1;
  67. goto fail;
  68. }
  69. if (flags & URL_WRONLY)
  70. r->Link.protocol |= RTMP_FEATURE_WRITE;
  71. if (!RTMP_Connect(r, NULL) || !RTMP_ConnectStream(r, 0)) {
  72. rc = -1;
  73. goto fail;
  74. }
  75. s->priv_data = r;
  76. s->is_streamed = 1;
  77. return 0;
  78. fail:
  79. av_free(r);
  80. return rc;
  81. }
  82. static int rtmp_write(URLContext *s, uint8_t *buf, int size)
  83. {
  84. RTMP *r = s->priv_data;
  85. return RTMP_Write(r, buf, size);
  86. }
  87. static int rtmp_read(URLContext *s, uint8_t *buf, int size)
  88. {
  89. RTMP *r = s->priv_data;
  90. return RTMP_Read(r, buf, size);
  91. }
  92. static int rtmp_read_pause(URLContext *s, int pause)
  93. {
  94. RTMP *r = s->priv_data;
  95. if (pause)
  96. r->m_pauseStamp =
  97. r->m_channelTimestamp[r->m_mediaChannel];
  98. if (!RTMP_SendPause(r, pause, r->m_pauseStamp))
  99. return -1;
  100. return 0;
  101. }
  102. static int64_t rtmp_read_seek(URLContext *s, int stream_index,
  103. int64_t timestamp, int flags)
  104. {
  105. RTMP *r = s->priv_data;
  106. if (flags & AVSEEK_FLAG_BYTE)
  107. return AVERROR_NOTSUPP;
  108. /* seeks are in milliseconds */
  109. timestamp = av_rescale(timestamp, AV_TIME_BASE, 1000);
  110. if (!RTMP_SendSeek(r, timestamp))
  111. return -1;
  112. return timestamp;
  113. }
  114. static int rtmp_get_file_handle(URLContext *s)
  115. {
  116. RTMP *r = s->priv_data;
  117. return r->m_sb.sb_socket;
  118. }
  119. URLProtocol rtmp_protocol = {
  120. "rtmp",
  121. rtmp_open,
  122. rtmp_read,
  123. rtmp_write,
  124. NULL, /* seek */
  125. rtmp_close,
  126. NULL, /* next */
  127. rtmp_read_pause,
  128. rtmp_read_seek,
  129. rtmp_get_file_handle
  130. };
  131. URLProtocol rtmpt_protocol = {
  132. "rtmpt",
  133. rtmp_open,
  134. rtmp_read,
  135. rtmp_write,
  136. NULL, /* seek */
  137. rtmp_close,
  138. NULL, /* next */
  139. rtmp_read_pause,
  140. rtmp_read_seek,
  141. rtmp_get_file_handle
  142. };
  143. URLProtocol rtmpe_protocol = {
  144. "rtmpe",
  145. rtmp_open,
  146. rtmp_read,
  147. rtmp_write,
  148. NULL, /* seek */
  149. rtmp_close,
  150. NULL, /* next */
  151. rtmp_read_pause,
  152. rtmp_read_seek,
  153. rtmp_get_file_handle
  154. };
  155. URLProtocol rtmpte_protocol = {
  156. "rtmpte",
  157. rtmp_open,
  158. rtmp_read,
  159. rtmp_write,
  160. NULL, /* seek */
  161. rtmp_close,
  162. NULL, /* next */
  163. rtmp_read_pause,
  164. rtmp_read_seek,
  165. rtmp_get_file_handle
  166. };
  167. URLProtocol rtmps_protocol = {
  168. "rtmps",
  169. rtmp_open,
  170. rtmp_read,
  171. rtmp_write,
  172. NULL, /* seek */
  173. rtmp_close,
  174. NULL, /* next */
  175. rtmp_read_pause,
  176. rtmp_read_seek,
  177. rtmp_get_file_handle
  178. };