## **Step 1:** Add and configure your Bitmovin Player
You have several options for integrating the Player SDK into your project.
We recommend you use the latest version of our Bitmovin Player. You can find all versions [here](🔗).
### Using CocoaPods
Add the following lines to the Podfile of your project and replace the `Version Number
` with the latest version of the SDK.
### Using Swift Package Manager
To integrate using Xcode 14.1 or newer, open your project file and specify it in **Project > Package Dependencies** using the following URL:
Note
You can also add the Player SDK to your project via different ways. Learn how to do that in our [Getting Started Guide](🔗).
### Configure the player license key
Add your player license key to the `<dict>
` in the `Info.plist
`:
Alternatively, you can also set the license key programmatically on the `PlayerConfig
` via `PlayerConfig.key
`.
### Allowlist your Bundle Identifiers
And finally, register the bundle identifier of your application in your [Bitmovin Dashboard](🔗) under **Player -> Licenses** and **Analytics -> Licenses**. This security mechanism protects your license from being used elsewhere.
## **Step 2:** Replace AVPlayer references in your project
### Replace AVPlayer API
The APIs of `AVPlayer
` and Bitmovin Player are similar in functionality. As a result, the migration is mostly about changing method names and signatures.
Here is an example of creating a new Bitmovin Player:
Next, replace occurrences of `AVPlayerItem
` by `SourceConfig
` and load your sources. Here is an example of loading an HLS stream:
### User Interface
#### SwiftUI
To migrate the UI used from SwiftUI, replace occurrences of `VideoPlayer
` with `VideoPlayerView
`.
Note
For full snippet for embedding `
VideoPlayerView
` into a SwiftUI view, see [here](🔗).
#### UIKit
To migrate the UI used from UIKit, replace occurrences of `AVPlayerViewController
` with `PlayerView
`.
An example:
Note
For full snippet for embedding `
PlayerView
` into a `UIViewController
`, see [here](🔗).
Learn how to customize your cross-platform Bitmovin UI [here](🔗).
Note
To support you with the further migration, we've created [mapping tables](🔗) between the `
AVPlayer
` and Bitmovin Player API, which you can refer to - especially for more advanced use cases.
And that's it!
You're ready to play a video in your application using the Bitmovin Player 😀
## **Summary**
In this guide, we demonstrated how easy it is to migrate from `AVPlayer
` to the Bitmovin Player including Analytics in just **two simple steps**: adding & configuring the Bitmovin Player and mapping the `AVPlayer
` API to the Bitmovin Player API.
Next, you can
check out our [Getting Started Guide](🔗).
download fully working [examples](🔗) and explore more features in our GitHub repository.
choose additional platforms to deploy on in our [Getting Started Hub](🔗) and try our no-code wizards.
browse our [Bitmovin Player API reference](🔗).
try our [Analytics](🔗) product to get real-time insights into your new iOS Player.
see if some of the questions you might have are answered in our [Community](🔗) and ask your own!
## **Appendix:** Mapping Tables
For more advanced use cases, we've created the following mapping tables to support your migration.
In comparison, the Bitmovin Player API allows more expressive and terse syntax by using event based communication whereas `AVPlayer
` makes heavy use of Key-Value Observing and Notifications.
### AVPlayer ➡️ Bitmovin Player mapping
AVPlayer | Bitmovin Player |
`AVPlayerItem(url:) ` | `SourceConfig(url:) ` |
`AVPlayer.replaceCurrentItem(with:) ` | `Player.load(sourceConfig:) ` |
`AVPlayer.replaceCurrentItem(with: nil) ` | `Player.unload() ` |
`AVPlayer.currentItem ` | `Player.source ` |
`AVPlayer.currentItem.tracks ` | `Player.availableAudio ` and `Player.availableSubtitles ` |
`AVPlayer.currentItem.duration ` | `Player.duration ` |
`AVPlayer.currentItem.error ` | `PlayerListener.onSourceError ` and `SourceListener.onSourceError ` |
`AVPlayer.currentItem.preferredForwardBufferDuration ` | `Player.buffer.setTargetLevel() ` |
`AVPlayer.currentItem.preferredPeakBitRate ` | `PlayerConfig.adaptationConfig.maxSelectableBitrate ` |
`AVPlayer.status ` | `PlayerListener.onReady ` |
`AVPlayer.error ` | `PlayerListener.onPlayerError ` |
`AVPlayer.timeControlStatus ` when `.playing ` | `PlayerListener.onPlaying ` |
`AVPlayer.timeControlStatus ` when `.paused ` | `PlayerListener.onPaused ` |
`AVPlayer.addPeriodicTimeObserver ` | `PlayerListener.onTimeChanged ` |
`AVQueuePlayer(items:) ` | `Player.load(playlistConfig:) ` |
`AVQueuePlayer.items() ` | `Player.playlist.sources ` |
`AVQueuePlayer.insert(_:, after:) ` | `Player.playlist.add(source: at:) ` |
`AVQueuePlayer.remove(_:) ` | `Player.playlist.remove(atIndex:) ` |
`AVQueuePlayer.removeAllItems() ` | `Player.unload() ` |
### Additional Notes
#### Seeking
[`AVPlayer.seek(to time: CMTime)
`](🔗) (seeking in the current source) is equivalent to:
[`
player.seek(time:)
`](🔗) for **non-live** streams[`
player.timeShift
`](🔗) for **live** streams
[`AVQueuePlayer.advanceToNextItem()
`](🔗) (seeking in any source of the playlist) is equivalent to:
[`
player.playlist.seek(source:, time:)
`](🔗) for **non-live** streamsLive streams are currently not supported in Playlists.
#### Events
The Bitmovin Player provides an extensive Event Framework. Listening to a `Player
` event is as simple as:
Compared to Key-Value Observing based solution with AVPlayer:
For more advanced use cases, take a look at our API documentation for the `PlayerListener
` [here](🔗).