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

129 строки
3.3KB

  1. #!/usr/bin/env ruby
  2. require 'fileutils'
  3. # Preset:
  4. # ultrafast
  5. # superfast
  6. # veryfast
  7. # faster
  8. # fast
  9. # medium – default preset
  10. # slow
  11. # slower
  12. # veryslow
  13. # Tune:
  14. # film – use for high quality movie content; lowers deblocking
  15. # animation – good for cartoons; uses higher deblocking and more reference frames
  16. # grain – preserves the grain structure in old, grainy film material
  17. # stillimage – good for slideshow-like content
  18. # fastdecode – allows faster decoding by disabling certain filters
  19. # zerolatency – good for fast encoding and low-latency streaming
  20. # psnr – ignore this as it is only used for codec development
  21. # ssim – ignore this as it is only used for codec development
  22. # -profile:v baseline -level 3.0
  23. # -c:a aac -ar 48000
  24. FPS = 30
  25. COMMON = {
  26. audio: %w[
  27. -c:a aac
  28. -ar 48000
  29. ],
  30. # -vaapi_device /dev/dri/renderD128 -vf format=nv12,hwupload
  31. # -c:v h264_vaapi
  32. # -init_hw_device qsv=hw -filter_hw_device hw
  33. # -vf hwupload=extra_hw_frames=64,format=qsv -c:v h264_qsv
  34. video: %W[
  35. -c:v libx264 -preset ultrafast -crf 23
  36. -sc_threshold 0 -r #{FPS} -g #{FPS*2} -keyint_min #{FPS}
  37. -movflags faststart
  38. ],
  39. hls: %w[
  40. -profile:v high -level 4.2 -pix_fmt yuv420p
  41. -hls_time 5 -hls_list_size 10
  42. -hls_flags delete_segments
  43. -use_localtime 1
  44. ],
  45. '360p' => %w[
  46. -vf scale=-2:360 -b:v 800k
  47. -b:a 96k
  48. ],
  49. '480p' => %w[
  50. -vf scale=-2:480 -b:v 1400k
  51. -b:a 128k
  52. ],
  53. '720p' => %w[
  54. -vf scale=-2:720 -b:v 2800k
  55. -b:a 128k
  56. ],
  57. '1080p' => %w[
  58. -vf scale=-2:1080 -b:v 5000k
  59. -b:a 192k
  60. ]
  61. }
  62. HLS = {
  63. audio: COMMON[:hls] + COMMON[:audio],
  64. video: COMMON[:hls] + COMMON[:audio] + COMMON[:video]
  65. }
  66. OUTPUT = {
  67. 'audio' => HLS[:audio] + %w[-b:a 192k -vn],
  68. '360p' => HLS[:video] + COMMON['360p'],
  69. '480p' => HLS[:video] + COMMON['480p'],
  70. '720p' => HLS[:video] + COMMON['720p'],
  71. '1080p' => HLS[:video] + COMMON['1080p'],
  72. }.map do |k, v|
  73. v += [
  74. '-hls_base_url', "#{k}/",
  75. '-hls_segment_filename', "stream/#{k}/%s.ts",
  76. "stream/#{k}.m3u8"
  77. ]
  78. [k, v]
  79. end.to_h
  80. # OUTPUT = OUTPUT.slice '1080p', '720p'
  81. OUTPUT.keys.each do |type|
  82. output = File.join 'stream', type
  83. FileUtils.mkdir_p output unless Dir.exist? output
  84. ts = File.join output, '*.ts'
  85. ts = Dir[ts]
  86. ts.each { |f| File.unlink f }
  87. end
  88. timestamp = Time.now().strftime "%Y-%m-%dT%H:%M:%S"
  89. OUTPUT['video'] = COMMON[:audio] + COMMON[:video] + COMMON['1080p'] + [ File.join('video', "#{timestamp}.ts") ]
  90. FileUtils.mkdir_p 'video' unless Dir.exist? 'video'
  91. OUTPUT['twitch'] = COMMON[:audio] + COMMON[:video] + COMMON['1080p'] + %w[-maxrate 5M -bufsize 10M -pix_fmt yuv420p -f flv] \
  92. + [ "rtmp://live-cdg.twitch.tv/app/#{ENV.fetch('TWITCH_KEY')}#{ENV['TWITCH_TEST'] ? '?bandwidthtest=true' : ''}" ]
  93. # INPUT = [ '-re', '-r', '25', '-threads', '0', '-i', ARGV.first ]
  94. # INPUT=( -i udp://@localhost:9999 )
  95. # INPUT = %w[-f libndi_newtek -i ENDOR\ (OBS)]
  96. INPUT = %w[-threads 0 -f libndi_newtek -i LANDSCAPE\ (OBS)]
  97. # INPUT = %w[-i udp://224.0.0.1:9999]
  98. # FFMPEG = 'ffmpeg'
  99. # FFMPEG = './ffmpeg.sh'
  100. FFMPEG = './ffmpeg/ffmpeg'
  101. args = ARGV.first
  102. args = %w[video twitch] if args == 'live'
  103. # args = %w[video] if args == 'live'
  104. args = OUTPUT.keys - %w[video twitch] unless args
  105. p args
  106. # output = OUTPUT.keys - %w[video] if output.empty?
  107. output = OUTPUT.values_at(*args).flatten
  108. cmd = [ FFMPEG, '-y' ] + INPUT + output
  109. puts cmd.join ' '
  110. exec *cmd