Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Repeat modes #899

Closed
9 tasks done
defagos opened this issue May 30, 2024 · 6 comments · Fixed by #993
Closed
9 tasks done

Repeat modes #899

defagos opened this issue May 30, 2024 · 6 comments · Fixed by #993
Assignees
Labels
enhancement New feature or request

Comments

@defagos
Copy link
Member

defagos commented May 30, 2024

As a user I want some playback experiences to provide me with repeat modes:

  • Repeat one: When enabled, repeats the current content in a playlist.
  • Repeat all: When enabled, repeats the whole playlist at the end.

Hints

  • ExoPlayer API documentation for inspiration.

Acceptance criteria

  • An API is available to set the repeat mode (can be none).
  • A repeat mode toggle button (none, one, all) has been added to the playlist demo.
  • Advancing to the next / returning to the previous item wraps around the playlist in repeat all mode.
  • Advancing to the next / returning to the previous item in repeat one mode moves to the next / previous item, as usual.
  • In all repeat modes the playback experience is gapless.

Hints

Maybe AVPlayerLooper might be helpful (maybe not).

Tasks

  • Check with AVQueuePlayer and AVPlayerLooper how repeat modes interact with actionAtItemEnd so that we can better understand how our implementation should behave.
  • Add repeat modes:
    • Update behavior when syncing queue items with content updates.
    • Update (can) advance to next APIs (properly handle single-item queues).
    • Probably force an AVPlayerQueue item queue update when the repeat mode is changed.
  • Update the playlist demo with a dedicated button.
  • Make sure each individual loop is a separate comScore analytics session.
  • Check tacker behavior.
  • Check network activity (e.g. preload of next stored item).
@defagos defagos added the enhancement New feature or request label May 30, 2024
@defagos
Copy link
Member Author

defagos commented May 31, 2024

Three ideas to tackle this issue:

  1. Use item end notification to apply the behavior. Probably requires internal queue player actionAtItemEnd to be tweaked (not the external value) to have playback paused before applying the behavior, otherwise the item might be consumed early. It might be difficult to obtain a gapless playback experience with this approach, though.
  2. Use AVPlayerLooper to manage repeat one behavior, and inject the first AVPlayerItem in the AVQueuePlayer at the end of the playlist to have pre-buffering work in the repeat all mode.
  3. Maybe the easiest and most consistent approach to deal with all repeat modes is to insert the current AVPlayerItem twice in repeat one, and the first one at the end of the playlist in repeat all. Since we are managing the AVQueuePlayer queue in a unidirectional approach, this is likely to work. We might need to be careful when syncing the playlist due to stored item mutations, ensuring additional items are inserted depending on the repeat mode. This also might work because we usually locate items by id, looking for a first match from the beginning of the queue. This would also guarantee a gapless playback experience.

@defagos
Copy link
Member Author

defagos commented Jun 3, 2024

SF Symbols provide several repeat icons that can be useful for UI integration.

@defagos defagos self-assigned this Aug 22, 2024
@defagos
Copy link
Member Author

defagos commented Aug 23, 2024

AVPlayerLooper is interesting but limited. Some facts:

  • It can only repeat one item at a time and can replay only a specific range.
  • When using AVPlayerViewController or VideoPlayer the seek bar is restricted to the repeated range. The seekable time ranges, though, remain the same, so there is no secret way of truncating the playlist we don't know about (it uses forwardPlaybackEndTime according to the documentation).
  • Not sure what AVPlayerLooper.ItemOrdering is useful for.
  • AVPlayerLooper is doing probably too much magic for its own good. I also attached the header documentation below since it contains more information about how actionAtItemEnd is changed by the looper, something we should avoid.

The specified AVPlayerItem will be used as a template to generate at least 3 AVPlayerItem replicas and the replicas will be inserted into specified AVQueuePlayer's play queue to accomplish the looping playback. The specified AVPlayerItem should have its asset's duration property loaded beforehand so looping setup work would not be blocked until the duration value is known. Otherwise, AVPlayerLooper's status property is AVPlayerLooperStatusUnknown until the duration property is loaded. The specified AVPlayerItem will not be used in the actual looping playback. Furthermore, AVPlayerItem replicas will be generated at initialization time so any changes made to the specified AVPlayerItem's property afterwards will not be reflected in the replicas used for looping playback. Specified CMTimeRange will limit each item loop iteration to playing within the specified time range. To play from beginning and the whole duration of the item, specify kCMTimeRangeInvalid for the range parameter. Time range will be accomplished by seeking to range start time and setting AVPlayerItem's forwardPlaybackEndTime property on the looping item replicas. Client should not modify AVQueuePlayer's play queue while AVPlayerLooper is performing the looping. AVPlayerLooper will insert the replica items in the specified AVQueuePlayer's play queue before or after existing equeued items according to the specified AVPlayerLooperItemOrdering. The looper will change the actionAtItemEnd to AVPlayerActionAtItemEndAdvance if required. AVQueuePlayer's play queue and actionAtItemEnd will be restored when -disableLooping method is called and then current looping item replicas completes playback or when AVPlayerLooper is destroyed. While AVPlayerLooper is being initialized, the specified AVQueuePlayer will be paused (rate of 0.0) if necessary and the original player rate will be restored after initialization completes. The client shall set the specified AVQueuePlayer's rate to 0 beforehand if additional set-up work needs to be performed after AVPlayerLooper initialization and before starting looping playback. An NSInvalidArgumentException will be raised if the player and template item are not specified or the template item has a 0 duration. An NSInvalidArgumentException will be raised if a valid time range has a duration of 0 or is not contained within time 0 and duration of the templateItem.

@defagos
Copy link
Member Author

defagos commented Aug 23, 2024

I guess no special work is required for comScore. Still we have to check the behavior of trackers in general, though it is likely no special work is actually required.

@defagos
Copy link
Member Author

defagos commented Aug 29, 2024

According to #951 we can reuse the same comScore session id after having ended but not left the current item. So for loops obtained by enabling "repeat one" behavior we can reuse the same session as well.

@waliid waliid linked a pull request Aug 29, 2024 that will close this issue
4 tasks
@defagos
Copy link
Member Author

defagos commented Aug 29, 2024

Previous / next APIs wrap around playlist ends when the repeat mode is set to .all, even if there is only a single item in the list. This is consistent with other apps like Spotify and Android ExoPlayer behavior as well. Applications can still decide to disable the button when a single item is loaded by testing the number of items in the queue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: ✅ Done
Development

Successfully merging a pull request may close this issue.

2 participants