@@ -41,8 +41,8 @@ actor SampleWriter {
4141
4242 // MARK: Internal state
4343
44- private let reader : AVAssetReader
45- private let writer : AVAssetWriter
44+ private var reader : AVAssetReader ?
45+ private var writer : AVAssetWriter ?
4646 private var audioOutput : AVAssetReaderAudioMixOutput ?
4747 private var audioInput : AVAssetWriterInput ?
4848 private var videoOutput : AVAssetReaderVideoCompositionOutput ?
@@ -111,15 +111,15 @@ actor SampleWriter {
111111
112112 progressContinuation. yield ( 0.0 )
113113
114- writer. startWriting ( )
115- writer. startSession ( atSourceTime: timeRange. start)
116- reader. startReading ( )
114+ writer? . startWriting ( )
115+ writer? . startSession ( atSourceTime: timeRange. start)
116+ reader? . startReading ( )
117117 try Task . checkCancellation ( )
118118
119119 startEncodingAudioTracks ( )
120120 startEncodingVideoTracks ( )
121121
122- while reader. status == . reading, writer. status == . writing {
122+ while reader? . status == . reading, writer? . status == . writing {
123123 guard !Task. isCancelled else {
124124 // Flag so that we stop writing samples
125125 isCancelled = true
@@ -129,24 +129,29 @@ actor SampleWriter {
129129 try await Task . sleep ( for: . milliseconds( 10 ) )
130130 }
131131
132- guard !isCancelled, reader. status != . cancelled, writer. status != . cancelled else {
132+ defer {
133+ cleanUp ( )
134+ }
135+
136+ guard !isCancelled, reader? . status != . cancelled, writer? . status != . cancelled else {
133137 log. debug ( " Cancelled before writing samples " )
134- reader. cancelReading ( )
135- writer. cancelWriting ( )
138+ cancelReaderAndWriter ( )
136139 throw CancellationError ( )
137140 }
138- guard writer. status != . failed else {
139- reader. cancelReading ( )
140- throw Error . writeFailure ( writer. error)
141+ guard writer? . status != . failed else {
142+ reader? . cancelReading ( )
143+ throw Error . writeFailure ( writer? . error)
141144 }
142- guard reader. status != . failed else {
143- writer. cancelWriting ( )
144- throw Error . readFailure ( reader. error)
145+ guard reader? . status != . failed else {
146+ writer? . cancelWriting ( )
147+ throw Error . readFailure ( reader? . error)
145148 }
146149
147- await withCheckedContinuation { continuation in
148- writer. finishWriting {
149- continuation. resume ( returning: ( ) )
150+ if let writer {
151+ await withCheckedContinuation { continuation in
152+ writer. finishWriting {
153+ continuation. resume ( returning: ( ) )
154+ }
150155 }
151156 }
152157
@@ -169,15 +174,15 @@ actor SampleWriter {
169174 let audioOutput = AVAssetReaderAudioMixOutput ( audioTracks: audioTracks, audioSettings: nil )
170175 audioOutput. alwaysCopiesSampleData = false
171176 audioOutput. audioMix = audioMix
172- guard reader. canAdd ( audioOutput) else {
177+ guard let reader , reader. canAdd ( audioOutput) else {
173178 throw Error . setupFailure ( . cannotAddAudioOutput)
174179 }
175180 reader. add ( audioOutput)
176181 self . audioOutput = audioOutput
177182
178183 let audioInput = AVAssetWriterInput ( mediaType: . audio, outputSettings: audioOutputSettings)
179184 audioInput. expectsMediaDataInRealTime = false
180- guard writer. canAdd ( audioInput) else {
185+ guard let writer , writer. canAdd ( audioInput) else {
181186 throw Error . setupFailure ( . cannotAddAudioInput)
182187 }
183188 writer. add ( audioInput)
@@ -193,15 +198,15 @@ actor SampleWriter {
193198 )
194199 videoOutput. alwaysCopiesSampleData = false
195200 videoOutput. videoComposition = videoComposition
196- guard reader. canAdd ( videoOutput) else {
201+ guard let reader , reader. canAdd ( videoOutput) else {
197202 throw Error . setupFailure ( . cannotAddVideoOutput)
198203 }
199204 reader. add ( videoOutput)
200205 self . videoOutput = videoOutput
201206
202207 let videoInput = AVAssetWriterInput ( mediaType: . video, outputSettings: videoOutputSettings)
203208 videoInput. expectsMediaDataInRealTime = false
204- guard writer. canAdd ( videoInput) else {
209+ guard let writer , writer. canAdd ( videoInput) else {
205210 throw Error . setupFailure ( . cannotAddVideoInput)
206211 }
207212 writer. add ( videoInput)
@@ -233,11 +238,25 @@ actor SampleWriter {
233238 }
234239 }
235240
241+ private func cancelReaderAndWriter( ) {
242+ reader? . cancelReading ( )
243+ writer? . cancelWriting ( )
244+ cleanUp ( )
245+ }
246+
247+ private func cleanUp( ) {
248+ reader = nil
249+ writer = nil
250+ audioInput = nil
251+ audioOutput = nil
252+ videoInput = nil
253+ videoOutput = nil
254+ }
255+
236256 private func writeAllReadySamples( ) {
237257 guard !isCancelled else {
238258 log. debug ( " Cancelled while writing samples " )
239- reader. cancelReading ( )
240- writer. cancelWriting ( )
259+ cancelReaderAndWriter ( )
241260 return
242261 }
243262
@@ -254,11 +273,10 @@ actor SampleWriter {
254273 while input. isReadyForMoreMediaData {
255274 guard !isCancelled else {
256275 log. debug ( " Cancelled while writing samples " )
257- reader. cancelReading ( )
258- writer. cancelWriting ( )
276+ cancelReaderAndWriter ( )
259277 return false
260278 }
261- guard reader. status == . reading && writer. status == . writing,
279+ guard reader? . status == . reading && writer? . status == . writing,
262280 let sampleBuffer = output. copyNextSampleBuffer ( ) else {
263281 input. markAsFinished ( )
264282 return false
0 commit comments