Skip to content

Commit 784e16f

Browse files
committed
Migrate FLTAssetWriter class to Swift
1 parent b939170 commit 784e16f

File tree

12 files changed

+93
-232
lines changed

12 files changed

+93
-232
lines changed

packages/camera/camera_avfoundation/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## 0.9.22+7
22

3-
* Migrates `FLTCaptureConnection` and `FLTCaptureDeviceFormat` classes to Swift.
3+
* Migrates `FLTCaptureConnection`, `FLTCaptureDeviceFormat` and `FLTAssetWriter` classes to Swift.
44

55
## 0.9.22+6
66

packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ private final class TestMediaSettingsAVWrapper: FLTCamMediaSettingsAVWrapper {
7272
}
7373

7474
override func assetWriterAudioInput(withOutputSettings outputSettings: [String: Any]?)
75-
-> FLTAssetWriterInput
75+
-> AssetWriterInput
7676
{
7777
if let bitrate = outputSettings?[AVEncoderBitRateKey] as? Int, bitrate == testAudioBitrate {
7878
audioSettingsExpectation.fulfill()
@@ -81,7 +81,7 @@ private final class TestMediaSettingsAVWrapper: FLTCamMediaSettingsAVWrapper {
8181
}
8282

8383
override func assetWriterVideoInput(withOutputSettings outputSettings: [String: Any]?)
84-
-> FLTAssetWriterInput
84+
-> AssetWriterInput
8585
{
8686
if let compressionProperties = outputSettings?[AVVideoCompressionPropertiesKey]
8787
as? [String: Any],
@@ -101,7 +101,7 @@ private final class TestMediaSettingsAVWrapper: FLTCamMediaSettingsAVWrapper {
101101
return MockAssetWriterInput()
102102
}
103103

104-
override func addInput(_ writerInput: FLTAssetWriterInput, to writer: FLTAssetWriter) {
104+
override func addInput(_ writerInput: AssetWriterInput, to writer: AssetWriter) {
105105
// No-op.
106106
}
107107

packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockAssetWriter.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import camera_avfoundation
5+
@testable import camera_avfoundation
66

77
// Import Objective-C part of the implementation when SwiftPM is used.
88
#if canImport(camera_avfoundation_objc)
99
import camera_avfoundation_objc
1010
#endif
1111

12-
/// Mock implementation of `FLTAssetWriter` protocol which allows injecting a custom
12+
/// Mock implementation of `AssetWriter` protocol which allows injecting a custom
1313
/// implementation.
14-
final class MockAssetWriter: NSObject, FLTAssetWriter {
14+
final class MockAssetWriter: NSObject, AssetWriter {
1515
var statusStub: (() -> AVAssetWriter.Status)?
1616
var startWritingStub: (() -> Bool)?
1717
var finishWritingStub: ((() -> Void) -> Void)?

packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockAssetWriterInput.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,25 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import camera_avfoundation
5+
@testable import camera_avfoundation
66

77
// Import Objective-C part of the implementation when SwiftPM is used.
88
#if canImport(camera_avfoundation_objc)
99
import camera_avfoundation_objc
1010
#endif
1111

12-
/// Mock implementation of `FLTAssetWriterInput` protocol which allows injecting a custom
12+
/// Mock implementation of `AssetWriterInput` protocol which allows injecting a custom
1313
/// implementation.
14-
final class MockAssetWriterInput: NSObject, FLTAssetWriterInput {
14+
final class MockAssetWriterInput: NSObject, AssetWriterInput {
1515
var appendStub: ((CMSampleBuffer) -> Bool)?
1616

17-
var input: AVAssetWriterInput {
18-
preconditionFailure("Attempted to access unimplemented property: input")
17+
var avInput: AVAssetWriterInput {
18+
preconditionFailure("Attempted to access unimplemented property: avInput")
1919
}
2020

2121
var expectsMediaDataInRealTime = false
2222

23-
var readyForMoreMediaData = false
23+
var isReadyForMoreMediaData = false
2424

2525
func append(_ sampleBuffer: CMSampleBuffer) -> Bool {
2626
return appendStub?(sampleBuffer) ?? false

packages/camera/camera_avfoundation/example/ios/RunnerTests/Mocks/MockAssetWriterInputPixelBufferAdaptor.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import camera_avfoundation
5+
@testable import camera_avfoundation
66

77
// Import Objective-C part of the implementation when SwiftPM is used.
88
#if canImport(camera_avfoundation_objc)
99
import camera_avfoundation_objc
1010
#endif
1111

12-
/// Mock implementation of `FLTAssetWriterInputPixelBufferAdaptor` protocol which allows injecting a custom
12+
/// Mock implementation of `AssetWriterInputPixelBufferAdaptor` protocol which allows injecting a custom
1313
/// implementation.
14-
final class MockAssetWriterInputPixelBufferAdaptor: NSObject, FLTAssetWriterInputPixelBufferAdaptor
15-
{
14+
final class MockAssetWriterInputPixelBufferAdaptor: NSObject, AssetWriterInputPixelBufferAdaptor {
1615
var appendStub: ((CVPixelBuffer, CMTime) -> Bool)?
1716

1817
func append(_ pixelBuffer: CVPixelBuffer, withPresentationTime presentationTime: CMTime) -> Bool {

packages/camera/camera_avfoundation/example/ios/RunnerTests/SampleBufferTests.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,18 @@ private class FakeMediaSettingsAVWrapper: FLTCamMediaSettingsAVWrapper {
4444
}
4545

4646
override func assetWriterAudioInput(withOutputSettings outputSettings: [String: Any]?)
47-
-> FLTAssetWriterInput
47+
-> AssetWriterInput
4848
{
4949
return inputMock
5050
}
5151

5252
override func assetWriterVideoInput(withOutputSettings outputSettings: [String: Any]?)
53-
-> FLTAssetWriterInput
53+
-> AssetWriterInput
5454
{
5555
return inputMock
5656
}
5757

58-
override func addInput(_ writerInput: FLTAssetWriterInput, to writer: FLTAssetWriter) {
58+
override func addInput(_ writerInput: AssetWriterInput, to writer: AssetWriter) {
5959
// No-op.
6060
}
6161

@@ -175,7 +175,7 @@ final class CameraSampleBufferTests: XCTestCase {
175175
writtenSamples.append("video")
176176
return true
177177
}
178-
inputMock.readyForMoreMediaData = true
178+
inputMock.isReadyForMoreMediaData = true
179179
inputMock.appendStub = { buffer in
180180
writtenSamples.append("audio")
181181
return true
@@ -222,7 +222,7 @@ final class CameraSampleBufferTests: XCTestCase {
222222
}
223223

224224
var audioAppended = false
225-
inputMock.readyForMoreMediaData = true
225+
inputMock.isReadyForMoreMediaData = true
226226
inputMock.appendStub = { buffer in
227227
let sampleTime = CMSampleBufferGetPresentationTimeStamp(buffer)
228228
XCTAssert(CMTIME_IS_NUMERIC(sampleTime))
@@ -262,15 +262,15 @@ final class CameraSampleBufferTests: XCTestCase {
262262

263263
camera.startVideoRecording(completion: { error in }, messengerForStreaming: nil)
264264

265-
inputMock.readyForMoreMediaData = true
265+
inputMock.isReadyForMoreMediaData = true
266266
sampleAppended = false
267267
camera.captureOutput(
268268
camera.captureVideoOutput.avOutput,
269269
didOutput: videoSample,
270270
from: testVideoConnection)
271271
XCTAssertTrue(sampleAppended, "Sample was not appended.")
272272

273-
inputMock.readyForMoreMediaData = false
273+
inputMock.isReadyForMoreMediaData = false
274274
sampleAppended = false
275275
camera.captureOutput(
276276
camera.captureVideoOutput.avOutput,
@@ -327,7 +327,7 @@ final class CameraSampleBufferTests: XCTestCase {
327327
return true
328328
}
329329

330-
inputMock.readyForMoreMediaData = true
330+
inputMock.isReadyForMoreMediaData = true
331331

332332
camera.startVideoRecording(completion: { error in }, messengerForStreaming: nil)
333333

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2013 The Flutter Authors
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import AVFoundation
6+
import Foundation
7+
8+
/// A protocol that is a direct passthrough to `AVAssetWriter`. It is used to allow for mocking
9+
/// `AVAssetWriter` in tests.
10+
protocol AssetWriter: NSObjectProtocol {
11+
var status: AVAssetWriter.Status { get }
12+
var error: Error? { get }
13+
14+
func startWriting() -> Bool
15+
func finishWriting(completionHandler handler: @escaping @Sendable () -> Void)
16+
func startSession(atSourceTime startTime: CMTime)
17+
func add(_ input: AVAssetWriterInput)
18+
}
19+
20+
/// A protocol that is a direct passthrough to `AVAssetWriterInput`. It is used to allow for mocking
21+
/// `AVAssetWriterInput` in tests.
22+
protocol AssetWriterInput: NSObjectProtocol {
23+
/// The underlying `AVAssetWriterInput` instance. This exists so that the input
24+
/// can be extracted when adding to an AVAssetWriter.
25+
var avInput: AVAssetWriterInput { get }
26+
27+
var expectsMediaDataInRealTime: Bool { get set }
28+
var isReadyForMoreMediaData: Bool { get }
29+
30+
func append(_ sampleBuffer: CMSampleBuffer) -> Bool
31+
}
32+
33+
/// A protocol that is a direct passthrough to `AVAssetWriterInputPixelBufferAdaptor`. It is used to
34+
/// allow for mocking `AVAssetWriterInputPixelBufferAdaptor` in tests.
35+
protocol AssetWriterInputPixelBufferAdaptor: NSObjectProtocol {
36+
func append(_ pixelBuffer: CVPixelBuffer, withPresentationTime presentationTime: CMTime) -> Bool
37+
}
38+
39+
extension AVAssetWriter: AssetWriter {}
40+
41+
extension AVAssetWriterInput: AssetWriterInput {
42+
var avInput: AVAssetWriterInput { self }
43+
}
44+
45+
extension AVAssetWriterInputPixelBufferAdaptor: AssetWriterInputPixelBufferAdaptor {}

packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/CameraConfiguration.swift

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ typealias AudioCaptureDeviceFactory = () -> CaptureDevice
1919

2020
typealias CaptureSessionFactory = () -> CaptureSession
2121

22-
typealias AssetWriterFactory = (_ assetUrl: URL, _ fileType: AVFileType) throws -> FLTAssetWriter
22+
typealias AssetWriterFactory = (_ assetUrl: URL, _ fileType: AVFileType) throws -> AssetWriter
2323

2424
typealias InputPixelBufferAdaptorFactory = (
25-
_ input: FLTAssetWriterInput, _ settings: [String: Any]?
25+
_ input: AssetWriterInput, _ settings: [String: Any]?
2626
) ->
27-
FLTAssetWriterInputPixelBufferAdaptor
27+
AssetWriterInputPixelBufferAdaptor
2828

2929
/// A configuration object that centralizes dependencies for `DefaultCamera`.
3030
class CameraConfiguration {
@@ -70,22 +70,14 @@ class CameraConfiguration {
7070
}
7171

7272
self.assetWriterFactory = { url, fileType in
73-
var error: NSError?
74-
let writer = FLTDefaultAssetWriter(url: url, fileType: fileType, error: &error)
75-
76-
if let error = error {
77-
throw error
78-
}
79-
80-
return writer
73+
return try AVAssetWriter(outputURL: url, fileType: fileType)
8174
}
8275

8376
self.inputPixelBufferAdaptorFactory = { assetWriterInput, sourcePixelBufferAttributes in
84-
let adaptor = AVAssetWriterInputPixelBufferAdaptor(
85-
assetWriterInput: assetWriterInput.input,
77+
return AVAssetWriterInputPixelBufferAdaptor(
78+
assetWriterInput: assetWriterInput.avInput,
8679
sourcePixelBufferAttributes: sourcePixelBufferAttributes
8780
)
88-
return FLTDefaultAssetWriterInputPixelBufferAdaptor(adaptor: adaptor)
8981
}
9082
}
9183
}

packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ final class DefaultCamera: NSObject, Camera {
6767
var capturePhotoOutput: CapturePhotoOutput
6868
private var captureVideoInput: CaptureInput
6969

70-
private var videoWriter: FLTAssetWriter?
71-
private var videoWriterInput: FLTAssetWriterInput?
72-
private var audioWriterInput: FLTAssetWriterInput?
73-
private var assetWriterPixelBufferAdaptor: FLTAssetWriterInputPixelBufferAdaptor?
74-
private var videoAdaptor: FLTAssetWriterInputPixelBufferAdaptor?
70+
private var videoWriter: AssetWriter?
71+
private var videoWriterInput: AssetWriterInput?
72+
private var audioWriterInput: AssetWriterInput?
73+
private var assetWriterPixelBufferAdaptor: AssetWriterInputPixelBufferAdaptor?
74+
private var videoAdaptor: AssetWriterInputPixelBufferAdaptor?
7575

7676
/// A dictionary to retain all in-progress FLTSavePhotoDelegates. The key of the dictionary is the
7777
/// AVCapturePhotoSettings's uniqueID for each photo capture operation, and the value is the
@@ -524,7 +524,7 @@ final class DefaultCamera: NSObject, Camera {
524524
private func setupWriter(forPath path: String) -> Bool {
525525
setUpCaptureSessionForAudioIfNeeded()
526526

527-
let videoWriter: FLTAssetWriter
527+
let videoWriter: AssetWriter
528528

529529
do {
530530
videoWriter = try assetWriterFactory(URL(fileURLWithPath: path), .mp4)
@@ -1218,7 +1218,7 @@ final class DefaultCamera: NSObject, Camera {
12181218
let nextSampleTime = CMTimeSubtract(lastVideoSampleTime, videoTimeOffset)
12191219
// do not append sample buffer when readyForMoreMediaData is NO to avoid crash
12201220
// https://github.com/flutter/flutter/issues/132073
1221-
if videoWriterInput?.readyForMoreMediaData ?? false {
1221+
if videoWriterInput?.isReadyForMoreMediaData ?? false {
12221222
videoAdaptor?.append(nextBuffer!, withPresentationTime: nextSampleTime)
12231223
}
12241224
} else {
@@ -1368,7 +1368,7 @@ final class DefaultCamera: NSObject, Camera {
13681368
}
13691369
return
13701370
}
1371-
if audioWriterInput?.readyForMoreMediaData ?? false {
1371+
if audioWriterInput?.isReadyForMoreMediaData ?? false {
13721372
if !(audioWriterInput?.append(sampleBuffer) ?? false) {
13731373
reportErrorMessage("Unable to write to audio input")
13741374
}

packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/MediaSettingsAVWrapper.swift

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,31 +64,29 @@ class FLTCamMediaSettingsAVWrapper {
6464
/// Creates a new input of the audio media type to receive sample buffers for writing to
6565
/// the output file.
6666
/// - Parameter outputSettings: The settings used for encoding the audio appended to the output.
67-
/// - Returns: An instance of `FLTAssetWriterInput`.
67+
/// - Returns: An instance of `AssetWriterInput`.
6868
func assetWriterAudioInput(withOutputSettings outputSettings: [String: Any]?)
69-
-> FLTAssetWriterInput
69+
-> AssetWriterInput
7070
{
71-
let input = AVAssetWriterInput(mediaType: .audio, outputSettings: outputSettings)
72-
return FLTDefaultAssetWriterInput(input: input)
71+
return AVAssetWriterInput(mediaType: .audio, outputSettings: outputSettings)
7372
}
7473

7574
/// Creates a new input of the video media type to receive sample buffers for writing to
7675
/// the output file.
7776
/// - Parameter outputSettings: The settings used for encoding the video appended to the output.
78-
/// - Returns: An instance of `FLTAssetWriterInput`.
77+
/// - Returns: An instance of `AssetWriterInput`.
7978
func assetWriterVideoInput(withOutputSettings outputSettings: [String: Any]?)
80-
-> FLTAssetWriterInput
79+
-> AssetWriterInput
8180
{
82-
let input = AVAssetWriterInput(mediaType: .video, outputSettings: outputSettings)
83-
return FLTDefaultAssetWriterInput(input: input)
81+
return AVAssetWriterInput(mediaType: .video, outputSettings: outputSettings)
8482
}
8583

8684
/// Adds an input to the asset writer.
8785
/// - Parameters:
88-
/// - writerInput: The `FLTAssetWriterInput` object to be added.
89-
/// - writer: The `FLTAssetWriter` object.
90-
func addInput(_ writerInput: FLTAssetWriterInput, to writer: FLTAssetWriter) {
91-
writer.add(writerInput.input)
86+
/// - writerInput: The `AssetWriterInput` object to be added.
87+
/// - writer: The `AssetWriter` object.
88+
func addInput(_ writerInput: AssetWriterInput, to writer: AssetWriter) {
89+
writer.add(writerInput.avInput)
9290
}
9391

9492
/// Specifies the recommended video settings for `FLTCaptureVideoDataOutput`.

0 commit comments

Comments
 (0)