Coder Social home page Coder Social logo

dsa28s / compose-video Goto Github PK

View Code? Open in Web Editor NEW
232.0 6.0 26.0 37.32 MB

Video UI Component for Jetpack Compose (Powered by androidx.media3)

Home Page: https://dsa28s.github.io/compose-video/

License: Apache License 2.0

Kotlin 100.00%
compose exoplayer jetpack player video

compose-video's Introduction

Hello!

πŸ€— I'm Dora Lee (@dsa28s), a 25 year old developer who wants to be as versatile as Doraemon!

πŸ‘¨β€πŸ’» I'm currently working at ModHaus as an

😘 There are so many things I want to do, so after work I usually work on my

  • side projects after work!
  • I enjoy drinking 🍻 beer, reading books, and catching up on YouTube.
  • I love to eat so much that I often go on restaurant hunts!

πŸ“š Currently, I'm studying

  • I'm learning Kotlin Native.
  • I'm trying to create my own interpreter language with rust.

πŸ‘‹ We talk together, we project together!

I love meeting new people, chatting with them, and working on projects together!

ν•œκ΅­μ–΄ 버전

Here is README_ko.md

compose-video's People

Contributors

anandjeyapal avatar dsa28s avatar iacobionut01 avatar itsallan avatar kangyee avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

compose-video's Issues

Having bottom paddings in fullScreenDilalog

When I open full screen it shows with bottom paddings:
(In my screen you can see some item and floating action button in full screen)

It's in default screen:

2024-02-09 11 12 38

And in full screen:

2024-02-09 11 12 35

Exit full screen UI offset

F7C32EFD26B7B5D1C6DE4CBC0BF430DA

When I exit from full screen state, the UI is offset and there is an empty space on the right side
ver: Android 9

kotlin multiplatform support

What if this library supports kotlin multiplatform?
I'am asking for your opinion on whether you are in favor of updating the library so that it can be used on Kotlin multiplatform.

OnMediaLoaded callback

I want to show loading spinner while the media is loading. For that I think I need a callback for media loaded.

Is it possible with the current api?

Dialog displays an error after attachBaseContext()

After override the context configuration to prevent font scaling and density scaling, the full screen dialog displays an error.

    override fun attachBaseContext(newBase: Context) {
        val resources = newBase.resources
        val overrideConfiguration = Configuration(resources.configuration)
            .apply {
                fontScale = 1.0f
                densityDpi = resources.displayMetrics.xdpi.toInt()
            }

        super.attachBaseContext(
            newBase.createConfigurationContext(overrideConfiguration)
        )
    }

Screenshot_20240304_185817

