https://github.com/mohsenoid/Android-PiP
Android Picture-in-Picture feature helper library
https://github.com/mohsenoid/Android-PiP
Last synced: 3 months ago
JSON representation
Android Picture-in-Picture feature helper library
- Host: GitHub
- URL: https://github.com/mohsenoid/Android-PiP
- Owner: mohsenoid
- License: apache-2.0
- Created: 2023-12-14T09:49:20.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2023-12-31T09:39:27.000Z (over 1 year ago)
- Last Synced: 2024-08-01T19:55:54.738Z (11 months ago)
- Language: Kotlin
- Size: 22.9 MB
- Stars: 37
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
- awesome-list - mohsenoid/Android-PiP - Android Picture-in-Picture feature helper library (Kotlin)
README
# Android-PiP
[](https://search.maven.org/search?q=g:%22com.mohsenoid.pip%22%20AND%20a:%22pip-core%22)
Android Picture-in-Picture feature helper library
This repository holds an Android Library that helps with the use of Picture-in-Picture mode.
It also includes a sample app that shows how to use the library.
More to learn about Android PiP API:
https://youtu.be/bvCKd_XctNg## Setup
Add the dependencies to your project:
```groovy
// the core library
implementation("com.mohsenoid.pip:pip-core:1.0.0")
// the UI library including ViewGroups which are PiP aware
implementation("com.mohsenoid.pip:pip-ui:1.0.0")
```## Usage
First you need to initialize the library inside you application class:
```kotlin
class App : Application() {
override fun onCreate() {
super.onCreate()
Pip.init(this)
}
}
```## PipSupportAppCompatActivity
By extending the `PipSupportAppCompatActivity` you can easily use the Picture-in-Picture mode.
```kotlin
class PlayerActivity : PipSupportAppCompatActivity() {
// ...
}
```Make sure that your PlayerActivity is setup correctly for PiP mode:
```xml
```You can inform the PiP library about your player status changes so that it can update the PiP auto
enter accordingly:```kotlin
private fun setupPlayer() {
// ...
val exoPlayer = ExoPlayer.Builder(this).build().apply {
// ...
addListener(
object : Player.Listener {
override fun onIsPlayingChanged(isPlaying: Boolean) {
super.onIsPlayingChanged(isPlaying)
updatePlayerState(isPlaying)
}
},
)
}
// ...
}
```You can set the Player rectangle so that the PiP library can use it for a smooth animation when
entering/exiting PiP mode:```kotlin
val rect = Rect()
binding.player.getGlobalVisibleRect(rect)
updatePipRect(rect)
```You can pass actions to the PiP library so that it can show them in the PiP window:
```kotlin
updatePipActions(listOfNotNull(getPipAction()))
``````kotlin
private fun getPipAction(): RemoteAction? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val actionUri = Uri.parse("https://youtube.com/AndroidDeveloperTips")
val actionIntent = Intent(Intent.ACTION_VIEW, actionUri)
val actionPendingIntent =
PendingIntent.getActivity(this, 0, actionIntent, PendingIntent.FLAG_IMMUTABLE)
val remoteAction = RemoteAction(
Icon.createWithResource(this, R.drawable.ic_picture_in_picture_action),
"More info",
"More info action",
actionPendingIntent,
)
remoteAction
} else {
null
}
}
```## PipController
By getting this controller interface you can control the PiP mode:
```kotlin
private val pipController = Pip.mgetPipController()
```Use it to enter PiP mode if allowed:
```kotlin
pipCommander.enterPip(
{ alreadyInPipMode ->
// switching to PiP was successful
},
{ pipEnterError ->
// switching to PiP was not successful
},
)
```Or to exit PiP mode:
```kotlin
pipCommander.closePip()
```You may also pass a content ID to the `updatePlayerState` method and use that to close the correct
PiP window:```kotlin
updatePlayerState(isPlaying, contentId)// ...
pipCommander.closePip(contentId)
```## PipObservable
By getting this observable interface you can observe the PiP mode change:
```kotlin
private val pipObservable = Pip.getPipObservable()
```You can check if the PiP mode is allowed based on player state and device for instance to enabling/disabling PiP mode button:
```kotlin
lifecycleScope.launch {
pipObservable.isPipAllowedStateFlow.collectLatest {
repeatOnLifecycle(Lifecycle.State.STARTED) {
binding.button.isVisible = it
}
}
}
```Or indicate of the player is in PiP mode or not:
```kotlin
lifecycleScope.launch {
pipObservable.isInPipModeStateFlow.collectLatest { isInPipMode ->
binding.player.useController = !isInPipMode
}
}
```Or check if a content is being played in PiP mode:
```kotlin
val result = isInPipMode(contentId)
```## Pip aware ViewGroups
By adding the pip-ui library to your project you can use the `PipAwareFrameLayout` and `PipAwareConstraintLayout` in your layout files and show/hide views which should not be visible in the PiP mode:
```xml
```Just make sure to init the views once the layout is inflated:
```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
// inflate the layout
// ...
binding.titleContainer.init()
}
```## License
Copyright 2023 Mohsen Mirhoseini
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.