我在iOS开发方面不是很有经验,并且在AVFoundation方面做得很少。
我需要捕捉屏幕内容(即使按下主页按钮),并且必须通过quickblox将其发送给对手。
要捕获屏幕内容,我使用ReplayKit Framework(代码如下)
func startCapture(_ r:RPScreenRecorder){
r.startCapture(handler: {
(sampleBuffer, RPsampleBuffer, error) in
self.pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
})
}
我声明了一个CVPixelBuffer类型的可变像素缓冲区
然后我从下面给出了Image from Pixel Buffer代码
func screenShotFromPixelBuffer() -> UIImage? {
if let buffer = pixelBuffer {
let image = CIImage.init(cvPixelBuffer: buffer)
return UIImage.init(ciImage: image)
}
return nil
}
然后我通过以下代码发送给对手
@objc func sendPixelBuffer(_ sender: CADisplayLink?) {
videoQueue.async(execute: {
autoreleasepool {
let image = self.screenShotFromPixelBuffer()
print("Called")
let renderWidth = Int(image?.size.width ?? 0)
let renderHeight = Int(image?.size.height ?? 0)
var buffer: CVPixelBuffer? = nil
var pixelFormatType: OSType
var pixelBufferAttributes: CFDictionary? = nil
if kQBRTCUseBiPlanarFormatTypeForShare {
pixelFormatType = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
pixelBufferAttributes = ([kCVPixelBufferIOSurfacePropertiesKey as String: [:]] as? CFDictionary?)!
} else {
pixelFormatType = kCVPixelFormatType_32ARGB
pixelBufferAttributes = ([kCVPixelBufferCGImageCompatibilityKey as String: false, kCVPixelBufferCGBitmapContextCompatibilityKey as String: false] as? CFDictionary?)!
}
let status: CVReturn = CVPixelBufferCreate(kCFAllocatorDefault, renderWidth, renderHeight, pixelFormatType, pixelBufferAttributes, &buffer)
if status == kCVReturnSuccess && buffer != nil {
CVPixelBufferLockBaseAddress(buffer!, CVPixelBufferLockFlags(rawValue: 0))
if kQBRTCUseBiPlanarFormatTypeForShare {
var rImage: CIImage? = nil
if let anImage = image {
rImage = CIImage(image: anImage)
}
if let anImage = rImage, let aBuffer = buffer {
self.qb_sharedGPUContext()?.render(anImage, to: aBuffer)
}
} else {
let pxdata = CVPixelBufferGetBaseAddress(buffer!)
let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
// let bitmapInfo: UInt32 = [.byteOrder32Little, .premultipliedFirst]
let bitMap = CGBitmapInfo.byteOrder32Little
let context = CGContext(data: pxdata, width: renderWidth, height: renderHeight, bitsPerComponent: 8, bytesPerRow: renderWidth * 4, space: rgbColorSpace, bitmapInfo: bitMap.rawValue)
// context.draw(in: image?.cgImage, image: CGRect(x: 0, y: 0, width: CGFloat(renderWidth), height: CGFloat(renderHeight)))
// context?.draw(image: image!, in: CGRect(x: 0, y: 0, width: CGFloat(renderWidth), height: CGFloat(renderHeight)))
context?.draw(image!.cgImage!, in: CGRect(x: 0, y: 0, width: CGFloat(renderWidth), height: CGFloat(renderHeight)))
// CGContextRelease(context)
}
CVPixelBufferUnlockBaseAddress(buffer!, CVPixelBufferLockFlags.init(rawValue: CVOptionFlags.init(0.0)))
let videoFrame = QBRTCVideoFrame(pixelBuffer: buffer, videoRotation: ._0)
super.send(videoFrame)
}
// CVPixelBufferRelease(buffer)
}
})
}
绿色照片正在进入对手设备。