Skip to content

Commit

Permalink
Add metadata to the system player (#735)
Browse files Browse the repository at this point in the history
Co-authored-by: Samuel Défago <[email protected]>
  • Loading branch information
waliid and defagos authored Jan 12, 2024
1 parent a7c2c65 commit a4280d6
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 104 deletions.
6 changes: 3 additions & 3 deletions Demo/Sources/ContentLists/ContentListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ private struct ContentCell: View {
#if os(tvOS)
MediaCardView(
title: topic.title,
image: SRGDataProvider.current!.url(for: topic.image, size: .large)
imageUrl: SRGDataProvider.current!.url(for: topic.image, size: .large)
)
#endif
}
Expand All @@ -91,7 +91,7 @@ private struct ContentCell: View {
size: .init(width: 570, height: 350),
title: constant(iOS: title, tvOS: media.show?.title),
subtitle: constant(iOS: MediaDescription.subtitle(for: media), tvOS: media.title),
image: SRGDataProvider.current!.url(for: media.image, size: .large),
imageUrl: SRGDataProvider.current!.url(for: media.image, size: .large),
type: MediaDescription.systemImage(for: media),
duration: MediaDescription.duration(for: media),
date: MediaDescription.date(for: media),
Expand All @@ -115,7 +115,7 @@ private struct ContentCell: View {
#if os(tvOS)
MediaCardView(
title: show.title,
image: SRGDataProvider.current!.url(for: show.image, size: .large)
imageUrl: SRGDataProvider.current!.url(for: show.image, size: .large)
)
#endif
}
Expand Down
2 changes: 1 addition & 1 deletion Demo/Sources/Examples/ExamplesView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ struct ExamplesView: View {
private func section(title: String, medias: [Media]) -> some View {
CustomSection(title) {
ForEach(medias, id: \.self) { media in
Cell(title: media.title, subtitle: media.description, image: media.image) {
Cell(title: media.title, subtitle: media.description, imageUrl: media.imageUrl) {
router.presented = .player(media: media)
}
}
Expand Down
4 changes: 2 additions & 2 deletions Demo/Sources/Examples/ExamplesViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ final class ExamplesViewModel: ObservableObject {
Media(
title: title(of: media),
description: "DRM-protected video",
image: SRGDataProvider.current!.url(for: media.show?.image, size: .large),
imageUrl: SRGDataProvider.current!.url(for: media.show?.image, size: .large),
type: .urn(media.urn),
isMonoscopic: media.isMonoscopic
)
Expand All @@ -136,7 +136,7 @@ final class ExamplesViewModel: ObservableObject {
Media(
title: media.title,
description: "Token-protected video",
image: SRGDataProvider.current!.url(for: media.image, size: .large),
imageUrl: SRGDataProvider.current!.url(for: media.image, size: .large),
type: .urn(media.urn),
isMonoscopic: media.isMonoscopic
)
Expand Down
57 changes: 39 additions & 18 deletions Demo/Sources/Model/Media.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
// License information is available from the LICENSE file.
//

import AVFoundation
import Combine
import CoreMedia
import Foundation
import PillarboxCoreBusiness
import PillarboxPlayer
import UIKit

struct Media: Hashable {
enum `Type`: Hashable {
Expand All @@ -22,21 +25,24 @@ struct Media: Hashable {

let title: String
let description: String?
let image: URL?
let imageUrl: URL?
let image: UIImage?
let type: `Type`
let isMonoscopic: Bool
let startTime: CMTime

init(
title: String,
description: String? = nil,
image: URL? = nil,
imageUrl: URL? = nil,
image: UIImage? = nil,
type: `Type`,
isMonoscopic: Bool = false,
startTime: CMTime = .zero
) {
self.title = title
self.description = description
self.imageUrl = imageUrl
self.image = image
self.type = type
self.isMonoscopic = isMonoscopic
Expand All @@ -47,7 +53,7 @@ struct Media: Hashable {
self.init(
title: template.title,
description: template.description,
image: template.image,
imageUrl: template.imageUrl,
type: template.type,
isMonoscopic: template.isMonoscopic,
startTime: startTime
Expand All @@ -57,23 +63,11 @@ struct Media: Hashable {
func playerItem() -> PlayerItem {
switch type {
case let .url(url):
return .simple(url: url, metadata: self, trackerAdapters: [
DemoTracker.adapter { media in
DemoTracker.Metadata(title: media.title)
}
]) { item in
return playerItem(for: url) { item in
item.seek(at(startTime))
}
case let .unbufferedUrl(url):
return .simple(
url: url,
metadata: self,
trackerAdapters: [
DemoTracker.adapter { media in
DemoTracker.Metadata(title: media.title)
}
]
) { item in
return playerItem(for: url) { item in
item.automaticallyPreservesTimeOffsetFromLive = true
item.preferredForwardBufferDuration = 1
item.seek(at(startTime))
Expand All @@ -92,6 +86,33 @@ struct Media: Hashable {

extension Media: AssetMetadata {
func nowPlayingMetadata() -> NowPlayingMetadata {
.init(title: title, subtitle: description)
.init(title: title, subtitle: description, image: image)
}

private func playerItem(for url: URL, configuration: @escaping (AVPlayerItem) -> Void = { _ in }) -> PlayerItem {
.init(
publisher: imagePublisher()
.map { image in
.simple(
url: url,
metadata: Media(title: title, description: description, image: image, type: type),
configuration: configuration
)
},
trackerAdapters: [
DemoTracker.adapter { media in
DemoTracker.Metadata(title: media.title)
}
]
)
}

private func imagePublisher() -> AnyPublisher<UIImage?, Never> {
guard let imageUrl else { return Just(nil).eraseToAnyPublisher() }
return URLSession.shared.dataTaskPublisher(for: imageUrl)
.map(\.data)
.map { UIImage(data: $0) }
.replaceError(with: nil)
.eraseToAnyPublisher()
}
}
Loading

0 comments on commit a4280d6

Please sign in to comment.