2
0

srs_aac_raw_publish.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /**
  2. * The MIT License (MIT)
  3. *
  4. * Copyright (c) 2013-2018 Winlin
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  7. * this software and associated documentation files (the "Software"), to deal in
  8. * the Software without restriction, including without limitation the rights to
  9. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10. * the Software, and to permit persons to whom the Software is furnished to do so,
  11. * subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in all
  14. * copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <unistd.h>
  26. // for open audio raw file.
  27. #include <sys/types.h>
  28. #include <sys/stat.h>
  29. #include <fcntl.h>
  30. #include "../../objs/include/srs_librtmp.h"
  31. // https://github.com/ossrs/srs/issues/212#issuecomment-64145910
  32. int read_audio_frame(char* data, int size, char** pp, char** frame, int* frame_size)
  33. {
  34. char* p = *pp;
  35. // @remark, for this demo, to publish aac raw file to SRS,
  36. // we search the adts frame from the buffer which cached the aac data.
  37. // please get aac adts raw data from device, it always a encoded frame.
  38. if (!srs_aac_is_adts(p, size - (p - data))) {
  39. srs_human_trace("aac adts raw data invalid.");
  40. return -1;
  41. }
  42. // @see srs_audio_write_raw_frame
  43. // each frame prefixed aac adts header, '1111 1111 1111'B, that is 0xFFF.,
  44. // for instance, frame = FF F1 5C 80 13 A0 FC 00 D0 33 83 E8 5B
  45. *frame = p;
  46. // skip some data.
  47. // @remark, user donot need to do this.
  48. p += srs_aac_adts_frame_size(p, size - (p - data));
  49. *pp = p;
  50. *frame_size = p - *frame;
  51. if (*frame_size <= 0) {
  52. srs_human_trace("aac adts raw data invalid.");
  53. return -1;
  54. }
  55. return 0;
  56. }
  57. int main(int argc, char** argv)
  58. {
  59. printf("publish raw audio as rtmp stream to server like FMLE/FFMPEG/Encoder\n");
  60. printf("SRS(ossrs) client librtmp library.\n");
  61. printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
  62. if (argc <= 2) {
  63. printf("Usage: %s <audio_raw_file> <rtmp_publish_url>\n", argv[0]);
  64. printf(" audio_raw_file: the audio raw steam file.\n");
  65. printf(" rtmp_publish_url: the rtmp publish url.\n");
  66. printf("For example:\n");
  67. printf(" %s ./audio.raw.aac rtmp://127.0.0.1:1935/live/livestream\n", argv[0]);
  68. printf("Where the file: http://winlinvip.github.io/srs.release/3rdparty/audio.raw.aac\n");
  69. printf("See: https://github.com/ossrs/srs/issues/212\n");
  70. exit(-1);
  71. }
  72. const char* raw_file = argv[1];
  73. const char* rtmp_url = argv[2];
  74. srs_human_trace("raw_file=%s, rtmp_url=%s", raw_file, rtmp_url);
  75. // open file
  76. int raw_fd = open(raw_file, O_RDONLY);
  77. if (raw_fd < 0) {
  78. srs_human_trace("open audio raw file %s failed.", raw_file);
  79. goto rtmp_destroy;
  80. }
  81. off_t file_size = lseek(raw_fd, 0, SEEK_END);
  82. if (file_size <= 0) {
  83. srs_human_trace("audio raw file %s empty.", raw_file);
  84. goto rtmp_destroy;
  85. }
  86. srs_human_trace("read entirely audio raw file, size=%dKB", (int)(file_size / 1024));
  87. char* audio_raw = (char*)malloc(file_size);
  88. if (!audio_raw) {
  89. srs_human_trace("alloc raw buffer failed for file %s.", raw_file);
  90. goto rtmp_destroy;
  91. }
  92. lseek(raw_fd, 0, SEEK_SET);
  93. ssize_t nb_read = 0;
  94. if ((nb_read = read(raw_fd, audio_raw, file_size)) != file_size) {
  95. srs_human_trace("buffer %s failed, expect=%dKB, actual=%dKB.",
  96. raw_file, (int)(file_size / 1024), (int)(nb_read / 1024));
  97. goto rtmp_destroy;
  98. }
  99. // connect rtmp context
  100. srs_rtmp_t rtmp = srs_rtmp_create(rtmp_url);
  101. if (srs_rtmp_handshake(rtmp) != 0) {
  102. srs_human_trace("simple handshake failed.");
  103. goto rtmp_destroy;
  104. }
  105. srs_human_trace("simple handshake success");
  106. if (srs_rtmp_connect_app(rtmp) != 0) {
  107. srs_human_trace("connect vhost/app failed.");
  108. goto rtmp_destroy;
  109. }
  110. srs_human_trace("connect vhost/app success");
  111. if (srs_rtmp_publish_stream(rtmp) != 0) {
  112. srs_human_trace("publish stream failed.");
  113. goto rtmp_destroy;
  114. }
  115. srs_human_trace("publish stream success");
  116. uint32_t timestamp = 0;
  117. uint32_t time_delta = 45;
  118. // @remark, to decode the file.
  119. char* p = audio_raw;
  120. for (;p < audio_raw + file_size;) {
  121. // @remark, read a frame from file buffer.
  122. char* data = NULL;
  123. int size = 0;
  124. if (read_audio_frame(audio_raw, file_size, &p, &data, &size) < 0) {
  125. srs_human_trace("read a frame from file buffer failed.");
  126. goto rtmp_destroy;
  127. }
  128. // 0 = Linear PCM, platform endian
  129. // 1 = ADPCM
  130. // 2 = MP3
  131. // 7 = G.711 A-law logarithmic PCM
  132. // 8 = G.711 mu-law logarithmic PCM
  133. // 10 = AAC
  134. // 11 = Speex
  135. char sound_format = 10;
  136. // 2 = 22 kHz
  137. char sound_rate = 2;
  138. // 1 = 16-bit samples
  139. char sound_size = 1;
  140. // 1 = Stereo sound
  141. char sound_type = 1;
  142. timestamp += time_delta;
  143. int ret = 0;
  144. if ((ret = srs_audio_write_raw_frame(rtmp, sound_format, sound_rate, sound_size, sound_type, data, size, timestamp)) != 0) {
  145. srs_human_trace("send audio raw data failed. ret=%d", ret);
  146. goto rtmp_destroy;
  147. }
  148. srs_human_trace("sent packet: type=%s, time=%d, size=%d, codec=%d, rate=%d, sample=%d, channel=%d",
  149. srs_human_flv_tag_type2string(SRS_RTMP_TYPE_AUDIO), timestamp, size, sound_format, sound_rate, sound_size,
  150. sound_type);
  151. // @remark, when use encode device, it not need to sleep.
  152. usleep(1000 * time_delta);
  153. }
  154. rtmp_destroy:
  155. srs_rtmp_destroy(rtmp);
  156. close(raw_fd);
  157. free(audio_raw);
  158. return 0;
  159. }