|
- #!/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
|