After set defaultPlayerView background to GRAY.

    DisposableEffect(
        AndroidView(
            modifier = modifier,
            factory = {
                defaultPlayerView.apply {
                    useController = usePlayerController
                    resizeMode = surfaceResizeMode.toPlayerViewResizeMode()
                    setBackgroundColor(Color.GRAY)
                }
            },
        ),
    ) {

Screenshot_20240304_190028

How to disable subtitles initially

I was able to do this outside this project, but don't see a way to do it inside.

With straight exoPlayer, I was able to set the track selector, but can't get to this inside the explayer instance in this project:

`val trackSelector = DefaultTrackSelector(LocalContext.current).apply {
setParameters(buildUponParameters().setTrackTypeDisabled
(
C.TRACK_TYPE_TEXT, true
)
.setRendererDisabled
(
C.TRACK_TYPE_TEXT, true
)

    )

}
val exoPlayer = remember {

    ExoPlayer.Builder(context
    )
        .setTrackSelector(trackSelector)`

Can someone assist please?

Set current seek position

I cannot seem to find a way to seek to a stored seek time/position when relaunching a video after playback and seek time is stored.

Can anyone assist?

Samsung a series video overflow

Hello,

i have a problem,
actually i tried samsung j8, s23 or xiaomi devices and video normal on these devices but i tried galaxy a series (a73 and a34) and this problem occurred,
the problem is i select a video and video overflow, when once i tap the screen and the video size returns to normal?

What can i do?

Question regarding lifecycle

Hi! Nice extension.

I was experimenting with it and found that when using m3u8 network playback stream, the handleLifecycle=true paused playback properly when leaving the app, but never resumed it when coming back, resulting in back screen.

Not sure if it is a bug or a problem on my end. Perhaps it makes sense to be able to optionally create the exoplayer instance outside the library, for having more control over the instance? I'd assume then I would be able to use it to control playback with some custom logic.

M3U8 video not playing

i don't know if am doing anything wrong but but m3u8 not playing let me attach my code
` var repeatMode by remember { mutableStateOf(RepeatMode.NONE) }
VideoPlayerCacheManager.initialize(context, 1024 * 1024 * 1024)
VideoPlayer(
mediaItems = listOf(
VideoPlayerMediaItem.NetworkMediaItem(
url = videoUrl,
mediaMetadata = MediaMetadata.Builder().setTitle(title).build(),
mimeType = MimeTypes.APPLICATION_M3U8,
)
),
handleLifecycle = true,
autoPlay = true,
usePlayerController = true,
enablePip = true,
handleAudioFocus = true,
controllerConfig = VideoPlayerControllerConfig(
showSpeedAndPitchOverlay = true,
showSubtitleButton = true,
showCurrentTimeAndTotalTime = true,
showBufferingProgress = true,
showForwardIncrementButton = true,
showBackwardIncrementButton = true,
showBackTrackButton = false,
showNextTrackButton = false,
showRepeatModeButton = true,
controllerShowTimeMilliSeconds = 5_000,
controllerAutoShow = true,
showFullScreenButton = true,
),
volume = 0.8f, // volume 0.0f to 1.0f
repeatMode = RepeatMode.NONE, // or RepeatMode.ALL, RepeatMode.ONE
onCurrentTimeChanged = { // long type, current player time (millisec)
Log.e("CurrentTime", it.toString())
},
playerInstance = {
android.util.Log.e("VOLUME", volume.toString())
addAnalyticsListener(object : AnalyticsListener {
@SuppressLint("UnsafeOptInUsageError")
override fun onRepeatModeChanged(
eventTime: AnalyticsListener.EventTime,
rMode: Int,
) {
repeatMode = rMode.toRepeatMode()

                            }

                            @SuppressLint("UnsafeOptInUsageError")
                            override fun onPlayWhenReadyChanged(
                                eventTime: AnalyticsListener.EventTime,
                                playWhenReady: Boolean,
                                reason: Int,
                            ) {

                            }

                            @SuppressLint("UnsafeOptInUsageError")
                            override fun onVolumeChanged(
                                eventTime: AnalyticsListener.EventTime,
                                volume: Float,
                            ) {

                            }
                        })
                    },`

photo_5978802000718054152_y

black overlay

is there any way to hide video player back overlay before loading media item? (im using network media item)

Setting DataSource.Factory

Hi,

I really, really, like this library. Much much easier to use than the 400+ line ExoPlayer "getting started" demo.

I needed to use the OkHttp DataSource (to enable playing videos that a user has downloaded offline via an OkHttp interceptor I made).

The current function signatures don't allow setting the DataSource.Factory. I made a fork with an option for the HttpDataSource here:

https://github.com/UstadMobile/compose-video

Add argument:

httpDataSourceFactory: HttpDataSource.Factory = remember {
        DefaultHttpDataSource.Factory()
    },

Use it:

.apply {
                val cache = VideoPlayerCacheManager.getCache()
                if (cache != null) {
                    val cacheDataSourceFactory = CacheDataSource.Factory()
                        .setCache(cache)
                        .setUpstreamDataSourceFactory(DefaultDataSource.Factory(context, httpDataSourceFactory))
                    setMediaSourceFactory(DefaultMediaSourceFactory(cacheDataSourceFactory))
                } else {
                    setMediaSourceFactory(DefaultMediaSourceFactory(httpDataSourceFactory))
                }
            }

It's now working with OkHttpDataSource. I'm not sure if that is the most elegant API. Maybe accepting the DataSource.Factory itself would be an option?

I'm happy to tidy submit this into a pull request if that helps.

Player background

The player background can be set via a modifier. At the moment it is set as a constant. My suggestion is to fix this.

Enter full screen reset player and track state

When screen rotates all jetpack compose components lose the remembers states.
Player is reset and in consequence video track is set on start by default.
Trying use:

  • android:configChanges="orientation|screenSize|layoutDirection" on manifest did not work
  • rememberSaveable only works with serializable objects

Preview is not shown.

Whenever we use @Preview on function which is calling this library, it is not working.
Below is the stacktrace. Is there any solution:?

java.lang.NoClassDefFoundError: android/media/MediaCryptoException
at androidx.media3.exoplayer.DefaultRenderersFactory.buildVideoRenderers(DefaultRenderersFactory.java:359)
at androidx.media3.exoplayer.DefaultRenderersFactory.createRenderers(DefaultRenderersFactory.java:295)
at androidx.media3.exoplayer.ExoPlayerImpl.(ExoPlayerImpl.java:259)
at androidx.media3.exoplayer.ExoPlayer$Builder.build(ExoPlayer.java:1186)
at io.sanghun.compose.video.VideoPlayerKt.VideoPlayer(VideoPlayer.kt:154)
at io.sanghun.compose.video.sample.ComposableSingletons$MainActivityKt$lambda-1$1.invoke(MainActivity.kt:74)
at io.sanghun.compose.video.sample.ComposableSingletons$MainActivityKt$lambda-1$1.invoke(MainActivity.kt:65)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.material3.SurfaceKt$Surface$1.invoke(Surface.kt:132)
at androidx.compose.material3.SurfaceKt$Surface$1.invoke(Surface.kt:114)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.material3.SurfaceKt.Surface-T9BRK9s(Surface.kt:111)
at io.sanghun.compose.video.sample.MainActivity.Home(MainActivity.kt:62)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at androidx.compose.ui.tooling.ComposableInvoker.invokeComposableMethod(ComposableInvoker.kt:163)
at androidx.compose.ui.tooling.ComposableInvoker.invokeComposable(ComposableInvoker.kt:208)
at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1$composable$1.invoke(ComposeViewAdapter.kt:509)
at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1$composable$1.invoke(ComposeViewAdapter.kt:507)
at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1.invoke(ComposeViewAdapter.kt:544)
at androidx.compose.ui.tooling.ComposeViewAdapter$init$3$1.invoke(ComposeViewAdapter.kt:502)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.ui.tooling.InspectableKt.Inspectable(Inspectable.kt:61)
at androidx.compose.ui.tooling.ComposeViewAdapter$WrapPreview$1.invoke(ComposeViewAdapter.kt:449)
at androidx.compose.ui.tooling.ComposeViewAdapter$WrapPreview$1.invoke(ComposeViewAdapter.kt:448)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.ui.tooling.ComposeViewAdapter.WrapPreview(ComposeViewAdapter.kt:443)
at androidx.compose.ui.tooling.ComposeViewAdapter.access$WrapPreview(ComposeViewAdapter.kt:127)
at androidx.compose.ui.tooling.ComposeViewAdapter$init$3.invoke(ComposeViewAdapter.kt:502)
at androidx.compose.ui.tooling.ComposeViewAdapter$init$3.invoke(ComposeViewAdapter.kt:499)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.ui.platform.ComposeView.Content(ComposeView.android.kt:428)
at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:252)
at androidx.compose.ui.platform.AbstractComposeView$ensureCompositionCreated$1.invoke(ComposeView.android.kt:251)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.ui.platform.CompositionLocalsKt.ProvideCommonCompositionLocals(CompositionLocals.kt:194)
at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:123)
at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt$ProvideAndroidCompositionLocals$3.invoke(AndroidCompositionLocals.android.kt:122)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.ui.platform.AndroidCompositionLocals_androidKt.ProvideAndroidCompositionLocals(AndroidCompositionLocals.android.kt:114)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$2.invoke(Wrapper.android.kt:156)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1$2.invoke(Wrapper.android.kt:155)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:155)
at androidx.compose.ui.platform.WrappedComposition$setContent$1$1.invoke(Wrapper.android.kt:140)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
at androidx.compose.runtime.ActualJvm_jvmKt.invokeComposable(ActualJvm.jvm.kt:78)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3373)
at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3363)
at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341)
at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source)
at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3363)
at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:3298)
at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:587)
at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:966)
at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:519)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:140)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:131)
at androidx.compose.ui.platform.AndroidComposeView.setOnViewTreeOwnersAvailable(AndroidComposeView.android.kt:1099)
at androidx.compose.ui.platform.WrappedComposition.setContent(Wrapper.android.kt:131)
at androidx.compose.ui.platform.WrappedComposition.onStateChanged(Wrapper.android.kt:181)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.kt:314)
at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.kt:192)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:138)
at androidx.compose.ui.platform.WrappedComposition$setContent$1.invoke(Wrapper.android.kt:131)
at androidx.compose.ui.platform.AndroidComposeView.onAttachedToWindow(AndroidComposeView.android.kt:1174)
at android.view.View.dispatchAttachedToWindow(View.java:21980)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3490)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3497)
at android.view.AttachInfo_Accessor.setAttachInfo(AttachInfo_Accessor.java:44)
at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:372)
at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:454)
at com.android.tools.idea.layoutlib.LayoutLibrary.createSession(LayoutLibrary.java:120)
at com.android.tools.rendering.RenderTask.createRenderSession(RenderTask.java:776)
at com.android.tools.rendering.RenderTask.lambda$inflate$6(RenderTask.java:924)
at com.android.tools.rendering.RenderExecutor$runAsyncActionWithTimeout$3.run(RenderExecutor.kt:203)
at com.android.tools.rendering.RenderExecutor$PriorityRunnable.run(RenderExecutor.kt:317)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.lang.ClassNotFoundException: android.media.MediaCryptoException
at com.android.tools.rendering.classloading.loaders.DelegatingClassLoader.findClass(DelegatingClassLoader.kt:76)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:592)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
at com.android.tools.rendering.classloading.loaders.DelegatingClassLoader.loadClass(DelegatingClassLoader.kt:62)
... 101 more

