Add autoplay feature and playback end handling (#214)

- Introduced a new setting for "Autoplay Next" in the player settings.
- Implemented autoplay functionality in the CustomMediaPlayerViewController to automatically start the next episode when playback ends.
- Added notification observers for handling playback completion and managing the autoplay behavior.

Co-authored-by: cranci <100066266+cranci1@users.noreply.github.com>
This commit is contained in:
realdoomsboygaming 2025-07-01 11:08:14 -05:00 committed by GitHub
parent 95d6d1ac14
commit d707858ad7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 36 additions and 0 deletions

View file

@ -77,6 +77,13 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
}
return UserDefaults.standard.bool(forKey: "pipButtonVisible")
}
private var isAutoplayEnabled: Bool {
if UserDefaults.standard.object(forKey: "autoplayNext") == nil {
return true
}
return UserDefaults.standard.bool(forKey: "autoplayNext")
}
private var pipController: AVPictureInPictureController?
private var pipButton: UIButton!
@ -402,6 +409,13 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
twoFingerTapGesture.numberOfTouchesRequired = 2
twoFingerTapGesture.delegate = self
view.addGestureRecognizer(twoFingerTapGesture)
NotificationCenter.default.addObserver(
self,
selector: #selector(handlePlaybackEnded),
name: .AVPlayerItemDidPlayToEndTime,
object: player.currentItem
)
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
@ -466,6 +480,7 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
timeUpdateTimer.invalidate()
}
NotificationCenter.default.removeObserver(self, name: .AVPlayerItemDidPlayToEndTime, object: nil)
NotificationCenter.default.removeObserver(self)
UIDevice.current.isBatteryMonitoringEnabled = false
@ -2997,6 +3012,19 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
batteryLabel?.text = "N/A"
}
}
@objc private func handlePlaybackEnded() {
guard isAutoplayEnabled else { return }
Logger.shared.log("Playback ended, autoplay enabled - starting next episode", type: "Debug")
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in
self?.player.pause()
self?.dismiss(animated: true) { [weak self] in
self?.onWatchNext()
}
}
}
}
class GradientOverlayButton: UIButton {

View file

@ -205,6 +205,7 @@ struct SettingsViewPlayer: View {
@AppStorage("doubleTapSeekEnabled") private var doubleTapSeekEnabled: Bool = false
@AppStorage("skipIntroOutroVisible") private var skipIntroOutroVisible: Bool = true
@AppStorage("pipButtonVisible") private var pipButtonVisible: Bool = true
@AppStorage("autoplayNext") private var autoplayNext: Bool = true
@AppStorage("videoQualityWiFi") private var wifiQuality: String = VideoQualityPreference.defaultWiFiPreference.rawValue
@AppStorage("videoQualityCellular") private var cellularQuality: String = VideoQualityPreference.defaultCellularPreference.rawValue
@ -247,6 +248,13 @@ struct SettingsViewPlayer: View {
showDivider: true
)
SettingsToggleRow(
icon: "play.circle.fill",
title: NSLocalizedString("Autoplay Next", comment: ""),
isOn: $autoplayNext,
showDivider: true
)
SettingsPickerRow(
icon: "timer",
title: NSLocalizedString("Completion Percentage", comment: ""),