HLS streaming from OBS with NDI plugin
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.

129 lines
3.3 KiB

преди 3 години
#!/usr/bin/env ruby
require 'fileutils'
# Preset:
# ultrafast
# superfast
# veryfast
# faster
# fast
# medium – default preset
# slow
# slower
# veryslow
# Tune:
# film – use for high quality movie content; lowers deblocking
# animation – good for cartoons; uses higher deblocking and more reference frames
# grain – preserves the grain structure in old, grainy film material
# stillimage – good for slideshow-like content
# fastdecode – allows faster decoding by disabling certain filters
# zerolatency – good for fast encoding and low-latency streaming
# psnr – ignore this as it is only used for codec development
# ssim – ignore this as it is only used for codec development
# -profile:v baseline -level 3.0
# -c:a aac -ar 48000
FPS = 30
COMMON = {
audio: %w[
-c:a aac
-ar 48000
],
# -vaapi_device /dev/dri/renderD128 -vf format=nv12,hwupload
# -c:v h264_vaapi
# -init_hw_device qsv=hw -filter_hw_device hw
# -vf hwupload=extra_hw_frames=64,format=qsv -c:v h264_qsv
video: %W[
-c:v libx264 -preset ultrafast -crf 23
-sc_threshold 0 -r #{FPS} -g #{FPS*2} -keyint_min #{FPS}
-movflags faststart
],
hls: %w[
-profile:v high -level 4.2 -pix_fmt yuv420p
-hls_time 5 -hls_list_size 10
-hls_flags delete_segments
-use_localtime 1
],
'360p' => %w[
-vf scale=-2:360 -b:v 800k
-b:a 96k
],
'480p' => %w[
-vf scale=-2:480 -b:v 1400k
-b:a 128k
],
'720p' => %w[
-vf scale=-2:720 -b:v 2800k
-b:a 128k
],
'1080p' => %w[
-vf scale=-2:1080 -b:v 5000k
-b:a 192k
]
}
HLS = {
audio: COMMON[:hls] + COMMON[:audio],
video: COMMON[:hls] + COMMON[:audio] + COMMON[:video]
}
OUTPUT = {
'audio' => HLS[:audio] + %w[-b:a 192k -vn],
'360p' => HLS[:video] + COMMON['360p'],
'480p' => HLS[:video] + COMMON['480p'],
'720p' => HLS[:video] + COMMON['720p'],
'1080p' => HLS[:video] + COMMON['1080p'],
}.map do |k, v|
v += [
'-hls_base_url', "#{k}/",
'-hls_segment_filename', "stream/#{k}/%s.ts",
"stream/#{k}.m3u8"
]
[k, v]
end.to_h
# OUTPUT = OUTPUT.slice '1080p', '720p'
OUTPUT.keys.each do |type|
output = File.join 'stream', type
FileUtils.mkdir_p output unless Dir.exist? output
ts = File.join output, '*.ts'
ts = Dir[ts]
ts.each { |f| File.unlink f }
end
timestamp = Time.now().strftime "%Y-%m-%dT%H:%M:%S"
OUTPUT['video'] = COMMON[:audio] + COMMON[:video] + COMMON['1080p'] + [ File.join('video', "#{timestamp}.ts") ]
FileUtils.mkdir_p 'video' unless Dir.exist? 'video'
OUTPUT['twitch'] = COMMON[:audio] + COMMON[:video] + COMMON['1080p'] + %w[-maxrate 5M -bufsize 10M -pix_fmt yuv420p -f flv] \
+ [ "rtmp://live-cdg.twitch.tv/app/#{ENV.fetch('TWITCH_KEY')}#{ENV['TWITCH_TEST'] ? '?bandwidthtest=true' : ''}" ]
# INPUT = [ '-re', '-r', '25', '-threads', '0', '-i', ARGV.first ]
# INPUT=( -i udp://@localhost:9999 )
# INPUT = %w[-f libndi_newtek -i ENDOR\ (OBS)]
INPUT = %w[-threads 0 -f libndi_newtek -i LANDSCAPE\ (OBS)]
# INPUT = %w[-i udp://224.0.0.1:9999]
# FFMPEG = 'ffmpeg'
# FFMPEG = './ffmpeg.sh'
FFMPEG = './ffmpeg/ffmpeg'
args = ARGV.first
args = %w[video twitch] if args == 'live'
# args = %w[video] if args == 'live'
args = OUTPUT.keys - %w[video twitch] unless args
p args
# output = OUTPUT.keys - %w[video] if output.empty?
output = OUTPUT.values_at(*args).flatten
cmd = [ FFMPEG, '-y' ] + INPUT + output
puts cmd.join ' '
exec *cmd