Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 509c13a

Browse files
update
1 parent 1ad3791 commit 509c13a

File tree

2 files changed

+55
-86
lines changed

2 files changed

+55
-86
lines changed

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

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public protocol AbstractPlayer: AnyObject {
110110
func applyVideoComposition()
111111

112112
/// Updates the current playback asset, settings, and initializes playback or a specific action when the asset is ready.
113-
func update(settings: VideoSettings, asset : AVURLAsset?)
113+
func update(settings: VideoSettings, doUpdate : Bool)
114114
}
115115

116116
extension AbstractPlayer{
@@ -188,24 +188,25 @@ extension AbstractPlayer{
188188
/// the observer is invalidated, ensuring that the callback is called only once.
189189
///
190190
/// - Parameters:
191-
/// - newItem: The `AVPlayerItem` whose status is to be observed.
191+
/// - item: The `AVPlayerItem` whose status is to be observed.
192192
/// - callback: A closure that is called when the item's status changes to `.readyToPlay` or `.failed`.
193-
func setupStateItemStatusObserver(newItem: AVPlayerItem, callback : @escaping (AVPlayerItem.Status) -> Void) {
193+
func setupStateStatusObserver(for item: AVPlayerItem, callback : @escaping (AVPlayerItem.Status) -> Void) {
194194

195195
clearStatusObserver()
196196

197-
guard newItem.status == .unknown else{
198-
callback(newItem.status)
197+
guard item.status == .unknown else{
198+
callback(item.status)
199199
return
200200
}
201201

202-
//.unknown: This state is essentially the default, indicating that the player item is new or has not yet attempted to load its assets.
203-
statusObserver = newItem.observe(\.status, options:[.new,.old]){[weak self] item, _ in
202+
statusObserver = item.observe(\.status, options:[.new,.initial]){[weak self] item, change in
203+
print(item.status.rawValue,"status")
204204
guard item.status == .readyToPlay || item.status == .failed else {
205205
return
206206
}
207207

208208
callback(item.status)
209+
209210
Task { @MainActor in
210211
self?.clearStatusObserver()
211212
}
@@ -219,31 +220,52 @@ extension AbstractPlayer{
219220
statusObserver = nil
220221
}
221222
}
223+
224+
/// Creates an `AVPlayerItem` with optional subtitle merging.
225+
/// - Parameters:
226+
/// - asset: The main video asset.
227+
/// - settings: A `VideoSettings` object containing subtitle configuration.
228+
/// - Returns: A new `AVPlayerItem` configured with the merged or original asset.
229+
func createPlayerItem(with settings: VideoSettings) -> AVPlayerItem? {
230+
231+
guard let asset = assetFor(settings) else{
232+
delegate?.didReceiveError(.sourceNotFound(settings.name))
233+
return nil
234+
}
235+
236+
if let subtitleAsset = subtitlesAssetFor(settings),
237+
let mergedAsset = mergeAssetWithSubtitles(videoAsset: asset, subtitleAsset: subtitleAsset) {
238+
// Create and return a new `AVPlayerItem` using the merged asset
239+
return AVPlayerItem(asset: mergedAsset)
240+
} else {
241+
// Create and return a new `AVPlayerItem` using the original asset
242+
return AVPlayerItem(asset: asset)
243+
}
244+
}
222245

223246
/// Seeks the video to a specific time.
224247
/// This method moves the playback position to the specified time with precise accuracy.
225248
/// If the specified time is out of bounds, it will be clamped to the nearest valid time.
226249
/// - Parameter time: The target time to seek to in the video timeline.
227250
func seek(to time: Double, play: Bool = false) {
228251
guard let player = player, let duration = player.currentItem?.duration else {
229-
if let settings = currentSettings{
230-
let callback : (AVPlayerItem.Status) -> Void = { [weak self] status in
231-
if status == .readyToPlay{
232-
self?.seek(to: time, play: play)
233-
}else {
234-
self?.delegate?.didSeek(value: false, currentTime: time)
235-
}
236-
}
237-
update(settings: settings, asset: assetFor(settings))
238-
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5){
239-
if let item = self.currentItem{
240-
self.setupStateItemStatusObserver(newItem: item, callback: callback)
241-
}
242-
}
243-
}else{
252+
guard let settings = currentSettings else{
244253
delegate?.didSeek(value: false, currentTime: time)
254+
return
255+
}
256+
update(settings: settings, doUpdate: true)
257+
let callback : (AVPlayerItem.Status) -> Void = { [weak self] status in
258+
guard status == .readyToPlay else {
259+
self?.delegate?.didSeek(value: false, currentTime: time)
260+
return
261+
}
262+
self?.seek(to: time, play: play)
263+
}
264+
/// Need to refactor
265+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5){ [weak self] in
266+
guard let item = self?.currentItem else { return }
267+
self?.setupStateStatusObserver(for: item, callback: callback)
245268
}
246-
247269
return
248270
}
249271

@@ -274,6 +296,8 @@ extension AbstractPlayer{
274296
self?.delegate?.didSeek(value: value, currentTime: currentTime)
275297
if play{
276298
self?.play()
299+
}else{
300+
self?.pause()
277301
}
278302
}
279303
}

‎Sources/swiftui-loop-videoplayer/protocol/player/ExtPlayerProtocol.swift‎

Lines changed: 8 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -167,21 +167,19 @@ internal extension ExtPlayerProtocol {
167167
/// - Parameters:
168168
/// - settings: A `VideoSettings` struct containing configurations such as playback gravity,
169169
/// whether to loop the content, and whether to mute the audio.
170-
/// - asset: An optional `AVURLAsset` representing the new video content to be loaded. If nil,
171-
/// the current asset continues playing with updated settings.
172-
/// - callback: An optional closure executed when the asset reaches `.readyToPlay` status,
173-
/// providing the new status as its parameter for handling additional setup or errors.
174-
func update(
175-
settings: VideoSettings,
176-
asset : AVURLAsset? = nil
177-
) {
178-
guard let asset = prepareAsset(settings, asset) else { return }
170+
func update(settings: VideoSettings, doUpdate : Bool = false) {
171+
172+
if doUpdate == false && settings.isEqual(currentSettings){
173+
return
174+
}
179175

180176
stop()
181177

182178
currentSettings = settings
183179

184-
let newItem = createPlayerItem(with: asset, settings: settings)
180+
guard let newItem = createPlayerItem(with: settings) else{
181+
return
182+
}
185183

186184
insert(newItem)
187185

@@ -193,59 +191,6 @@ internal extension ExtPlayerProtocol {
193191
play()
194192
}
195193
}
196-
197-
/// Prepares and validates the media asset for playback based on the given settings.
198-
///
199-
/// This function determines the appropriate `AVURLAsset` to use for media playback.
200-
/// If a specific asset is provided, it uses that asset; otherwise, it attempts to retrieve
201-
/// an asset based on the provided settings. If the settings have changed from the current settings,
202-
/// it fetches a new asset using a method presumed to be `getAssets()`. If no valid asset is found or
203-
/// provided, it notifies a delegate of the error.
204-
///
205-
/// - Parameters:
206-
/// - settings: The `VideoSettings` containing configuration and asset retrieval logic.
207-
/// - asset: An optional `AVURLAsset` to be used directly if provided. If nil, an asset is attempted
208-
/// to be retrieved based on the `settings`.
209-
///
210-
/// - Returns: An optional `AVURLAsset` if a valid asset is found or provided; otherwise, nil if no
211-
/// valid asset could be located or an error occurred.
212-
///
213-
/// - Note: This function calls `didReceiveError` on the delegate with an error of `.sourceNotFound`
214-
/// if no valid asset is found, providing context for the failure.
215-
func prepareAsset(_ settings: VideoSettings, _ asset: AVURLAsset? = nil) -> AVURLAsset? {
216-
if let asset = asset {
217-
return asset
218-
}
219-
220-
let newAsset = settings.getAssets()
221-
222-
if !settings.isEqual(currentSettings), let newAsset{
223-
return newAsset
224-
}
225-
226-
if newAsset == nil {
227-
delegate?.didReceiveError(.sourceNotFound(settings.name))
228-
}
229-
230-
return nil
231-
}
232-
233-
/// Creates an `AVPlayerItem` with optional subtitle merging.
234-
/// - Parameters:
235-
/// - asset: The main video asset.
236-
/// - settings: A `VideoSettings` object containing subtitle configuration.
237-
/// - Returns: A new `AVPlayerItem` configured with the merged or original asset.
238-
func createPlayerItem(with asset: AVURLAsset, settings: VideoSettings) -> AVPlayerItem {
239-
// Attempt to retrieve the subtitle asset
240-
if let subtitleAsset = subtitlesAssetFor(settings),
241-
let mergedAsset = mergeAssetWithSubtitles(videoAsset: asset, subtitleAsset: subtitleAsset) {
242-
// Create and return a new `AVPlayerItem` using the merged asset
243-
return AVPlayerItem(asset: mergedAsset)
244-
} else {
245-
// Create and return a new `AVPlayerItem` using the original asset
246-
return AVPlayerItem(asset: asset)
247-
}
248-
}
249194

250195
/// Sets up observers on the player item and the player to track their status and error states.
251196
///

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /