Added ProgressBar for playback duration

This commit is contained in:
Balazs Toldi 2021-11-23 10:43:23 +01:00
parent dcac6e7801
commit f35295824c
Signed by: Bazsalanszky
GPG key ID: 933820884952BE27
5 changed files with 84 additions and 47 deletions

View file

@ -23,6 +23,9 @@
<entry key="../../../../../layout/compose-model-1637651867699.xml" value="0.3095439189189189" />
<entry key="../../../../../layout/compose-model-1637652867578.xml" value="0.36018518518518516" />
<entry key="../../../../../layout/compose-model-1637653004789.xml" value="0.45740740740740743" />
<entry key="../../../../../layout/compose-model-1637654654111.xml" value="0.33" />
<entry key="../../../../../layout/compose-model-1637655458616.xml" value="0.45740740740740743" />
<entry key="../../../../../layout/compose-model-1637656156044.xml" value="0.25" />
</map>
</option>
</component>

View file

@ -14,6 +14,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import eu.toldi.balazs.caster.ui.theme.CasterTheme
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.GlobalScope
@ -26,6 +28,9 @@ import com.yausername.youtubedl_android.YoutubeDL
import com.yausername.youtubedl_android.YoutubeDLRequest
import com.yausername.youtubedl_android.YoutubeDLException
import com.yausername.youtubedl_android.mapper.VideoInfo
import eu.toldi.balazs.caster.model.ChromecastManageViewmodel
import kotlinx.coroutines.withContext
import su.litvak.chromecast.api.v2.Media
import su.litvak.chromecast.api.v2.MediaStatus
@ -33,13 +38,13 @@ class ChromecastManagerActivity : ComponentActivity() {
companion object {
var chromeCast_: ChromeCast? = null
fun castLink(chromeCast: ChromeCast,link : String, callBack : () -> Unit = {}) : Boolean{
suspend fun castLink(chromeCast: ChromeCast,link : String, callBack : () -> Unit = {}) : Boolean{
var exitStatus = true
if(link.startsWith("https://").not() && link.startsWith("http://").not()) {
callBack.invoke()
return false
}
GlobalScope.launch(IO) {
withContext(IO){
val request =
YoutubeDLRequest(link)
request.addOption("-f", "best")
@ -94,9 +99,12 @@ class ChromecastManagerActivity : ComponentActivity() {
}
setContent {
CasterTheme {
val viewModel = ViewModelProvider(this).get(ChromecastManageViewmodel::class.java)
viewModel.chromeCast = chromeCast
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
Column {
viewModel.fetchMediaStatus()
MenuBar()
Column(
modifier = Modifier
@ -120,8 +128,10 @@ class ChromecastManagerActivity : ComponentActivity() {
enabled = castEnabled,
onClick = {
castEnabled = false
castLink(chromeCast,text) {
castEnabled = true
lifecycleScope.launch {
castLink(chromeCast, text) {
castEnabled = true
}
}
},
@ -132,7 +142,21 @@ class ChromecastManagerActivity : ComponentActivity() {
if(castEnabled.not()){
CircularProgressIndicator()
}
playBackControl()
playBackControl(viewmodel = viewModel)
val mediaStatus = viewModel.mediaStatus.value
if(mediaStatus != null) {
val nowPlaying = mediaStatus.media.metadata[Media.METADATA_TITLE]
Text(text = "Now playing: $nowPlaying")
val progress = mediaStatus.currentTime/ mediaStatus.media.duration
Row(Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween) {
Text(text = String.format("%02d:%02d",((mediaStatus.currentTime % 3600) / 60).toInt(), (mediaStatus.currentTime % 60).toInt()))
Text(text = String.format("%02d:%02d",((mediaStatus.media.duration % 3600) / 60).toInt(),(mediaStatus.media.duration % 60).toInt()))
}
Slider(value = progress.toFloat(), onValueChange = {
viewModel.seek(it.toDouble())
})
}
}
}
}
@ -164,63 +188,67 @@ class ChromecastManagerActivity : ComponentActivity() {
}
@Composable
fun playBackControl(){
fun playBackControl(viewmodel: ChromecastManageViewmodel){
val mediaStatus = viewmodel.mediaStatus.value
Row {
IconButton(onClick = {
GlobalScope.launch(IO) {
if(chromeCast.mediaStatus != null) {
chromeCast.seek(chromeCast.mediaStatus.currentTime - 10)
if(mediaStatus != null) {
lifecycleScope.launch(IO) {
chromeCast.seek(chromeCast.mediaStatus.currentTime - 10)
viewmodel.fetchMediaStatus()
}
}
}
}) {
},enabled = mediaStatus != null) {
Icon(
Icons.Filled.FastRewind,
contentDescription = "FastRewind"
)
}
/*
var playBackState by remember { mutableStateOf(MediaStatus.PlayerState.IDLE) }
GlobalScope.launch(IO) {
lifecycleScope.launch(IO) {
if(chromeCast.mediaStatus != null)
playBackState = chromeCast.mediaStatus.playerState
}
}*/
IconButton(onClick = {
GlobalScope.launch(IO) {
if(chromeCast.mediaStatus != null)
playBackState = chromeCast.mediaStatus.playerState
if(playBackState == MediaStatus.PlayerState.PLAYING) {
chromeCast.pause()
lifecycleScope.launch(IO) {
if(mediaStatus != null) {
if (mediaStatus.playerState == MediaStatus.PlayerState.PLAYING) {
chromeCast.pause()
}
if (mediaStatus.playerState == MediaStatus.PlayerState.PAUSED) {
chromeCast.play()
}
viewmodel.fetchMediaStatus()
}
if(playBackState == MediaStatus.PlayerState.PAUSED) {
chromeCast.play()
}
if(chromeCast.mediaStatus != null)
playBackState = chromeCast.mediaStatus.playerState
}
}) {
when(playBackState) {
MediaStatus.PlayerState.PLAYING -> Icon(
Icons.Filled.Pause,
contentDescription = "Pause"
)
MediaStatus.PlayerState.PAUSED -> Icon(
},enabled = mediaStatus != null) {
when {
mediaStatus == null || mediaStatus.playerState == MediaStatus.PlayerState.PAUSED -> Icon(
Icons.Filled.PlayArrow,
contentDescription = "Resume"
)
mediaStatus.playerState == MediaStatus.PlayerState.PLAYING -> Icon(
Icons.Filled.Pause,
contentDescription = "Pause"
)
else -> Icon(
Icons.Filled.PlayArrow,
contentDescription = "Resume"
)
}
}
IconButton(onClick = {
GlobalScope.launch(IO) {
if(chromeCast.runningApp != null)
lifecycleScope.launch(IO) {
if(chromeCast.runningApp != null) {
chromeCast.stopApp()
viewmodel.fetchMediaStatus()
}
}
}) {
},enabled = mediaStatus != null) {
Icon(
Icons.Filled.Stop,
contentDescription = "Stop"
@ -228,12 +256,13 @@ class ChromecastManagerActivity : ComponentActivity() {
}
IconButton(onClick = {
GlobalScope.launch(IO) {
lifecycleScope.launch(IO) {
if(chromeCast.mediaStatus != null) {
chromeCast.seek(chromeCast.mediaStatus.currentTime + 10)
viewmodel.fetchMediaStatus()
}
}
}) {
},enabled = mediaStatus != null) {
Icon(
Icons.Filled.FastForward,
contentDescription = "FastForward"
@ -292,7 +321,11 @@ class ChromecastManagerActivity : ComponentActivity() {
) {
Text(text = "Cast")
}
playBackControl()
// val viewModel = ViewModelProvider(this).get(ChromecastManageViewmodel::class.java)
//playBackControl(viewModel)
Text(text = "Now playing: Some video")
var sliderPosition by remember { mutableStateOf(0f) }
Slider(value = sliderPosition, onValueChange = { sliderPosition = it })
}
}
}

View file

@ -42,13 +42,13 @@ class MainActivity : ComponentActivity() {
val viewModel = ViewModelProvider(this).get(ChromeCastViewModel::class.java)
viewModel.startScanning()
val chromeCastState = viewModel._chromecasts.observeAsState(initial = emptyList())
val chromeCastState = viewModel.chromeCasts.observeAsState(initial = emptyList())
val chromeCasts = chromeCastState.value
Log.e(null,chromeCasts.toString())
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
Column {
MenuBar() {
MenuBar {
viewModel.refresh()
}
LazyColumn(modifier = Modifier

View file

@ -22,6 +22,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.yausername.youtubedl_android.YoutubeDL
import com.yausername.youtubedl_android.YoutubeDLException
import eu.toldi.balazs.caster.model.ChromeCastViewModel
@ -53,7 +54,7 @@ class ShareRecieverActivity : ComponentActivity() {
CasterTheme {
val viewModel = ViewModelProvider(this).get(ChromeCastViewModel::class.java)
viewModel.startScanning()
val chromeCastState = viewModel.chromeCastsLiveData.observeAsState(emptyList())
val chromeCastState = viewModel.chromeCasts.observeAsState(emptyList())
val chromeCasts = chromeCastState.value
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
@ -105,8 +106,10 @@ class ShareRecieverActivity : ComponentActivity() {
Button(
onClick = {
onEnableChanged(false)
ChromecastManagerActivity.castLink(chromeCast, link) {
finish()
lifecycleScope.launch {
ChromecastManagerActivity.castLink(chromeCast, link) {
finish()
}
}
},
modifier = Modifier.padding(5.dp),

View file

@ -12,17 +12,15 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
import su.litvak.chromecast.api.v2.ChromeCast
import su.litvak.chromecast.api.v2.ChromeCasts
import su.litvak.chromecast.api.v2.ChromeCastsListener
import su.litvak.chromecast.api.v2.*
import java.net.InetAddress
import java.net.NetworkInterface
import javax.jmdns.ServiceEvent
import javax.jmdns.ServiceListener
class ChromeCastViewModel : ViewModel(),ChromeCastsListener {
val _chromecasts : MutableLiveData<List<ChromeCast>> = MutableLiveData<List<ChromeCast>>(listOf())
val chromeCastsLiveData : LiveData<List<ChromeCast>>
private val _chromecasts : MutableLiveData<List<ChromeCast>> = MutableLiveData<List<ChromeCast>>(listOf())
val chromeCasts : LiveData<List<ChromeCast>>
get() = _chromecasts
init {