Skip to content

Commit

Permalink
Merge pull request #4 from LouisDuboscq/multiple-players
Browse files Browse the repository at this point in the history
Multiple players support
  • Loading branch information
LouisDuboscq committed Feb 11, 2023
2 parents 15679fa + 1b3c37c commit fc49279
Show file tree
Hide file tree
Showing 9 changed files with 412 additions and 161 deletions.
1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,93 +1 @@
package com.lduboscq.jukeboxe.examples

import android.net.Uri
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material.Button
import androidx.compose.material.Icon
import androidx.compose.material.LinearProgressIndicator
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Close
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.lduboscq.jukebox.Jukebox
import com.lduboscq.jukebox.JukeboxViewModel
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch

/**
* Jukebox component with play and pause buttons
*/
@Composable
fun JukeboxSample(uri: Uri, setNextUri: () -> Unit) {
val commands: Channel<JukeboxViewModel.Commands> = Channel()
val commandsScope = rememberCoroutineScope()

Column(
Modifier
.fillMaxSize()
.wrapContentSize(Alignment.Center),
verticalArrangement = Arrangement.Center
) {
Jukebox(
uri = uri,
playWhenReady = true,
commands = commands.receiveAsFlow(), // user clicks for play and pause
onAudioListened = setNextUri, // in this sample, onAudioListened is just change uri to next mp3
modifier = Modifier.padding(horizontal = 32.dp),
errorView = {
Column(
Modifier
.fillMaxWidth()
.wrapContentWidth(Alignment.CenterHorizontally),
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painterResource(id = R.drawable.error_404),
modifier = Modifier.height(200.dp),
contentDescription = "error"
)
Text("Your audio was not found")
}
},
)
Spacer(Modifier.height(16.dp))
Row(
Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
) {
Button(onClick = {
commandsScope.launch {
commands.send(JukeboxViewModel.Commands.Play)
}
}) {
Text("play")
}
Spacer(Modifier.width(16.dp))
Button(onClick = {
commandsScope.launch {
commands.send(JukeboxViewModel.Commands.Pause)
}
}) {
Text("pause")
}
}
}
}
111 changes: 111 additions & 0 deletions examples/src/main/java/com/lduboscq/jukeboxe/examples/ListExample.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package com.lduboscq.jukeboxe.examples

import android.net.Uri
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.Card
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material.icons.rounded.PlayArrow
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.lduboscq.jukebox.Jukebox
import com.lduboscq.jukebox.JukeboxViewModel
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch

@Composable
fun ListExample() {

val commands1: Channel<JukeboxViewModel.Commands> = Channel()
val commands2: Channel<JukeboxViewModel.Commands> = Channel()
val commands3: Channel<JukeboxViewModel.Commands> = Channel()

Column {
ListenAudioItem(
"Audio 1",
Uri.parse("https://filesamples.com/samples/audio/mp3/sample1.mp3"),
commands1
)
Spacer(Modifier.height(16.dp))

ListenAudioItem(
"Audio 2",
Uri.parse("https://filesamples.com/samples/audio/mp3/sample2.mp3"),
commands2
)

Spacer(Modifier.height(16.dp))

ListenAudioItem(
"Audio 3",
Uri.parse("https://filesamples.com/samples/audio/mp3/sample3.mp3"),
commands3
)
}
}


@Composable
private fun ListenAudioItem(
name: String,
uri: Uri,
flowCommands: Channel<JukeboxViewModel.Commands>,
) {
val commandsScope = rememberCoroutineScope()

Card(Modifier.fillMaxWidth()) {
Column(Modifier.padding(16.dp)) {
Text(
name,
modifier = Modifier.fillMaxWidth(),
)

Spacer(Modifier.height(8.dp))

Jukebox(
uri = uri,
commands = flowCommands.receiveAsFlow(),
modifier = Modifier
.fillMaxWidth()
)

Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.wrapContentSize(Alignment.Center)
) {
TextButton(
onClick = {
commandsScope.launch { flowCommands.send(JukeboxViewModel.Commands.Pause) }
},
modifier = Modifier,
) {
Text(text = "Pause")
}
Spacer(Modifier.width(8.dp))
TextButton(
modifier = Modifier,
onClick = {
commandsScope.launch { flowCommands.send(JukeboxViewModel.Commands.Play) }
},
) { Text("Play") }
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,47 @@ import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier

class MainActivity : ComponentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
var itemPlaying by remember { mutableStateOf(0) }
var uri by remember { mutableStateOf(Uri.parse("https://filesamples.com/samples/audio/mp3/sample1.mp3")) }
var example by remember { mutableStateOf(2) }

JukeboxSample(
uri,
setNextUri = {
if (itemPlaying < 3) itemPlaying += 1
uri = Uri.parse(
when (itemPlaying) {
0 -> "https://filesamples.com/samples/audio/mp3/sample1.mp3"
1 -> "https://filesamples.com/samples/audio/mp3/sample2.mp3"
2 -> "https://filesamples.com/samples/audio/mp3/sample3.mp3"
3 -> "https://filesamples.com/samples/audio/mp3/sample4.mp3"
else -> throw IllegalAccessError()
}
)
Log.d("MainActivity", "onAudioListened $itemPlaying $uri")
})
Column {
Row(
Modifier
.fillMaxWidth()
.wrapContentWidth(Alignment.CenterHorizontally)
) {
Button(onClick = { example = 1 }) {
Text("One after the other")
}
Button(onClick = { example = 2 }) {
Text("List")
}
}

if (example == 1) {
OneAfterTheOtherExample()
} else if (example == 2) {
ListExample()
}
}
}
}
}
Loading

0 comments on commit fc49279

Please sign in to comment.