首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何以编程方式记录IOS屏幕

如何以编程方式记录IOS屏幕
EN

Stack Overflow用户
提问于 2016-07-12 07:46:16
回答 4查看 26.1K关注 0票数 16

有没有任何方法以编程方式记录IOS屏幕。意味着无论你做什么活动,如点击按钮,滚动表视图。

即使一段视频正在播放,它也会和其他活动一起再次被捕获吗?

试过这些

  1. https://www.raywenderlich.com/30200/avfoundation-tutorial-adding-overlays-and-animations-to-videos
  2. https://github.com/alskipp/ASScreenRecorder

但是有了这些图书馆就不能提供高质量的视频。我需要高质量的视频。

问题是,当我捕捉屏幕时,在后台播放的视频并不能显示流畅的视频。它显示像一帧视频,然后在3-4秒后,第二帧,等等。视频的质量也不是很好,它模糊了。

EN

回答 4

Stack Overflow用户

发布于 2017-03-10 19:24:52

从iOS 9开始,ReplayKit看起来可以大大简化这一点。

https://developer.apple.com/reference/replaykit

https://code.tutsplus.com/tutorials/ios-9-an-introduction-to-replaykit--cms-25458

Update:既然iOS 11有内置的屏幕记录器,这可能就不那么重要了,但是下面的Swift 3代码对我有用:

代码语言:javascript
运行
复制
import ReplayKit

@IBAction func toggleRecording(_ sender: UIBarButtonItem) {
    let r = RPScreenRecorder.shared()

    guard r.isAvailable else {
        print("ReplayKit unavailable")
        return
    }
    
    if r.isRecording {
        self.stopRecording(sender, r)
        
    }
    else {
        self.startRecording(sender, r)
    }
}

func startRecording(_ sender: UIBarButtonItem, _ r: RPScreenRecorder) {
    
    r.startRecording(handler: { (error: Error?) -> Void in
        if error == nil { // Recording has started
            sender.title = "Stop"
        } else {
            // Handle error
            print(error?.localizedDescription ?? "Unknown error")
        }
    })
}

func stopRecording(_ sender: UIBarButtonItem, _ r: RPScreenRecorder) {
    r.stopRecording( handler: { previewViewController, error in

        sender.title = "Record"
        
        if let pvc = previewViewController {

            if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad {
                pvc.modalPresentationStyle = UIModalPresentationStyle.popover
                pvc.popoverPresentationController?.sourceRect = CGRect.zero
                pvc.popoverPresentationController?.sourceView = self.view
            }

            pvc.previewControllerDelegate = self
            self.present(pvc, animated: true, completion: nil)
        }
        else if let error = error {
            print(error.localizedDescription)
        }
        
    })
}

// MARK: RPPreviewViewControllerDelegate
func previewControllerDidFinish(_ previewController: RPPreviewViewController) {
    previewController.dismiss(animated: true, completion: nil)
}
票数 5
EN

Stack Overflow用户

发布于 2017-05-21 20:05:36

ReplayKit是可用的,尽管您不允许访问结果视频,但我到目前为止发现的唯一方法是制作许多屏幕截图(将它们存储在图像数组中),然后将这些图像转换为视频,尽管从性能的角度来看并不是很有效,但是如果您不需要30/60 fps屏幕记录,并且可能可以使用w/ 6-20 pfs,则可能会有效。这是完整的例子

票数 3
EN

Stack Overflow用户

发布于 2016-07-12 07:57:44

查看ScreenCaptureView,这有内置的视频记录支持(参见链接)。

这样做是将UIView的内容保存到UIImage中。作者建议你可以通过AVCaptureSession来保存正在使用的应用程序的视频。

我相信它还没有经过OpenGL子视图的测试,但假设它工作正常,您可能可以稍微修改它以包括音频,然后就可以设置它了。

AVCaptureSession样品

AVCaptureSession参考

代码语言:javascript
运行
复制
import UIKit
import AVFoundation
class ViewController: UIViewController {
    let captureSession = AVCaptureSession()
    let stillImageOutput = AVCaptureStillImageOutput()
    var error: NSError?
    override func viewDidLoad() {
        super.viewDidLoad()
        let devices = AVCaptureDevice.devices().filter{ $0.hasMediaType(AVMediaTypeVideo) && $0.position == AVCaptureDevicePosition.Back }
        if let captureDevice = devices.first as? AVCaptureDevice  {

            captureSession.addInput(AVCaptureDeviceInput(device: captureDevice, error: &error))
            captureSession.sessionPreset = AVCaptureSessionPresetPhoto
            captureSession.startRunning()
            stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG]
            if captureSession.canAddOutput(stillImageOutput) {
                captureSession.addOutput(stillImageOutput)
            }
            if let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) {
                previewLayer.bounds = view.bounds
                previewLayer.position = CGPointMake(view.bounds.midX, view.bounds.midY)
                previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
                let cameraPreview = UIView(frame: CGRectMake(0.0, 0.0, view.bounds.size.width, view.bounds.size.height))
                cameraPreview.layer.addSublayer(previewLayer)
                cameraPreview.addGestureRecognizer(UITapGestureRecognizer(target: self, action:"saveToCamera:"))
                view.addSubview(cameraPreview)
            }
        }
    }
    func saveToCamera(sender: UITapGestureRecognizer) {
        if let videoConnection = stillImageOutput.connectionWithMediaType(AVMediaTypeVideo) {
            stillImageOutput.captureStillImageAsynchronouslyFromConnection(videoConnection) {
                (imageDataSampleBuffer, error) -> Void in
                let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)
                 UIImageWriteToSavedPhotosAlbum(UIImage(data: imageData), nil, nil, nil)
            }
        }
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38322853

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档