Skip to content

Commit

Permalink
Document metadata integration (#882)
Browse files Browse the repository at this point in the history
  • Loading branch information
defagos authored May 15, 2024
1 parent 5a87ff8 commit e02de41
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ The main responsibility of a ``PlayerItem`` loaded into a ``Player`` is to deliv

To associate Control Center metadata with a player item:

1. Create a type which represents your asset metadata and have it conform to ``AssetMetadata``.
1. Create a type which represents your asset metadata and have it conform to ``AssetMetadata``. More information is available from the <doc:metadata> article.
2. Implement the ``AssetMetadata/playerMetadata`` method and return the ``PlayerMetadata`` which must be displayed in the Control Center when the item is currently being played.
3. Implement a custom ``PlayerItem`` with a metadata publisher retrieving all metadata required before delivering an asset. Alternatively, and provided you have all metadata and the URL to be played readily available, you can simply use one of the available ``PlayerItem`` construction helpers, supplying the asset metadata at creation time.

Expand Down
73 changes: 73 additions & 0 deletions Sources/Player/Player.docc/Articles/metadata.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Metadata

@Metadata {
@PageColor(purple)
}

Associate metadata with the content being played.

## Overview

A ``PlayerItem`` is responsible of delivering a playable ``Asset``, which can optionally be attached metadata describing the content being played.

Metadata serves two purposes:

- A ``Player`` automatically retrieves and publishes standard ``PlayerMetadata`` about its current item. This possibly includes a title, a subtitle, an artwork image or chapters, for example. To provide standard player metadata an asset metadata must conform to the ``AssetMetadata`` protocol.
- Metadata associated with an asset is provided as is to any ``TrackerAdapter`` associated with a ``PlayerItem``. This makes it possible to map metadata to the input expected from a concrete ``PlayerItemTracker`` implementation. For more information please refer to the <doc:tracking> article.

Standard metadata can be used by player user interfaces. It is also used to consistently update information displayed in the Control Center.

## Define player metadata

Suppose you retrieve metadata about content being played from some web service in the following format:

```swift
struct Media {
let name: String
let show: String?
let date: Date
let artworkUrl: URL
let streamUrl: URL
}
```

To be able to associate this metadata with an ``Asset`` it must conform to ``AssetMetadata``. This lets you define which standard ``PlayerMetadata`` must be extracted and published by the player once it plays this item, for example:

```swift
extension Media: AssetMetadata {
var playerMetadata: PlayerMetadata {
.init(title: show, subtitle: name, imageSource: .url(artworkUrl))
}
}
```

Images are provided as ``ImageSource``, either as a URL or as a `UIImage`.

> Note: To avoid wasting resources images are only loaded when actually needed.
### Chapters

If your metadata provides markers into the content, as well as metadata describing them, you should build a corresponding ``Chapter`` list and provide it to the ``PlayerMetadata`` via its ``PlayerMetadata/chapters`` parameter.

On iOS chapters can be displayed by custom user interfaces. This can serve display purposes or let you implement alternative ways of navigating the content. On tvOS chapters are automatically displayed in the standard playback user interface info panel.

### Time ranges

In addition your metadata might include information about remarkable time ranges within the content. Standard player metadata currently supports:

- Opening and closing credits, during which custom user interfaces might want to adjust their presentation (e.g. add a skip button).
- Blocked time ranges which should never be playable. A ``Player`` automatically skips blocked time ranges during playback and prevents seek attempts into them.

If this makes sense for your content you can build a corresponding ``TimeRange`` list and provide it to the ``PlayerMetadata`` via its ``PlayerMetadata/timeRanges`` parameter.

> Tip: On tvOS you might want to use `SystemVideoView/contextualActions(_:)` to associate contextual actions during opening or closing credits.
## Display metadata in a player user interface

``PlayerMetadata`` associated with the item currently being played is automatically made available by a ``Player`` through its ``Player/metadata`` published property.

On iOS you can use this metadata to display the title, subtitle and artwork associated with the content being played. You can also display associated chapters or adjust your user interface during time range traversal.

To display images you must use a ``LazyImage`` instantiated with an ``ImageSource``. This ensures that images are only retrieved when actually required.

> Tip: When using ``SystemVideoView``, either on iOS or tvOS, most metadata is automatically displayed.
2 changes: 1 addition & 1 deletion Sources/Player/Player.docc/Articles/playback/playback.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ The above examples use ``PlayerItem/simple(url:metadata:trackerAdapters:configur
You can create a player item that loads content in a custom way as follows:

1. Write a publisher which retrieves the URL to be played as well as any required metadata you might need. This publisher likely requires some external parameters to be provided, for example a content identifier.
2. Map the result of your publisher to an ``Asset``. If you want to provide asset metadata, most notably for <doc:control-center> integration or custom <doc:tracking>, just define a corresponding type and associate an instance with your asset.
2. Map the result of your publisher to an ``Asset``. If you want to provide asset metadata, most notably for <doc:control-center> integration or custom <doc:tracking>, you must define a corresponding type and associate an instance with your asset. Please refer to the <doc:metadata> article for more information.
3. Create a ``PlayerItem`` with the corresponding initializer taking a publisher as argument. Your item initializer signature should likely reflect the external parameters required by your publisher.

The resulting player item can then be played with ``Player`` instance, possibly mixed with content from other sources.
Expand Down
2 changes: 2 additions & 0 deletions Sources/Player/Player.docc/Articles/tracking/tracking.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ Once types associated with an item tracker have been defined, start implementing

Once you have a tracker you can attach it to any item. The only requirement is that ``AssetMetadata`` supplied as part of the ``Asset`` retrieval process is transformed into ``PlayerItemTracker/Metadata`` required by the tracker.

> Tip: More information about <doc:metadata> is available from the dedicated article.
This transformation requires the use of a dedicated adapter, simply created from your custom tracker type using the ``PlayerItemTracker/adapter(configuration:mapper:)`` method. The adapter is also where you can supply any configuration required by your tracker:

```swift
Expand Down
4 changes: 3 additions & 1 deletion Sources/Player/Player.docc/Extensions/player.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
- ``isExternalPlaybackActive``
- ``isMuted``
- ``mediaType``
- ``metadata``
- ``playbackState``
- ``presentationSize``
- ``propertiesPublisher``
Expand All @@ -84,7 +85,8 @@

- ``canSeek(to:)``
- ``seek(_:smooth:completion:)``
- ``seek(to:completion:)``
- ``seek(to:completion:)-9bknb``
- ``seek(to:completion:)-2ypz8``
- ``after(_:)``
- ``at(_:)``
- ``before(_:)``
Expand Down
2 changes: 2 additions & 0 deletions Sources/Player/Player.docc/PillarboxPlayer.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ The PillarboxPlayer framework fully integrates with SwiftUI, embracing its decla

### Metadata

- <doc:metadata>

- ``AssetMetadata``
- ``PlayerMetadata``

Expand Down

0 comments on commit e02de41

Please sign in to comment.