Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tiagomaial/piplayground
A simple iOS app exploring how Picture in Picture works
https://github.com/tiagomaial/piplayground
avfoundation avkit ios picture-in-picture pip swift swiftui
Last synced: 11 days ago
JSON representation
A simple iOS app exploring how Picture in Picture works
- Host: GitHub
- URL: https://github.com/tiagomaial/piplayground
- Owner: TiagoMaiaL
- License: mit
- Created: 2024-01-31T17:47:10.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2024-02-27T02:55:48.000Z (10 months ago)
- Last Synced: 2024-02-27T03:35:49.857Z (10 months ago)
- Topics: avfoundation, avkit, ios, picture-in-picture, pip, swift, swiftui
- Language: Swift
- Homepage:
- Size: 9.67 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# PiPlayground
A simple iOS app exploring how to implement Picture in Picture in a custom player.
## TODOS:
- [x] Add the project UI
- [x] Add video playback components
- [x] Add control for starting pip
- [x] Add support for pip restoration
- [x] Document how PiP works in this README file## Screenshot
## PiP: Pragmatic Information
### What it is
- Allows users to watch a video in a little floating window, controlled by iOS
- Users then are free to navigate in the app or OS itself (open different apps, for example)
- Users are able to restore playback, allowing them to return to the original playback context
- It's part of the `AVKit` framework
- `AVKit` contains UI facilities for visualization of media playback### How to make it work
- You'll be interfacing with the `AVPictureInPictureController` class (check `PictureInPicture.swift` in this project)
- Use an `AVPlayerLayer` to instantiate it:
```swift
AVPictureInPictureController(playerLayer: playerLayer)
```
- Initialization follows this order:
- Create an `AVPlayer` ready for playback
- Create an `AVPlayerLayer`, which will have AVPlayer as its player
- Create the `AVPictureInPictureController`
- You'll then need to check if pip is possible:
```swift
publisher(for: \.isPictureInPicturePossible)
.filter { $0 == false }
.receive(on: RunLoop.main)
.timeout(.seconds(1), scheduler: RunLoop.main)
.removeDuplicates()
.sink(receiveCompletion: { completion in
switch completion {
case .failure:
continuation.resume(returning: false)
default:
break
}
cancellable?.cancel()
}, receiveValue: { _ in
debugPrint("Pip is possible.")
continuation.resume(returning: true)
})
```
- Once pip is possible, use `startPictureInPicture()` and `stopPictureInPicture()` methods to control it
- Use delegation (`AVPictureInPictureControllerDelegate`) to receive its state:
```swift
func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
debugPrint("Pip is active.")
}
func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
debugPrint("Pip is inactive.")
}
func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, failedToStartPictureInPictureWithError error: Error) {
debugPrint("Pip error: \(error)")
}
```
- PiP provides a way for you to restore the app UI, so users can navigate back to the original playback context:
```swift
func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController) async -> Bool {
guard let playbackRestorer else { return false }
return await playbackRestorer.restore()
}
// Check:
// 1. PictureInPicture.swift (for pip encapsulation and restoration definitions)
// 2. MovieSession.swift (for playback and pip creation)
// 3. MoviesCatalogView.swift (for playback context restoration)
```
- Automatically start pip when application enters background:
```swift
pipController.canStartPictureInPictureAutomaticallyFromInline = true
```### Limitations
- Lack of controls customization. The only documented method for customizing some of the controls is when you set `requiresLinearPlayback`
- Other customization options are described in [this repository](https://github.com/CaiWanFeng/PiP) (although they are not documented by Apple)
- PiP doesn't work on iPhone simulators