[英]Trouble with screen recording in iOS
I've got some trouble with screen recording using ReplayKit
我在使用
ReplayKit
进行屏幕录制时遇到了一些问题
So, the strangeness begins in the startCapture
's handler
closure所以,奇怪开始于
startCapture
的handler
闭包
Every time it starts to capture and sampleType
is .video
, the self.videoWriter?.startSession
is called, and instantaneously videoWriter.status
becomes failure
(3)每次开始捕获且
sampleType
为.video
时,都会调用self.videoWriter?.startSession
,并且瞬间videoWriter.status
变为failure
(3)
This behaviour is not throwing any exceptions until I finish recording:在我完成录制之前,此行为不会引发任何异常:
Optional("Cannot Encode")
可选(“无法编码”)
Optional("Optional(Error Domain=AVFoundationErrorDomain Code=-11834 "Cannot Encode" UserInfo={AVErrorMediaSubTypeKey=(\n 778924083\n), NSLocalizedFailureReason=The encoder required for this media cannot be found., AVErrorMediaTypeKey=soun, NSLocalizedDescription=Cannot Encode })") Optional("<AVAssetWriter: 0x283ef0920, outputURL = file:///var/mobile/Containers/Data/Application/A85826BA-DCBE-428B-AB9E-84D77F234FF6/Documents/Replays/capture92949FA1-F65D-48A0-8140-207BC892C204.mp4, outputFileType = public.mpeg-4>")
Optional("Optional(Error Domain=AVFoundationErrorDomain Code=-11834 "Cannot Encode" UserInfo={AVErrorMediaSubTypeKey=(\n 778924083\n), NSLocalizedFailureReason=找不到此媒体所需的编码器。, AVErrorMediaTypeKey=soun, NSLocalizedDescription=Cannot编码})") 可选("<AVAssetWriter: 0x283ef0920, outputURL = file:///var/mobile/Containers/Data/Application/A85826BA-DCBE-428B-AB9E-84D77F234FF6/Documents/Replays/capture92949FA1-F65D-48A0- 8140-207BC892C204.mp4,输出文件类型 = public.mpeg-4>")
Error Domain=PHPhotosErrorDomain Code=3302 "(null)"
错误域=PHPhotosErrorDomain 代码=3302“(空)”
Here is my code:这是我的代码:
let settings = [
AVFormatIDKey: Int(AudioFormat.kAudioFormatMPEGLayer3.rawValue),
AVNumberOfChannelsKey: 2,
AVSampleRateKey: 44100,
AVEncoderBitRateKey: 128000
]
let audioInput = AVAssetWriterInput(
mediaType: .audio,
outputSettings: settings
)
audioInput.expectsMediaDataInRealTime = true
videoWriter.add(audioInput)
self.videoWriterInput = audioInput
self.videoWriter = videoWriter
let videoSettings: [String: Any] = [
AVVideoCodecKey: AVVideoCodecType.h264,
AVVideoWidthKey: passingSize.width,
AVVideoHeightKey: passingSize.height
]
self.videoWriterInput = AVAssetWriterInput(
mediaType: AVMediaType.video,
outputSettings: videoSettings
)
self.appAudioWriterInput = AVAssetWriterInput(
mediaType: .audio,
outputSettings: settings
)
self.videoWriter.add(appAudioWriterInput!)
self.recorder.startCapture(
handler: { (sampleBuffer, sampleType, passedError) in
switch sampleType {
case .video:
self.handleSampleBuffer(sampleBuffer: sampleBuffer)
case .audioApp:
self.add(sample: sampleBuffer, to: appAudioWriterInput)
default:
break
}
},
completionHandler: { error in
if let error = error {
print(">>> Error!")
errorHandler(error: error)
}
}
)
private func handleSampleBuffer(sampleBuffer: CMSampleBuffer) {
if videoWriter?.status == AVAssetWriter.Status.unknown {
serialQueue.async {
if !self.isRecording {
self.videoWriter?.startWriting()
self.videoWriter?.startSession(
atSourceTime: .zero
)
self.isRecording = true
}
}
} else if videoWriter?.status == AVAssetWriter.Status.writing &&
videoWriterInput?.isReadyForMoreMediaData == true {
serialQueue.async {
self.videoWriterInput?.append(sampleBuffer)
}
}
}
I'm not familiar with iOS development and I think that I'm missing something obvious.我不熟悉 iOS 开发,我认为我遗漏了一些明显的东西。
Things I've tried:我尝试过的事情:
PHPhotoLibrary.authorizationStatus()
and AVCaptureDevice.authorizationStatus
before recordingPHPhotoLibrary.authorizationStatus()
和AVCaptureDevice.authorizationStatus
Here is my modifications to Info.plist
这是我对
Info.plist
的修改
<key>NSPhotoLibraryAddUsageDescription</key>
<string>The app requires access to Photos to save media to it.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>The app requires access to Photos to interact with it.</string>
<key>PHPhotoLibraryPreventAutomaticLimitedAccessAlert</key>
<true/>
The solution was pretty simple: I just passed wrong variable to self.videoWriterInput
解决方案非常简单:我只是将错误的变量传递给
self.videoWriterInput
Proper initialization should be something like this:正确的初始化应该是这样的:
let screenSize: CGRect = UIScreen.main.bounds
let videoSettings: [String: Any] = [
AVVideoCodecKey: AVVideoCodecType.h264,
AVVideoWidthKey: screenSize.width,
AVVideoHeightKey: screenSize.height,
]
let newVideoWriterInput = AVAssetWriterInput(
mediaType: AVMediaType.video,
outputSettings: videoSettings
)
newVideoWriterInput.expectsMediaDataInRealTime = true
self.videoWriter?.add(newVideoWriterInput)
self.videoWriterInput = newVideoWriterInput // THE ERROR WAS HERE
let settings: [String : Any] = [
AVNumberOfChannelsKey : 2,
AVFormatIDKey : kAudioFormatMPEG4AAC,
AVSampleRateKey: 44100,
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
]
let audioInput = AVAssetWriterInput(
mediaType: .audio,
outputSettings: settings
)
audioInput.expectsMediaDataInRealTime = true
self.videoWriter?.add(audioInput)
self.appAudioWriterInput = audioInput
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.