I would like to stream video footage of running Selenium scripts/bots. I'm using capybara with selenium-webdriver and I know I can use headless to capture video.
What I don't know how to do is stream the video such that I can access it at some URL and not consume disk space. Has anyone done this?
Here's a test script I use to generate video files:
require 'capybara/dsl'
require 'selenium-webdriver'
require 'headless'
Capybara.configure do |c|
c.javascript_driver = :selenium
c.default_driver = :selenium
end
Capybara.register_driver :selenium do |app|
profile = Selenium::WebDriver::Chrome::Profile.new
profile['general.useragent.override'] = Bot::USER_AGENT
Capybara::Selenium::Driver.new(app, {
browser: :chrome,
profile: profile,
args: ['--window-size=1024,768']
})
end
class Bot
include Capybara::DSL
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36'
def run
headless = Headless.new
headless.start
headless.video.start_capture
loop do
visit('http://google.com')
sleep 1
visit('http://youtube.com')
sleep 1
headless.video.stop_and_save("video-#{Time.now.to_i}.mov")
end
end
end
bot = Bot.new
bot.run
I got it working. Here's the updated Ruby script:
require 'capybara/dsl'
require 'selenium-webdriver'
require 'headless'
Capybara.configure do |c|
c.javascript_driver = :selenium
c.default_driver = :selenium
end
Capybara.register_driver :selenium do |app|
profile = Selenium::WebDriver::Chrome::Profile.new
profile['general.useragent.override'] = Bot::USER_AGENT
Capybara::Selenium::Driver.new(app, {
browser: :chrome,
profile: profile,
args: ["--window-size=1024,768"]
})
end
class Bot
include Capybara::DSL
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36'
FILE_PATH = File.join(__dir__, 'segment%05d.ts')
def run
headless = Headless.new(video: {
codec: 'libx264',
frame_rate: 25,
tmp_file_path: FILE_PATH,
extra: [
'-pix_fmt yuv420p',
'-profile:v baseline',
'-b:v 1500k',
'-x264opts keyint=25',
'-s 640x360',
'-map 0',
'-flags',
'-global_header',
'-f segment',
'-segment_list index_1500.m3u8',
'-segment_time 1',
'-segment_format mpeg_ts',
'-segment_list_type m3u8',
'-segment_list_flags +live',
'-segment_list_size 2',
],
})
headless.start
headless.video.start_capture
loop do
print 'loading google... '
visit('http://google.com')
puts 'done'
print 'loading youtube... '
visit('http://youtube.com')
puts 'done'
end
end
end
bot = Bot.new
bot.run
Internally, headless
will build this command:
/usr/bin/avconv -y -r 25 -s 1280x1024 -f x11grab -i :99 -g 600 -vcodec libx264 -pix_fmt yuv420p -profile:v baseline -b:v 1500k -x264opts keyint=25 -s 640x360
-map 0 -flags -global_header -f segment -segment_list index_1500.m3u8 -segment_time 1 -segment_format mpeg_ts -segment_list_type m3u8 -segment_list_flags +li
ve -segment_list_size 2 /home/mhluska/record-test/segment%05d.ts
I'm not well versed in ffmpeg
so I can't explain what half of these parameters do. The end result is it will produce segment*.ts
files and index_1500.m3u8
which seems to be a manifest.
We can play it in the browser now. Create index.html
:
<!doctype html>
<html>
<head>
<title>Video stream test</title>
</head>
<body>
<video src="index_1500.m3u8" autoplay controls type="application/x-mpegURL"></video>
</body>
</html>
And serve it temporarily with sudo python -m SimpleHTTPServer 80
.
Notes/caveats:
video
tag seems to only play on Safari and not Chromeffmpeg
parameters