How to take screenshot from WKWebView with embedded video ?

I want to take a screenshot with WKWebView contains a playing video. I tried many ways, it works well in Simulator, but on device the video's content is not captured.

Simulator:

Device:


I tried the following ways:

CALayer#render

let window = UIApplication.shared.windows.first { $0.isKeyWindow }
if window == nil { return }

let layer = window!.layer
let screenRect = window!.screen.bounds
UIGraphicsBeginImageContext(screenRect.size)
let ctx:CGContext = UIGraphicsGetCurrentContext()!
layer.render(in: ctx)
self.screenShotImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

and

UIView#drawHierarchy

let window = UIApplication.shared.windows.first { $0.isKeyWindow }
if window == nil { return }

UIGraphicsBeginImageContextWithOptions(window!.frame.size, false, 0)
window!.drawHierarchy(in: window!.frame, afterScreenUpdates: true)
self.screenShotImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

and

WKWebView#takeSnapshot

let config = WKSnapshotConfiguration()
config.rect = WKWebViewHolder.webView!.frame
config.afterScreenUpdates = false
webView.takeSnapshot(with: config, completionHandler: { (image: UIImage?, error: Error?) in
     if error != nil {
       return
     }
     self.screenShotImage = image
})

What should I do? 🤔

Replies

I've seen this on macOS and it seems to be caused by some videos being rendered in hardware.

A solution is to use javascript to create a canvas, draw the currebt video frame into the canvas, then show the canvas while you take the screenshot. That seems to force the video content to really get included in the webView properly and then it shows up in the screenshot.

@ZhengHaipeng As part of your WKWebView project, by any chance have you had to deal with microphone permissions? We wrote a demo app to record audio and each time the user gets the microphone permissions prompt. Thanks in advance for any input!