Skip to content

Commit

Permalink
Enable advanced Picture in Picture and Control Center integration for…
Browse files Browse the repository at this point in the history
… the chapter-supporting player (#836)
  • Loading branch information
defagos authored Apr 21, 2024
1 parent 657beed commit 5f4e94b
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 39 deletions.
100 changes: 62 additions & 38 deletions Demo/Sources/Players/ChaptersPlayerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import CoreMedia
import PillarboxPlayer
import SwiftUI

private struct ChapterView: View {
private struct ChapterCell: View {
private static let width: CGFloat = 200

private static let durationFormatter: DateComponentsFormatter = {
Expand All @@ -33,7 +33,7 @@ private struct ChapterView: View {
.frame(width: Self.width, height: Self.width * 9 / 16)
.clipShape(RoundedRectangle(cornerRadius: 5))
.saturation(isHighlighted ? 1 : 0)
.scaleEffect17(isHighlighted ? 1.05 : 1)
.scaleEffect17(isHighlighted ? 1.07 : 1)
.animation(.defaultLinear, value: isHighlighted)
}

Expand Down Expand Up @@ -88,14 +88,13 @@ private struct ChapterView: View {
}
}

struct ChaptersPlayerView: View {
private let player = Player()
@State private var layout: PlaybackView.Layout = .minimized
@State private var chapters: [Chapter] = []
private struct ChaptersList: View {
@ObservedObject var player: Player

@StateObject private var progressTracker = ProgressTracker(interval: .init(value: 1, timescale: 1))

private var effectiveLayout: Binding<PlaybackView.Layout> {
!chapters.isEmpty ? $layout : .constant(.inline)
private var chapters: [Chapter] {
player.metadata.chapters
}

private var currentChapter: Chapter? {
Expand All @@ -105,47 +104,72 @@ struct ChaptersPlayerView: View {
}
}

let media: Media
var body: some View {
ScrollView(.horizontal) {
chaptersList()
}
.scrollIndicators(.hidden)
.scrollClipDisabled17()
.bind(progressTracker, to: player)
._debugBodyCounter(color: .purple)
}

@ViewBuilder
private func chaptersList() -> some View {
HStack(spacing: 15) {
ForEach(chapters, id: \.timeRange) { chapter in
Button {
player.seek(to: chapter)
} label: {
ChapterCell(chapter: chapter, isHighlighted: chapter == currentChapter)
}
.buttonStyle(PlainButtonStyle())
}
}
.padding(.horizontal)
}
}

private struct MainView: View {
@ObservedObject var player: Player
@State private var layout: PlaybackView.Layout = .minimized

private var chapters: [Chapter] {
player.metadata.chapters
}

private var currentLayout: Binding<PlaybackView.Layout> {
!chapters.isEmpty ? $layout : .constant(.inline)
}

var body: some View {
VStack {
PlaybackView(player: player, layout: effectiveLayout)
PlaybackView(player: player, layout: currentLayout)
.supportsPictureInPicture()
if layout != .maximized {
chaptersView()
if layout != .maximized, !chapters.isEmpty {
ChaptersList(player: player)
}
}
.animation(.defaultLinear, values: layout, chapters)
.background(.black)
.bind(progressTracker, to: player)
.onReceive(player.$metadata, assign: \.chapters, to: $chapters)
.onAppear(perform: play)
}
}

private func play() {
player.append(media.playerItem())
player.play()
struct ChaptersPlayerView: View {
@StateObject private var model = PlayerViewModel.persisted ?? PlayerViewModel()

let media: Media

var body: some View {
MainView(player: model.player)
.enabledForInAppPictureInPicture(persisting: model)
.background(.black)
.onAppear(perform: play)
.tracked(name: "chapters-player")
}

@ViewBuilder
private func chaptersView() -> some View {
if !chapters.isEmpty {
ScrollView(.horizontal) {
HStack(spacing: 15) {
ForEach(chapters, id: \.timeRange) { chapter in
Button {
player.seek(to: chapter)
} label: {
ChapterView(chapter: chapter, isHighlighted: chapter == currentChapter)
}
.buttonStyle(PlainButtonStyle())
}
}
.padding(.horizontal)
}
.scrollIndicators(.hidden)
.scrollClipDisabled17()
}
private func play() {
model.media = media
model.play()
}
}

Expand Down
2 changes: 1 addition & 1 deletion Demo/Sources/Router/Router.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ final class Router: ObservableObject {
extension Router: PictureInPictureDelegate {
func pictureInPictureWillStart() {
switch presented {
case .player, .systemPlayer, .playlist, .multi:
case .player, .systemPlayer, .chaptersPlayer, .playlist, .multi:
previousPresented = presented
presented = nil
case .inlineSystemPlayer:
Expand Down

0 comments on commit 5f4e94b

Please sign in to comment.