HLS streaming from OBS with NDI plugin
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

il y a 2 ans
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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