Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI for customizing playback params #63

Merged
merged 7 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,17 @@
android:exported="false"
tools:ignore="LockedOrientationActivity" />
<activity
android:name=".examples.BasicPlayerActivity"
android:exported="false"
android:label="Basic Foreground Player" />
android:name=".examples.BasicPlayerActivity"
android:exported="false"
android:label="Basic Foreground Player" />
<activity
android:name=".examples.MaxResActivity"
android:name=".examples.ConfigurablePlayerActivity"
android:exported="false"
android:label="Max-Res Modifier" />
android:label="Basic Foreground Player" />
<activity
android:name=".examples.SmartCacheActivity"
android:exported="false"
android:label="Smart Caching Example" />
<activity
android:name=".examples.DrmPlaybackActivity"
android:exported="false"
android:label="DRM Playback Example"
android:theme="@style/Theme.MuxVideoMedia3.NoActionBar" />
<activity
android:name=".MainActivity"
android:exported="true"
Expand Down
19 changes: 7 additions & 12 deletions app/src/main/java/com/mux/player/media3/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.mux.player.media3.databinding.ActivityMainBinding
import com.mux.player.media3.databinding.ListitemExampleBinding
import com.mux.player.media3.examples.BasicPlayerActivity
import com.mux.player.media3.examples.DrmPlaybackActivity
import com.mux.player.media3.examples.MaxResActivity
import com.mux.player.media3.examples.ConfigurablePlayerActivity
import com.mux.player.media3.examples.SmartCacheActivity
import com.mux.player.media3.examples.carousel.PlayerCarouselActivity

Expand Down Expand Up @@ -42,31 +41,27 @@ class MainActivity : AppCompatActivity() {

private fun examples() = listOf(
Example(
title = "Basic Foreground Player",
title = "Basic Player Screen",
destination = Intent(this@MainActivity, BasicPlayerActivity::class.java)
),
Example(
title = "Fullscreen Carousel (like reels)",
destination = Intent(this@MainActivity, PlayerCarouselActivity::class.java),
title = "Configurable Player Screen",
destination = Intent(this@MainActivity, ConfigurablePlayerActivity::class.java)
),
Example(
title = "Max-Resolution Modifier",
destination = Intent(this@MainActivity, MaxResActivity::class.java)
title = "Fullscreen Carousel",
destination = Intent(this@MainActivity, PlayerCarouselActivity::class.java),
),
Example(
title = "Smart Caching",
destination = Intent(this@MainActivity, SmartCacheActivity::class.java)
),
Example(
title = "DRM Playback",
destination = Intent(this@MainActivity, DrmPlaybackActivity::class.java)
)
)
}

data class Example(
val title: String,
val destination: Intent
val destination: Intent,
)

class ExampleListAdapter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@ import com.mux.stats.sdk.core.model.CustomerViewData
import com.mux.stats.sdk.core.util.UUID
import com.mux.player.MuxPlayer
import com.mux.player.media.MediaItems
import com.mux.player.media.PlaybackResolution
import com.mux.player.media3.PlaybackIds
import com.mux.player.media3.databinding.ActivityBasicPlayerBinding

