Free and Open-source video streaming suite. https://miracle-tv.live
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.

190 lines
6.6 KiB

  1. # vim: set filetype=nginx.conf
  2. # Major portions stolen from the following link:
  3. # https://github.com/TareqAlqutami/rtmp-hls-server/blob/master/conf/nginx.conf
  4. # which is licensed under MIT.
  5. # This config does the following:
  6. # 1. Requires streams to go to /miracle, where the stream key is checked.
  7. # 2. Broadcasts back through /live, where...
  8. # 3. HLS and DASH fragments are served, with caching disabled.
  9. # 4. All other requests are forwarded to Miracle.
  10. # This config should be used with Docker, in order to replace the environment
  11. # variables for MIRACLE_PORT, RTMP_PORT, et al.
  12. # It also assumes that HLS fragments can be kept in /mnt/hls/, and DASH in /mnt/dash/.
  13. # TODO: Certain settings could certainly be optimized for speed. I'm not an nginx master,
  14. # so I'm not sure where to start, especially given a setup like this.
  15. events {}
  16. # RTMP config.
  17. rtmp {
  18. server {
  19. # Port for the RTMP stream.
  20. listen 1935;
  21. chunk_size 4096;
  22. # This accepts the external connections, and redirects them to `live`
  23. # if a valid stream key is provided.
  24. application miracle {
  25. # Allow streaming to this endpoint, and disable recording.
  26. live on;
  27. record off;
  28. # Callback for when a stream begins.
  29. # On 2xx: Allows streaming.
  30. # On 3xx: Redirects? Not sure what that would be, honestly.
  31. # On 4xx: Denies streaming.
  32. on_publish "http://miracle-backend:4000/api/hook/on_publish?name=$uri";
  33. # Callback for when a stream stops.
  34. on_publish_done http://miracle-backend:4000/api/hook/on_publish_done;
  35. # Deny listening to this endpoint for non-localhost.
  36. allow play 127.0.0.1;
  37. deny play all;
  38. exec_push /usr/local/bin/ffmpeg -i rtmp://localhost:1935/$app/$name -async 1 -vsync -1
  39. -c:v libx264 -c:a aac -b:v 256k -b:a 64k -vf "scale=480:trunc(ow/a/2)*2" -tune zerolatency -preset superfast -crf 23 -f flv rtmp://localhost:1935/live/$name_low
  40. -c:v libx264 -c:a aac -b:v 768k -b:a 128k -vf "scale=720:trunc(ow/a/2)*2" -tune zerolatency -preset superfast -crf 23 -f flv rtmp://localhost:1935/live/$name_mid
  41. -c:v libx264 -c:a aac -b:v 1024k -b:a 128k -vf "scale=960:trunc(ow/a/2)*2" -tune zerolatency -preset superfast -crf 23 -f flv rtmp://localhost:1935/live/$name_high
  42. -c:v libx264 -c:a aac -b:v 1920k -b:a 128k -vf "scale=1280:trunc(ow/a/2)*2" -tune zerolatency -preset superfast -crf 23 -f flv rtmp://localhost:1935/live/$name_hd720
  43. -c copy -f flv rtmp://localhost:1935/live/$name_src;
  44. }
  45. # Application for receiving.
  46. application live {
  47. live on; # Allow streaming from localhost.
  48. deny play all; # Deny receiving as RTMP.
  49. # Only allow publishing from localhost - `miracle` handles publishing here.
  50. allow publish 127.0.0.1;
  51. deny publish all;
  52. # HLS config.
  53. hls on; # Enable HLS.
  54. hls_fragment 3;
  55. hls_playlist_length 10;
  56. hls_path /mnt/hls/;
  57. hls_variant _src BANDWIDTH=4096000; # Source bitrate, source resolution
  58. hls_variant _hd720 BANDWIDTH=2048000; # High bitrate, HD 720p resolution
  59. hls_variant _high BANDWIDTH=1152000; # High bitrate, higher-than-SD resolution
  60. hls_variant _mid BANDWIDTH=448000; # Medium bitrate, SD resolution
  61. hls_variant _low BANDWIDTH=288000; # Low bitrate, sub-SD resolution
  62. # DASH config.
  63. dash on;
  64. dash_path /mnt/dash/;
  65. dash_fragment 3;
  66. dash_playlist_length 10;
  67. }
  68. }
  69. }
  70. # HTTP config; also serves Miracle itself.
  71. http {
  72. # Stops nginx from spamming the console with constant requests.
  73. access_log off;
  74. # Honestly, not sure what these do.
  75. # ??? https://nginx.org/en/docs/http/ngx_http_core_module.html#sendfile
  76. sendfile off;
  77. # Try to send all headers in one packet.
  78. # ... this is disabled by the sendfile off; above, though, isn't it?
  79. # Keeping it here since it's in rtmp-hls-server, why not.
  80. tcp_nopush on;
  81. # Disable fs cache for files over 512 in size. Probably a speed thing?
  82. directio 512;
  83. server {
  84. # Port for the HTTP nginx server.
  85. listen 1337;
  86. # RTMP stats.
  87. # Probably not needed in production; TODO: any way to dynamically set this up?
  88. # We also need to serve the stylesheet. Not sure where that's kept.
  89. # location /stat {
  90. # rtmp_stat all;
  91. # }
  92. # HLS fragments.
  93. location /hls {
  94. types {
  95. application/vnd.apple.mpegurl m3u8;
  96. video/mp2t ts;
  97. }
  98. root /mnt;
  99. # Don't cache.
  100. add_header Cache-Control no-cache;
  101. # CORS.
  102. add_header 'Access-Control-Allow-Origin' '*' always;
  103. add_header 'Access-Control-Expose-Headers' 'Content-Length';
  104. # Allow CORS preflight requests.
  105. if ($request_method = 'OPTIONS') {
  106. add_header 'Access-Control-Allow-Origin' '*';
  107. add_header 'Access-Control-Max-Age' 1728000;
  108. add_header 'Content-Type' 'text/plain charset=UTF-8';
  109. add_header 'Content-Length' 0;
  110. return 204;
  111. }
  112. }
  113. # DASH fragments; largely similar to HLS config.
  114. # TODO: refactor so these cache bits can be more DRY?
  115. location /dash {
  116. types {
  117. application/dash+xml mpd;
  118. video/mp4 mp4;
  119. }
  120. root /mnt;
  121. }
  122. # Proxy all /api requests to Miracle backend.
  123. location /api/ {
  124. proxy_pass http://miracle-backend:4000;
  125. #proxy_http_version 1.1;
  126. #proxy_set_header Upgrade $http_upgrade;
  127. #proxy_set_header Connection 'upgrade';
  128. #proxy_set_header Host $host;
  129. #proxy_cache_bypass $http_upgrade;
  130. # CORS.
  131. add_header 'Access-Control-Allow-Origin' '*' always;
  132. add_header 'Access-Control-Expose-Headers' 'Content-Length';
  133. # Allow CORS preflight requests.
  134. if ($request_method = 'OPTIONS') {
  135. add_header 'Access-Control-Allow-Origin' '*';
  136. add_header 'Access-Control-Max-Age' 1728000;
  137. add_header 'Content-Type' 'text/plain charset=UTF-8';
  138. add_header 'Content-Length' 0;
  139. return 204;
  140. }
  141. }
  142. # Finally, proxy requests to Miracle frontend.
  143. location / {
  144. proxy_pass http://miracle-frontend:3000;
  145. proxy_http_version 1.1;
  146. proxy_set_header Upgrade $http_upgrade;
  147. proxy_set_header Connection 'upgrade';
  148. proxy_set_header Host $host;
  149. proxy_cache_bypass $http_upgrade;
  150. # CORS.
  151. add_header 'Access-Control-Allow-Origin' '*' always;
  152. add_header 'Access-Control-Expose-Headers' 'Content-Length';
  153. # Allow CORS preflight requests.
  154. if ($request_method = 'OPTIONS') {
  155. add_header 'Access-Control-Allow-Origin' '*';
  156. add_header 'Access-Control-Max-Age' 1728000;
  157. add_header 'Content-Type' 'text/plain charset=UTF-8';
  158. add_header 'Content-Length' 0;
  159. return 204;
  160. }
  161. }
  162. }
  163. }