Skip to content

Commit

Permalink
Update player version to 3.92.0 and add sample for media session
Browse files Browse the repository at this point in the history
  • Loading branch information
strangesource committed Nov 11, 2024
1 parent 64de605 commit ef65e39
Show file tree
Hide file tree
Showing 28 changed files with 614 additions and 106 deletions.
1 change: 1 addition & 0 deletions MediaSessionKotlin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
44 changes: 44 additions & 0 deletions MediaSessionKotlin/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}

android {
namespace 'com.bitmovin.player.samples.media.session'
compileSdk rootProject.compileSdk

defaultConfig {
applicationId "com.bitmovin.player.samples.media.session"
minSdkVersion rootProject.minSdkVersion
targetSdkVersion rootProject.targetSdkVersion
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
buildFeatures {
viewBinding = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = '11'
}
}

dependencies {
implementation supportDependencies.appCompat
implementation bitmovinPlayerDependencies.bitmovinPlayer
implementation "com.bitmovin.player:player-media-session:${bitmovinPlayerVersion}"
implementation 'androidx.activity:activity:1.9.3'
implementation 'com.google.android.material:material:1.12.0'
}
21 changes: 21 additions & 0 deletions MediaSessionKotlin/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
38 changes: 38 additions & 0 deletions MediaSessionKotlin/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<service
android:name=".MediaSessionPlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
</intent-filter>
</service>

<meta-data
android:name="BITMOVIN_PLAYER_LICENSE_KEY"
android:value="{PLAYER_LICENSE_KEY}" />
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package com.bitmovin.player.samples.media.session

import android.Manifest
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.view.ViewGroup
import android.widget.RelativeLayout
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.bitmovin.player.PlayerView
import com.bitmovin.player.api.Player
import com.bitmovin.player.api.source.SourceConfig
import com.bitmovin.player.api.source.SourceType
import com.bitmovin.player.samples.media.session.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
private lateinit var playerView: PlayerView
private var serviceBinder: MediaSessionPlaybackService.ServiceBinder? = null
private val player: Player? get() = serviceBinder?.player
private var isBound = false
private lateinit var uiBinding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
uiBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(uiBinding.root)
// Create a PlayerView without a Player and add it to the View hierarchy
playerView = PlayerView(this, null as Player?).apply {
layoutParams = RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
}
playerView.keepScreenOn = true
uiBinding.root.addView(playerView)
}

private fun initializePlayer() {
// Load a new source
val sourceConfig = SourceConfig(
"https://bitmovin-a.akamaihd.net/content/MI201109210084_1/mpds/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.mpd",
SourceType.Dash,
posterSource = "https://bitmovin-a.akamaihd.net/content/poster/hd/RedBull.jpg"
)

player?.load(sourceConfig)
}


private fun bindService() {
val intent = Intent(this, MediaSessionPlaybackService::class.java)
intent.setAction(Intent.ACTION_MEDIA_BUTTON)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
startService(intent)
}

private fun unbindService() {
unbindService(connection)
}

override fun onStart() {
super.onStart()
playerView.onStart()
bindService()
}

override fun onResume() {
super.onResume()

// Attach the Player to allow the PlayerView to control the player
playerView.player = player
playerView.onResume()
}

override fun onPause() {
// Detach the Player to decouple it from the PlayerView lifecycle
playerView.player = null
playerView.onPause()
super.onPause()
}

override fun onStop() {
super.onStop()
// Unbind the Service and reset the Player reference
unbindService()
playerView.onStop()
}

override fun onDestroy() {
playerView.onDestroy()
super.onDestroy()
}

private val connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
// We've bound to the Service, cast the IBinder and get the Player instance
val binder = service as MediaSessionPlaybackService.ServiceBinder
serviceBinder = binder
val player = binder.player ?: throw IllegalStateException("Player is null")
playerView.player = player
if (player.source == null) {
initializePlayer()
}
}

override fun onServiceDisconnected(name: ComponentName) {
isBound = false
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.bitmovin.player.samples.media.session

import android.content.Intent
import android.os.Binder
import android.os.IBinder
import com.bitmovin.player.api.PlaybackConfig
import com.bitmovin.player.api.Player
import com.bitmovin.player.api.PlayerConfig
import com.bitmovin.player.api.media.session.ControllerInfo
import com.bitmovin.player.api.media.session.MediaSession
import com.bitmovin.player.api.media.session.MediaSessionService

class MediaSessionPlaybackService : MediaSessionService() {
inner class ServiceBinder : Binder() {
val player get() = this@MediaSessionPlaybackService.player
fun connectSession() = addSession(mediaSession)
fun disconnectSession() = removeSession(mediaSession)
}

private val binder = ServiceBinder()
private lateinit var player: Player
private lateinit var mediaSession: MediaSession

override fun onGetSession(controllerInfo: ControllerInfo) = mediaSession

override fun onCreate() {
super.onCreate()
player = Player(
this, PlayerConfig(
playbackConfig = PlaybackConfig(
handleAudioFocus = true
)
)
)
mediaSession = MediaSession(
this,
mainLooper,
player,
)
}

override fun onDestroy() {
mediaSession.release()
player.destroy()

super.onDestroy()
}

override fun onBind(intent: Intent?): IBinder {
super.onBind(intent)
return binder
}
}
Loading

0 comments on commit ef65e39

Please sign in to comment.