Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/ferrum/browser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Browser
body doctype content=
headers cookies network downloads
mouse keyboard
start_screencast stop_screencast
screenshot pdf mhtml viewport_size device_pixel_ratio
frames frame_by main_frame
evaluate evaluate_on evaluate_async execute evaluate_func
Expand Down
18 changes: 17 additions & 1 deletion lib/ferrum/page.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
require "ferrum/headers"
require "ferrum/cookies"
require "ferrum/dialog"
require "ferrum/screencaster"
require "ferrum/network"
require "ferrum/downloads"
require "ferrum/page/frames"
require "ferrum/page/screenshot"
require "ferrum/page/screencast"
require "ferrum/page/animation"
require "ferrum/page/tracing"
require "ferrum/page/stream"
Expand All @@ -30,6 +32,7 @@ class Page
include Screenshot
include Frames
include Stream
include Screencast

attr_accessor :referrer
attr_reader :context_id, :target_id, :event, :tracing
Expand Down Expand Up @@ -69,12 +72,16 @@ class Page
# @return [Downloads]
attr_reader :downloads

# Control Screencasting
#
# @return [nil]
attr_reader :screencaster

def initialize(client, context_id:, target_id:, proxy: nil)
@client = client
@context_id = context_id
@target_id = target_id
@options = client.options

@frames = Concurrent::Map.new
@main_frame = Frame.new(nil, self)
@event = Utils::Event.new.tap(&:set)
Expand All @@ -87,6 +94,7 @@ def initialize(client, context_id:, target_id:, proxy: nil)
@network = Network.new(self)
@tracing = Tracing.new(self)
@downloads = Downloads.new(self)
@screencaster = Screencaster.new(self)

subscribe
prepare_page
Expand Down Expand Up @@ -374,6 +382,10 @@ def on(name, &block)
request = Network::AuthRequest.new(self, params)
block.call(request, index, total)
end
when :screencastFrame
@client.on("Page.screencastFrame") do |params, index, total|
block.call(params, index, total)
end
else
client.on(name, &block)
end
Expand Down Expand Up @@ -425,6 +437,10 @@ def subscribe
dialog.accept
end
end

on(:screencastFrame) do |params, _index, _total|
@screencaster.add_frame(params)
end
end

def prepare_page
Expand Down
19 changes: 19 additions & 0 deletions lib/ferrum/page/screencast.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

require "ferrum/screencaster"

module Ferrum
class Page
module Screencast
attr_reader :screencaster

def start_screencast(...)
@screencaster.start_screencast(...)
end

def stop_screencast
@screencaster.stop_screencast
end
end
end
end
38 changes: 38 additions & 0 deletions lib/ferrum/screencaster.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true
require 'fileutils'

# Combine the resulting frames together into a video with:
# ffmpeg -y -framerate 30 -i 'frame-%d.jpeg' -c:v libx264 -r 30 -pix_fmt yuv420p try2.mp4
#
module Ferrum
class Screencaster
def initialize(page)
@page = page
@frame_number = 0
@threads = []
@save_path
end

def add_frame(params)
@page.command("Page.screencastFrameAck", sessionId: params["sessionId"])

t = Thread.new { File.binwrite("#{@save_path}/frame-#{@frame_number}.jpeg", Base64.decode64(params["data"])) }
@frame_number += 1
@threads << t
true
end


# save_path: Directory where individual frames from the screencast will be saved
def start_screencast(save_path)
@save_path = save_path
raise "Save path for screen recording does not exist" unless Dir.exist?(@save_path)
@page.command("Page.startScreencast", format: "jpeg")
end

def stop_screencast
@threads.each(&:join)
@page.command("Page.stopScreencast")
end
end
end
Loading