mirror of
https://github.com/yattee/yattee.git
synced 2024-11-09 15:58:20 +00:00
Merge pull request #789 from stonerl/fix-picture-in-picture
fix picture in picture
This commit is contained in:
commit
dfe7565138
@ -679,38 +679,24 @@ final class PlayerModel: ObservableObject {
|
||||
avPlayerBackend.startPictureInPictureOnPlay = false
|
||||
avPlayerBackend.startPictureInPictureOnSwitch = false
|
||||
|
||||
if activeBackend == .appleAVPlayer {
|
||||
guard activeBackend != .appleAVPlayer else {
|
||||
avPlayerBackend.tryStartingPictureInPicture()
|
||||
return
|
||||
}
|
||||
|
||||
// First, we need to create an array with supported formats.
|
||||
let formatOrderPiP: [QualityProfile.Format] = [.stream, .hls]
|
||||
avPlayerBackend.startPictureInPictureOnSwitch = true
|
||||
|
||||
guard let video = currentVideo else { return }
|
||||
guard let stream = avPlayerBackend.bestPlayable(availableStreams, maxResolution: .hd720p30, formatOrder: formatOrderPiP) else { return }
|
||||
|
||||
if avPlayerBackend.video == video {
|
||||
if activeBackend != .appleAVPlayer {
|
||||
avPlayerBackend.startPictureInPictureOnSwitch = true
|
||||
}
|
||||
changeActiveBackend(from: activeBackend, to: .appleAVPlayer)
|
||||
} else {
|
||||
avPlayerBackend.startPictureInPictureOnPlay = true
|
||||
playStream(stream, of: video, preservingTime: true, upgrading: true, withBackend: avPlayerBackend)
|
||||
}
|
||||
|
||||
var retryCount = 0
|
||||
_ = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { [weak self] timer in
|
||||
if let pipController = self?.pipController, pipController.isPictureInPictureActive, self?.avPlayerBackend.isPlaying == true {
|
||||
self?.exitFullScreen()
|
||||
self?.controls.objectWillChange.send()
|
||||
timer.invalidate()
|
||||
} else if retryCount < 3, self?.activeBackend == .appleAVPlayer, self?.avPlayerBackend.startPictureInPictureOnSwitch == false {
|
||||
// If PiP didn't start, try starting it again up to 3 times,
|
||||
self?.avPlayerBackend.startPictureInPictureOnSwitch = true
|
||||
self?.avPlayerBackend.tryStartingPictureInPicture()
|
||||
retryCount += 1
|
||||
saveTime {
|
||||
self.changeActiveBackend(from: .mpv, to: .appleAVPlayer)
|
||||
_ = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { [weak self] timer in
|
||||
if let pipController = self?.pipController, pipController.isPictureInPictureActive, self?.avPlayerBackend.isPlaying == true {
|
||||
self?.exitFullScreen()
|
||||
self?.controls.objectWillChange.send()
|
||||
timer.invalidate()
|
||||
} else if self?.activeBackend == .appleAVPlayer, self?.avPlayerBackend.startPictureInPictureOnSwitch == false {
|
||||
self?.avPlayerBackend.startPictureInPictureOnSwitch = true
|
||||
self?.avPlayerBackend.tryStartingPictureInPicture()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -740,19 +726,27 @@ final class PlayerModel: ObservableObject {
|
||||
show()
|
||||
#endif
|
||||
|
||||
if previousActiveBackend == .mpv {
|
||||
saveTime {
|
||||
self.changeActiveBackend(from: self.activeBackend, to: .mpv, isInClosePip: true)
|
||||
_ = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { [weak self] timer in
|
||||
if self?.activeBackend == .mpv, self?.mpvBackend.isPlaying == true {
|
||||
self?.backend.closePiP()
|
||||
self?.controls.resetTimer()
|
||||
timer.invalidate()
|
||||
}
|
||||
avPlayerBackend.closePiP()
|
||||
_ = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { [weak self] timer in
|
||||
if self?.activeBackend == .appleAVPlayer, self?.avPlayerBackend.isPlaying == true, self?.playingInPictureInPicture == false {
|
||||
timer.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
guard previousActiveBackend == .mpv else { return }
|
||||
|
||||
saveTime {
|
||||
self.changeActiveBackend(from: .appleAVPlayer, to: .mpv, isInClosePip: true)
|
||||
_ = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { [weak self] timer in
|
||||
if self?.activeBackend == .mpv, self?.mpvBackend.isPlaying == true {
|
||||
timer.invalidate()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
backend.closePiP()
|
||||
}
|
||||
|
||||
// We need to remove the itme from the player, if not it will be displayed when next video goe to PiP.
|
||||
Delay.by(1.0) {
|
||||
self.avPlayerBackend.closeItem()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1003,7 +997,10 @@ final class PlayerModel: ObservableObject {
|
||||
}
|
||||
|
||||
show()
|
||||
closePiP()
|
||||
// Needs to be delayed a bit, otherwise the PiP windows stays open
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
|
||||
self?.closePiP()
|
||||
}
|
||||
}
|
||||
|
||||
func handleEnterBackground() {
|
||||
|
@ -383,7 +383,7 @@ struct PlayerControls: View {
|
||||
}
|
||||
|
||||
private var pipButton: some View {
|
||||
button("PiP", systemImage: player.pipImage, action: player.togglePiPAction)
|
||||
button("PiP", systemImage: player.pipImage, active: player.playingInPictureInPicture, action: player.togglePiPAction)
|
||||
.disabled(!player.pipPossible)
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ struct VideoActions: View {
|
||||
case .fullScreen:
|
||||
actionButton("Fullscreen", systemImage: player.fullscreenImage, action: player.toggleFullScreenAction)
|
||||
case .pip:
|
||||
actionButton("PiP", systemImage: player.pipImage, action: player.togglePiPAction)
|
||||
actionButton("PiP", systemImage: player.pipImage, active: player.playingInPictureInPicture, action: player.togglePiPAction)
|
||||
#if os(iOS)
|
||||
case .lockOrientation:
|
||||
actionButton("Lock", systemImage: player.lockOrientationImage, active: player.lockedOrientation != nil, action: player.lockOrientationAction)
|
||||
|
Loading…
Reference in New Issue
Block a user