fix: Asset Writer Video-Audio Sync (#1075)
* fix: Start asset writer session on first frame * fix: Remove debug log * fix: Reset dev team
This commit is contained in:
parent
de41f8be83
commit
fb2156ec39
@ -324,7 +324,7 @@ PODS:
|
|||||||
- React
|
- React
|
||||||
- RNVectorIcons (8.1.0):
|
- RNVectorIcons (8.1.0):
|
||||||
- React-Core
|
- React-Core
|
||||||
- VisionCamera (2.13.0):
|
- VisionCamera (2.13.3):
|
||||||
- React
|
- React
|
||||||
- React-callinvoker
|
- React-callinvoker
|
||||||
- React-Core
|
- React-Core
|
||||||
@ -504,7 +504,7 @@ SPEC CHECKSUMS:
|
|||||||
RNScreens: 40a2cb40a02a609938137a1e0acfbf8fc9eebf19
|
RNScreens: 40a2cb40a02a609938137a1e0acfbf8fc9eebf19
|
||||||
RNStaticSafeAreaInsets: 6103cf09647fa427186d30f67b0f5163c1ae8252
|
RNStaticSafeAreaInsets: 6103cf09647fa427186d30f67b0f5163c1ae8252
|
||||||
RNVectorIcons: 31cebfcf94e8cf8686eb5303ae0357da64d7a5a4
|
RNVectorIcons: 31cebfcf94e8cf8686eb5303ae0357da64d7a5a4
|
||||||
VisionCamera: 9959a41d3edc36b37e8361a2e6cbc05714f0689b
|
VisionCamera: 7bcf3a81533a1c9ad13930804377ad13a03fcded
|
||||||
Yoga: e7dc4e71caba6472ff48ad7d234389b91dadc280
|
Yoga: e7dc4e71caba6472ff48ad7d234389b91dadc280
|
||||||
|
|
||||||
PODFILE CHECKSUM: 29b1752e05601e9867644e58ce0ed8b9106be6cb
|
PODFILE CHECKSUM: 29b1752e05601e9867644e58ce0ed8b9106be6cb
|
||||||
|
@ -456,7 +456,7 @@
|
|||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 ";
|
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
@ -517,7 +517,7 @@
|
|||||||
COPY_PHASE_STRIP = YES;
|
COPY_PHASE_STRIP = YES;
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 ";
|
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
@ -140,9 +140,9 @@ extension CameraView: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAud
|
|||||||
|
|
||||||
// start recording session with or without audio.
|
// start recording session with or without audio.
|
||||||
do {
|
do {
|
||||||
try recordingSession.start()
|
try recordingSession.startAssetWriter()
|
||||||
} catch let error as NSError {
|
} catch let error as NSError {
|
||||||
callback.reject(error: .capture(.createRecorderError(message: "RecordingSession failed to start writing.")), cause: error)
|
callback.reject(error: .capture(.createRecorderError(message: "RecordingSession failed to start asset writer.")), cause: error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.isRecording = true
|
self.isRecording = true
|
||||||
|
@ -32,6 +32,7 @@ class RecordingSession {
|
|||||||
|
|
||||||
private var initialTimestamp: CMTime?
|
private var initialTimestamp: CMTime?
|
||||||
private var latestTimestamp: CMTime?
|
private var latestTimestamp: CMTime?
|
||||||
|
private var hasStartedWritingSession = false
|
||||||
private var hasWrittenFirstVideoFrame = false
|
private var hasWrittenFirstVideoFrame = false
|
||||||
private var isFinishing = false
|
private var isFinishing = false
|
||||||
|
|
||||||
@ -111,7 +112,7 @@ class RecordingSession {
|
|||||||
/**
|
/**
|
||||||
Start the Asset Writer(s). If the AssetWriter failed to start, an error will be thrown.
|
Start the Asset Writer(s). If the AssetWriter failed to start, an error will be thrown.
|
||||||
*/
|
*/
|
||||||
func start() throws {
|
func startAssetWriter() throws {
|
||||||
ReactLogger.log(level: .info, message: "Starting Asset Writer(s)...")
|
ReactLogger.log(level: .info, message: "Starting Asset Writer(s)...")
|
||||||
|
|
||||||
let success = assetWriter.startWriting()
|
let success = assetWriter.startWriting()
|
||||||
@ -119,10 +120,6 @@ class RecordingSession {
|
|||||||
ReactLogger.log(level: .error, message: "Failed to start Asset Writer(s)!")
|
ReactLogger.log(level: .error, message: "Failed to start Asset Writer(s)!")
|
||||||
throw RecordingSessionError.failedToStartSession
|
throw RecordingSessionError.failedToStartSession
|
||||||
}
|
}
|
||||||
|
|
||||||
initialTimestamp = CMTime(seconds: CACurrentMediaTime(), preferredTimescale: 1_000_000_000)
|
|
||||||
assetWriter.startSession(atSourceTime: initialTimestamp!)
|
|
||||||
ReactLogger.log(level: .info, message: "Started RecordingSession at \(initialTimestamp!.seconds) seconds.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,11 +135,6 @@ class RecordingSession {
|
|||||||
ReactLogger.log(level: .error, message: "Frame arrived, but sample buffer is not ready!")
|
ReactLogger.log(level: .error, message: "Frame arrived, but sample buffer is not ready!")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
guard let initialTimestamp = initialTimestamp else {
|
|
||||||
ReactLogger.log(level: .error,
|
|
||||||
message: "A frame arrived, but initialTimestamp was nil. Is this RecordingSession running?")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
latestTimestamp = timestamp
|
latestTimestamp = timestamp
|
||||||
|
|
||||||
@ -161,10 +153,15 @@ class RecordingSession {
|
|||||||
ReactLogger.log(level: .error, message: "Failed to get the CVImageBuffer!")
|
ReactLogger.log(level: .error, message: "Failed to get the CVImageBuffer!")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Start the writing session before we write the first video frame
|
||||||
|
if !hasStartedWritingSession {
|
||||||
|
assetWriter.startSession(atSourceTime: timestamp)
|
||||||
|
ReactLogger.log(level: .info, message: "Started RecordingSession at \(timestamp.seconds) seconds.")
|
||||||
|
hasStartedWritingSession = true
|
||||||
|
}
|
||||||
bufferAdaptor.append(imageBuffer, withPresentationTime: timestamp)
|
bufferAdaptor.append(imageBuffer, withPresentationTime: timestamp)
|
||||||
if !hasWrittenFirstVideoFrame {
|
if !hasWrittenFirstVideoFrame {
|
||||||
hasWrittenFirstVideoFrame = true
|
hasWrittenFirstVideoFrame = true
|
||||||
ReactLogger.log(level: .warning, message: "VideoWriter: First frame arrived \((initialTimestamp - timestamp).seconds) seconds late.")
|
|
||||||
}
|
}
|
||||||
case .audio:
|
case .audio:
|
||||||
guard let audioWriter = audioWriter else {
|
guard let audioWriter = audioWriter else {
|
||||||
@ -174,7 +171,7 @@ class RecordingSession {
|
|||||||
if !audioWriter.isReadyForMoreMediaData {
|
if !audioWriter.isReadyForMoreMediaData {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !hasWrittenFirstVideoFrame {
|
if !hasWrittenFirstVideoFrame || !hasStartedWritingSession {
|
||||||
// first video frame has not been written yet, so skip this audio frame.
|
// first video frame has not been written yet, so skip this audio frame.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user