fix: Fix RecordingSession nil crash by keeping it local (#938)
* fix: Fix RecordingSession nil crash by keeping it local * fix: Fix error init * Update CameraView+RecordVideo.swift
This commit is contained in:
parent
2ccce3587d
commit
971b824914
@ -64,9 +64,8 @@ extension CameraView: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAud
|
|||||||
|
|
||||||
let enableAudio = self.audio?.boolValue == true
|
let enableAudio = self.audio?.boolValue == true
|
||||||
|
|
||||||
let onFinish = { (status: AVAssetWriter.Status, error: Error?) in
|
let onFinish = { (recordingSession: RecordingSession, status: AVAssetWriter.Status, error: Error?) in
|
||||||
defer {
|
defer {
|
||||||
self.recordingSession = nil
|
|
||||||
if enableAudio {
|
if enableAudio {
|
||||||
self.audioQueue.async {
|
self.audioQueue.async {
|
||||||
self.deactivateAudioSession()
|
self.deactivateAudioSession()
|
||||||
@ -78,6 +77,7 @@ extension CameraView: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAud
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.recordingSession = nil
|
||||||
self.isRecording = false
|
self.isRecording = false
|
||||||
ReactLogger.log(level: .info, message: "RecordingSession finished with status \(status.descriptor).")
|
ReactLogger.log(level: .info, message: "RecordingSession finished with status \(status.descriptor).")
|
||||||
|
|
||||||
@ -90,8 +90,8 @@ extension CameraView: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAud
|
|||||||
} else {
|
} else {
|
||||||
if status == .completed {
|
if status == .completed {
|
||||||
callback.resolve([
|
callback.resolve([
|
||||||
"path": self.recordingSession!.url.absoluteString,
|
"path": recordingSession.url.absoluteString,
|
||||||
"duration": self.recordingSession!.duration,
|
"duration": recordingSession.duration,
|
||||||
])
|
])
|
||||||
} else {
|
} else {
|
||||||
callback.reject(error: .unknown(message: "AVAssetWriter completed with status: \(status.descriptor)"))
|
callback.reject(error: .unknown(message: "AVAssetWriter completed with status: \(status.descriptor)"))
|
||||||
@ -99,14 +99,16 @@ extension CameraView: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAud
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let recordingSession: RecordingSession
|
||||||
do {
|
do {
|
||||||
self.recordingSession = try RecordingSession(url: tempURL,
|
recordingSession = try RecordingSession(url: tempURL,
|
||||||
fileType: fileType,
|
fileType: fileType,
|
||||||
completion: onFinish)
|
completion: onFinish)
|
||||||
} catch let error as NSError {
|
} catch let error as NSError {
|
||||||
callback.reject(error: .capture(.createRecorderError(message: nil)), cause: error)
|
callback.reject(error: .capture(.createRecorderError(message: nil)), cause: error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
self.recordingSession = recordingSession
|
||||||
|
|
||||||
var videoCodec: AVVideoCodecType?
|
var videoCodec: AVVideoCodecType?
|
||||||
if let codecString = options["videoCodec"] as? String {
|
if let codecString = options["videoCodec"] as? String {
|
||||||
@ -122,8 +124,8 @@ extension CameraView: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAud
|
|||||||
|
|
||||||
// get pixel format (420f, 420v, x420)
|
// get pixel format (420f, 420v, x420)
|
||||||
let pixelFormat = CMFormatDescriptionGetMediaSubType(videoInput.device.activeFormat.formatDescription)
|
let pixelFormat = CMFormatDescriptionGetMediaSubType(videoInput.device.activeFormat.formatDescription)
|
||||||
self.recordingSession!.initializeVideoWriter(withSettings: videoSettings,
|
recordingSession.initializeVideoWriter(withSettings: videoSettings,
|
||||||
pixelFormat: pixelFormat)
|
pixelFormat: pixelFormat)
|
||||||
|
|
||||||
// Init Audio (optional, async)
|
// Init Audio (optional, async)
|
||||||
if enableAudio {
|
if enableAudio {
|
||||||
@ -132,15 +134,15 @@ extension CameraView: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAud
|
|||||||
|
|
||||||
if let audioOutput = self.audioOutput,
|
if let audioOutput = self.audioOutput,
|
||||||
let audioSettings = audioOutput.recommendedAudioSettingsForAssetWriter(writingTo: fileType) {
|
let audioSettings = audioOutput.recommendedAudioSettingsForAssetWriter(writingTo: fileType) {
|
||||||
self.recordingSession!.initializeAudioWriter(withSettings: audioSettings)
|
recordingSession.initializeAudioWriter(withSettings: audioSettings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// start recording session with or without audio.
|
// start recording session with or without audio.
|
||||||
do {
|
do {
|
||||||
try self.recordingSession!.start()
|
try recordingSession.start()
|
||||||
} catch {
|
} catch let error as NSError {
|
||||||
callback.reject(error: .capture(.createRecorderError(message: "RecordingSession failed to start writing.")))
|
callback.reject(error: .capture(.createRecorderError(message: "RecordingSession failed to start writing.")), cause: error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.isRecording = true
|
self.isRecording = true
|
||||||
|
@ -28,7 +28,7 @@ class RecordingSession {
|
|||||||
private let assetWriter: AVAssetWriter
|
private let assetWriter: AVAssetWriter
|
||||||
private var audioWriter: AVAssetWriterInput?
|
private var audioWriter: AVAssetWriterInput?
|
||||||
private var bufferAdaptor: AVAssetWriterInputPixelBufferAdaptor?
|
private var bufferAdaptor: AVAssetWriterInputPixelBufferAdaptor?
|
||||||
private let completionHandler: (AVAssetWriter.Status, Error?) -> Void
|
private let completionHandler: (RecordingSession, AVAssetWriter.Status, Error?) -> Void
|
||||||
|
|
||||||
private var initialTimestamp: CMTime?
|
private var initialTimestamp: CMTime?
|
||||||
private var latestTimestamp: CMTime?
|
private var latestTimestamp: CMTime?
|
||||||
@ -48,7 +48,7 @@ class RecordingSession {
|
|||||||
|
|
||||||
init(url: URL,
|
init(url: URL,
|
||||||
fileType: AVFileType,
|
fileType: AVFileType,
|
||||||
completion: @escaping (AVAssetWriter.Status, Error?) -> Void) throws {
|
completion: @escaping (RecordingSession, AVAssetWriter.Status, Error?) -> Void) throws {
|
||||||
completionHandler = completion
|
completionHandler = completion
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@ -197,15 +197,15 @@ class RecordingSession {
|
|||||||
let error = NSError(domain: "capture/aborted",
|
let error = NSError(domain: "capture/aborted",
|
||||||
code: 1,
|
code: 1,
|
||||||
userInfo: [NSLocalizedDescriptionKey: "Stopped Recording Session too early, no frames have been recorded!"])
|
userInfo: [NSLocalizedDescriptionKey: "Stopped Recording Session too early, no frames have been recorded!"])
|
||||||
completionHandler(.failed, error)
|
completionHandler(self, .failed, error)
|
||||||
} else if assetWriter.status == .writing {
|
} else if assetWriter.status == .writing {
|
||||||
assetWriter.finishWriting {
|
assetWriter.finishWriting {
|
||||||
self.bufferAdaptor?.assetWriterInput.markAsFinished()
|
self.bufferAdaptor?.assetWriterInput.markAsFinished()
|
||||||
self.audioWriter?.markAsFinished()
|
self.audioWriter?.markAsFinished()
|
||||||
self.completionHandler(self.assetWriter.status, self.assetWriter.error)
|
self.completionHandler(self, self.assetWriter.status, self.assetWriter.error)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
completionHandler(assetWriter.status, assetWriter.error)
|
completionHandler(self, assetWriter.status, assetWriter.error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user