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.

record-screen.rb 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #!/usr/bin/ruby
  2. ################################################################################
  3. require('optparse')
  4. require('ostruct')
  5. ################################################################################
  6. class Driver
  7. ##############################################################################
  8. OPTIONS = {
  9. :verbose => true,
  10. :file => Time.now.strftime("%Y-%m-%d-%H:%M:%S.m4v"),
  11. :screen => 2,
  12. :x_display => "0.0",
  13. :fps => '25',
  14. :video_bitrate => '256k',
  15. :audio => true,
  16. :audio_hw => 'hw:0,0',
  17. :audio_bitrate => '64k',
  18. }
  19. ##############################################################################
  20. DEFAULTS = {
  21. # My desktop.
  22. 'hawkins' => {
  23. :audio_hw => 'hw:2,0',
  24. :screen => 3,
  25. },
  26. # My laptop.
  27. 'seward' => {
  28. :audio_hw => 'hw:0,0',
  29. :screen => 2,
  30. },
  31. }
  32. ##############################################################################
  33. attr_reader(:options)
  34. ##############################################################################
  35. def initialize
  36. @options = OpenStruct.new(OPTIONS)
  37. @hostname = `hostname`.chomp
  38. if DEFAULTS.has_key?(@hostname)
  39. DEFAULTS[@hostname].each {|k, v| options.send("#{k}=", v)}
  40. end
  41. OptionParser.new do |op|
  42. op.on('--screen=N', 'Record screen number N') {|n| options.screen = n.to_i}
  43. op.on('--[no-]audio', 'Enable/disable mic') {|a| options.audio = a}
  44. op.on('--audio-hw=DEVICE', 'Set audio device') {|h| options.audio_hw = h}
  45. end.parse(ARGV)
  46. end
  47. ################################################################################
  48. def run
  49. offset = screen_x_offset(options.screen)
  50. verbose("screen x offset: #{offset}")
  51. (width, height) = screen_size(options.screen).split('x')
  52. verbose("screen size: #{width}x#{height}")
  53. cmd = [
  54. 'avconv',
  55. '-f', 'x11grab',
  56. '-r', options.fps,
  57. '-s', "#{width}x#{height}",
  58. '-i', ":#{options.x_display}+#{offset},0",
  59. ]
  60. if options.audio
  61. cmd.concat(%W(-f alsa -i #{options.audio_hw} -ac 1 -strict experimental))
  62. end
  63. cmd << File.expand_path(options.file)
  64. verbose("command: #{cmd.join(' ')}")
  65. system(*cmd) || raise("command filed")
  66. end
  67. ##############################################################################
  68. private
  69. ##############################################################################
  70. def screen_x_offset (screen_num)
  71. offset = 0
  72. (screen_num - 1).times do |n|
  73. (x, y) = screen_size(n + 1).split('x')
  74. offset += x.to_i
  75. end
  76. offset
  77. end
  78. ##############################################################################
  79. def screen_size (screen_num)
  80. if screen_num > screen_sizes.size
  81. raise("not enough screens, there are: #{screen_sizes.size}")
  82. end
  83. screen_sizes[screen_num - 1]
  84. end
  85. ##############################################################################
  86. def screen_sizes
  87. @screen_sizes ||= `xrandr|grep '[0-9]\\*'|awk '{print $1}'`.split
  88. end
  89. ##############################################################################
  90. def verbose (msg)
  91. $stderr.puts(msg) if options.verbose
  92. end
  93. end
  94. ################################################################################
  95. begin
  96. Driver.new.run
  97. rescue RuntimeError => e
  98. $stderr.puts(File.basename($0) + ": ERROR: #{e}")
  99. exit(1)
  100. end