Skip to content

Commit f9734ab

Browse files
committed
refactoring
1 parent 1cd2bcf commit f9734ab

File tree

3 files changed

+59
-65
lines changed

3 files changed

+59
-65
lines changed

Sources/swiftui-loop-videoplayer/fn/fn+.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,27 @@ internal func combineFilters(_ filters: [CIFilter],_ brightness: Float,_ contra
8282
return allFilters
8383
}
8484

85+
/// Processes an asynchronous video composition request by applying a series of CIFilters.
86+
/// This function ensures each frame processed conforms to specified filter effects.
87+
///
88+
/// - Parameters:
89+
/// - request: An AVAsynchronousCIImageFilteringRequest object representing the current video frame to be processed.
90+
/// - filters: An array of CIFilters to be applied sequentially to the video frame.
91+
///
92+
/// The function starts by clamping the source image to ensure coordinates remain within the image bounds,
93+
/// applies each filter in the provided array, and completes by returning the modified image to the composition request.
94+
internal func handleVideoComposition(request: AVAsynchronousCIImageFilteringRequest, filters: [CIFilter]) {
95+
// Start with the source image, ensuring it's clamped to avoid any coordinate issues
96+
var currentImage = request.sourceImage.clampedToExtent()
97+
98+
// Apply each filter in the array to the image
99+
for filter in filters {
100+
filter.setValue(currentImage, forKey: kCIInputImageKey)
101+
if let outputImage = filter.outputImage {
102+
currentImage = outputImage.clampedToExtent()
103+
}
104+
}
105+
// Finish the composition request by outputting the final image
106+
request.finish(with: currentImage, context: nil)
107+
}
108+

Sources/swiftui-loop-videoplayer/protocol/player/AbstractPlayer.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,39 @@ extension AbstractPlayer{
309309
applyVideoComposition()
310310
}
311311
}
312+
313+
/// Applies the current set of filters to the video using an AVVideoComposition.
314+
/// This method combines the existing filters and brightness/contrast adjustments, creates a new video composition,
315+
/// and assigns it to the current AVPlayerItem. The video is paused during this process to ensure smooth application.
316+
/// This method is not supported on Vision OS.
317+
func applyVideoComposition() {
318+
guard let player = player else { return }
319+
let allFilters = combineFilters(filters, brightness, contrast)
320+
321+
#if !os(visionOS)
322+
// Optionally, check if the player is currently playing
323+
let wasPlaying = player.rate != 0
324+
325+
// Pause the player if it was playing
326+
if wasPlaying {
327+
player.pause()
328+
}
329+
330+
player.items().forEach{ item in
331+
332+
let videoComposition = AVVideoComposition(asset: item.asset, applyingCIFiltersWithHandler: { request in
333+
handleVideoComposition(request: request, filters: allFilters)
334+
})
335+
336+
item.videoComposition = videoComposition
337+
}
338+
339+
if wasPlaying{
340+
player.play()
341+
}
342+
343+
#endif
344+
}
312345

313346
/// Selects an audio track for the video playback.
314347
/// - Parameter languageCode: The language code (e.g., "en" for English) of the desired audio track.

Sources/swiftui-loop-videoplayer/protocol/player/LoopingPlayerProtocol.swift

Lines changed: 2 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,9 @@ internal extension LoopingPlayerProtocol {
8484

8585
// Replace the current item
8686
let newItem = AVPlayerItem(asset: asset)
87-
player.replaceCurrentItem(with: newItem)
87+
player.insert(newItem, after: nil)
8888
loop()
89-
applyVideoComposition()
90-
91-
player.seek(to: .zero, completionHandler: { [weak self] _ in
92-
if wasPlaying {
93-
self?.play()
94-
}
95-
})
89+
play()
9690
}
9791

9892
/// Sets up the player components with the specified media asset, display properties, and optional time publishing interval.
@@ -190,63 +184,6 @@ internal extension LoopingPlayerProtocol {
190184
delegate?.didReceiveError(.remoteVideoError(error))
191185
}
192186

193-
/// Processes an asynchronous video composition request by applying a series of CIFilters.
194-
/// This function ensures each frame processed conforms to specified filter effects.
195-
///
196-
/// - Parameters:
197-
/// - request: An AVAsynchronousCIImageFilteringRequest object representing the current video frame to be processed.
198-
/// - filters: An array of CIFilters to be applied sequentially to the video frame.
199-
///
200-
/// The function starts by clamping the source image to ensure coordinates remain within the image bounds,
201-
/// applies each filter in the provided array, and completes by returning the modified image to the composition request.
202-
static func handleVideoComposition(request: AVAsynchronousCIImageFilteringRequest, filters: [CIFilter]) {
203-
// Start with the source image, ensuring it's clamped to avoid any coordinate issues
204-
var currentImage = request.sourceImage.clampedToExtent()
205-
206-
// Apply each filter in the array to the image
207-
for filter in filters {
208-
filter.setValue(currentImage, forKey: kCIInputImageKey)
209-
if let outputImage = filter.outputImage {
210-
currentImage = outputImage.clampedToExtent()
211-
}
212-
}
213-
// Finish the composition request by outputting the final image
214-
request.finish(with: currentImage, context: nil)
215-
}
216-
217-
/// Applies the current set of filters to the video using an AVVideoComposition.
218-
/// This method combines the existing filters and brightness/contrast adjustments, creates a new video composition,
219-
/// and assigns it to the current AVPlayerItem. The video is paused during this process to ensure smooth application.
220-
/// This method is not supported on Vision OS.
221-
func applyVideoComposition() {
222-
guard let player = player else { return }
223-
let allFilters = combineFilters(filters, brightness, contrast)
224-
225-
#if !os(visionOS)
226-
// Optionally, check if the player is currently playing
227-
let wasPlaying = player.rate != 0
228-
229-
// Pause the player if it was playing
230-
if wasPlaying {
231-
player.pause()
232-
}
233-
234-
player.items().forEach{ item in
235-
236-
let videoComposition = AVVideoComposition(asset: item.asset, applyingCIFiltersWithHandler: { request in
237-
Self.handleVideoComposition(request: request, filters: allFilters)
238-
})
239-
240-
item.videoComposition = videoComposition
241-
}
242-
243-
if wasPlaying{
244-
player.play()
245-
}
246-
247-
#endif
248-
}
249-
250187
/// Clears all items from the player's queue.
251188
func clearPlayerQueue() {
252189
guard let items = player?.items() else { return }

0 commit comments

Comments
 (0)