/**
* A simple example that uses the normal media3 player UI to play a video in the foreground from
* Mux Video, using a Playback ID
* A minimal example of using Mux Player without any extra functionality
*/
class BasicPlayerActivity : AppCompatActivity() {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package com.mux.player.media3.examples

import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.annotation.OptIn
import androidx.appcompat.app.AppCompatActivity
import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import com.mux.stats.sdk.core.model.CustomData
import com.mux.stats.sdk.core.model.CustomerData
import com.mux.stats.sdk.core.model.CustomerVideoData
import com.mux.stats.sdk.core.model.CustomerViewData
import com.mux.stats.sdk.core.util.UUID
import com.mux.player.MuxPlayer
import com.mux.player.media3.R
import com.mux.player.media3.databinding.ActivityConfigurablePlayerBinding

/**
* A configurable example that uses the normal media3 player UI to play a video in the foreground from
* Mux Video, using a Playback ID
*
* You can configure the Activity via the UI
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.. and soon a URL

*/
class ConfigurablePlayerActivity : AppCompatActivity() {

private lateinit var binding: ActivityConfigurablePlayerBinding
private val playerView get() = binding.player

private val playbackParamsHelper = PlaybackParamsHelper()

private var player: MuxPlayer? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityConfigurablePlayerBinding.inflate(layoutInflater)
setContentView(binding.root)

if (savedInstanceState != null) {
playbackParamsHelper.restoreInstanceState(savedInstanceState)
}

binding.configurablePlayerPlaybackIdIn.hint = playbackParamsHelper.playbackIdOrDefault()

binding.configurablePlayerUpdateMediaItem.setOnClickListener {
playbackParamsHelper.playbackId = binding.configurablePlayerPlaybackIdIn.text?.trim()?.toString()
playbackParamsHelper.playbackToken =
binding.configurablePlayerPlaybackTokenIn.text?.trim()?.toString()
playbackParamsHelper.drmToken = binding.configurablePlayerDrmTokenIn.text?.trim()?.toString()
playbackParamsHelper.customDomain = binding.configurablePlayerDomainIn.text?.trim()?.toString()

maybePlayMediaItem(playbackParamsHelper.createMediaItem())
}
binding.configurablePlaybackIdClear.setOnClickListener {
binding.configurablePlayerPlaybackIdIn.text = null
playbackParamsHelper.playbackId = null
}
binding.configurablePlayerDrmTokenClear.setOnClickListener {
binding.configurablePlayerDrmTokenIn.text = null
playbackParamsHelper.drmToken = null
}
binding.configurablePlayerPlaybackTokenClear.setOnClickListener {
binding.configurablePlayerPlaybackTokenIn.text = null
playbackParamsHelper.playbackToken = null
}
binding.configurablePlayerDomainClear.setOnClickListener {
binding.configurablePlayerDomainIn.text = null
playbackParamsHelper.customDomain = null
}
}

override fun onStart() {
super.onStart()

val mediaItem = playbackParamsHelper.createMediaItem()

maybePlayMediaItem(mediaItem)
}

override fun onStop() {
tearDownPlayer()

super.onStop()
}

override fun onSaveInstanceState(outState: Bundle) {
playbackParamsHelper.saveInstanceState(outState)

super.onSaveInstanceState(outState)
}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.basic_player_menu, menu)
return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
val helperHandled = playbackParamsHelper.handleMenuClick(item)
if (helperHandled) {
val newMediaItem = playbackParamsHelper.createMediaItem()
maybePlayMediaItem(newMediaItem)
return true
} else {
return super.onOptionsItemSelected(item)
}
}

private fun maybePlayMediaItem(mediaItem: MediaItem) {
val item = mediaItem.buildUpon().setMediaMetadata(createMediaMetadata()).build()
if (item != player?.currentMediaItem) {
playSomething(item)
}
}

private fun createMediaMetadata(): MediaMetadata {
return MediaMetadata.Builder()
.setTitle("Mux Player Example")
.build()
}

private fun tearDownPlayer() {
playerView.player = null
player?.release()
}

private fun playSomething(mediaItem: MediaItem) {
val player = createPlayer(this)
player.setMediaItem(mediaItem)
player.prepare()
player.playWhenReady = true

this.playerView.player = player
this.player = player
}

@OptIn(UnstableApi::class)
private fun createPlayer(context: Context): MuxPlayer {
val out: MuxPlayer = MuxPlayer.Builder(context)
.addMonitoringData(
CustomerData().apply {
customerViewData = CustomerViewData().apply {
viewSessionId = UUID.generateUUID()
}
customerVideoData = CustomerVideoData().apply {
videoSeries = "My Series"
videoId = "abc1234zyxw"
}
customData = CustomData().apply {
customData1 = "my custom metadata field"
customData2 = "another custom metadata field"
customData10 = "up to 10 custom fields"
}
}
)
.applyExoConfig {
// Call ExoPlayer.Builder methods here
setHandleAudioBecomingNoisy(true)
setSeekBackIncrementMs(10_000)
setSeekForwardIncrementMs(30_000)
}
.build()

out.addListener(object : Player.Listener {
override fun onPlayerError(error: PlaybackException) {
// todo - better error info than this, inline in ui
Log.e(TAG, "player error!", error)
Toast.makeText(
this@ConfigurablePlayerActivity,
"Playback error! ${error.localizedMessage}",
Toast.LENGTH_LONG
).show()
}
})

return out
}

companion object {
val TAG = ConfigurablePlayerActivity::class.simpleName
}
}

This file was deleted.

Loading