How to use player on lazycolumn?

Hello, I have a problem with using the player on the lazycolumn, but because each player control creates a player instance, the memory usage is very large, what should I do?

Play Multi Exoplayer

I want to know how to play multi-exoplayer like this picture
[explain]

  • one exoplayer is working well but the other one is stop
  • how to play at the same time each of them

hello

fun MultiPlayerScreen(){
  Column(){
    VideoScreen() // 1
    videoScreen() //2
  } 
}
-----------------------------------------------------------------------------------------------------------------------------------
const val MIME_TYPE_DASH = MimeTypes.APPLICATION_MPD
const val MIME_TYPE_HLS = MimeTypes.APPLICATION_M3U8
const val MIME_TYPE_VIDEO_MP4 = MimeTypes.VIDEO_MP4
@Composable
fun VideoScreen(
    onChangeView : () -> Unit,
    durationTime : Long = 8000L,
){
    val currentChangeView by rememberUpdatedState(newValue = onChangeView)
    var repeatMode by remember { mutableStateOf(RepeatMode.ALL) }

    val context = LocalContext.current

    LaunchedEffect(Unit){
        delay(durationTime)
        if(durationTime != 0L) currentChangeView()
    }
     VideoPlayer(
        mediaItems = listOf(
            VideoPlayerMediaItem.NetworkMediaItem(
                url = "https://html5demos.com/assets/dizzy.mp4",
                mediaMetadata = MediaMetadata.Builder().setTitle("Clear MP4: Dizzy").build(),
                mimeType = MIME_TYPE_VIDEO_MP4,
            )

        ),
        handleLifecycle = true,
        autoPlay = true,
        usePlayerController = true,
        enablePip = true,
        handleAudioFocus = true,
        controllerConfig = VideoPlayerControllerConfig.Default.copy(
            showSpeedAndPitchOverlay = false,
            showSubtitleButton = false,
            showCurrentTimeAndTotalTime = true,
            showBufferingProgress = false,
            showForwardIncrementButton = true,
            showBackwardIncrementButton = true,
            showBackTrackButton = true,
            showNextTrackButton = true,
            showRepeatModeButton = true,
            controllerShowTimeMilliSeconds = 5_000,
            controllerAutoShow = true,
            showFullScreenButton = false
        ),
        volume = 0.5f,  // volume 0.0f to 1.0f
        repeatMode = repeatMode,       // or RepeatMode.ALL, RepeatMode.ONE
        onCurrentTimeChanged = { // long type, current player time (millisec)
            Log.e("CurrentTime", it.toString())
        },
        playerInstance = { // ExoPlayer instance (Experimental)
            addAnalyticsListener(object : AnalyticsListener {
                @SuppressLint("UnsafeOptInUsageError")
                override fun onRepeatModeChanged(
                    eventTime: AnalyticsListener.EventTime,
                    rMode: Int,
                ) {
                    repeatMode = rMode.toRepeatMode()
                    Toast.makeText(
                        context,
                        "RepeatMode changed = ${rMode.toRepeatMode()}",
                        Toast.LENGTH_LONG,
                    )
                        .show()
                }

                @SuppressLint("UnsafeOptInUsageError")
                override fun onPlayWhenReadyChanged(
                    eventTime: AnalyticsListener.EventTime,
                    playWhenReady: Boolean,
                    reason: Int,
                ) {
                    Toast.makeText(
                        context,
                        "isPlaying = $playWhenReady",
                        Toast.LENGTH_LONG,
                    )
                        .show()
                }

                @SuppressLint("UnsafeOptInUsageError")
                override fun onVolumeChanged(
                    eventTime: AnalyticsListener.EventTime,
                    volume: Float,
                ) {
                    Toast.makeText(
                        context,
                        "Player volume changed = $volume",
                        Toast.LENGTH_LONG,
                    )
                        .show()
                }
                }
            )
        },
        modifier = Modifier
            .fillMaxSize()
//           .align(Alignment.Center),
    )
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.