Skip to content

Commit

Permalink
feat: cache chunk in disk and preload next music
Browse files Browse the repository at this point in the history
  • Loading branch information
hpp2334 committed Nov 27, 2024
1 parent 96f6390 commit 5ae1435
Show file tree
Hide file tree
Showing 18 changed files with 652 additions and 265 deletions.
2 changes: 1 addition & 1 deletion android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ android {
minSdk = 29
targetSdk = 34
versionCode = 1
versionName = "0.2.0-beta.6"
versionName = "0.2.0-beta.7"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ enum class EaseIconButtonType {
}

data class EaseIconButtonColors(
val buttonBg: Color,
val iconTint: Color,
val buttonBg: Color? = null,
val buttonDisabledBg: Color? = null,
val iconTint: Color? = null,
)

@Composable
Expand All @@ -73,7 +74,7 @@ fun EaseIconButton(
if (!isVariant) {
Color.Transparent
} else {
MaterialTheme.colorScheme.surfaceVariant
overrideColors?.buttonDisabledBg ?: MaterialTheme.colorScheme.surfaceVariant
}
} else {
overrideColors?.buttonBg
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Semaphore
import uniffi.ease_client_android.IAssetLoadDelegateForeign
import uniffi.ease_client_android.IPlayerDelegateForeign
import uniffi.ease_client_android.apiBackendPlayNext
import uniffi.ease_client_android.apiBackendPlayPrevious
import uniffi.ease_client_android.apiCloseAsset
import uniffi.ease_client_android.apiOpenAsset
import uniffi.ease_client_android.apiPollAsset
import uniffi.ease_client_backend.AssetChunkData
import uniffi.ease_client_backend.AssetChunkRead
import uniffi.ease_client_backend.AssetLoadStatus
import uniffi.ease_client_backend.MusicToPlay
import uniffi.ease_client_shared.DataSourceKey
Expand Down Expand Up @@ -108,12 +110,35 @@ private class EaseMusicDataSource : BaseDataSource(true) {

private var _currentDataSpec: DataSpec? = null

private var _sessionId: ULong = 0UL
private var _currentStatus: AssetLoadStatus = AssetLoadStatus.Pending
private val _byteQueue = ByteQueue()

fun poll() {
val result = apiPollAsset(this._handle!!)
when (result) {
is AssetChunkRead.Chunk -> {
when (result.v1) {
is AssetChunkData.Buffer -> {
_byteQueue.put(result.v1.v1)
}
is AssetChunkData.Status -> {
this._currentStatus = result.v1.v1
}
}
}
AssetChunkRead.None -> {}
AssetChunkRead.NotOpen -> {
this._currentStatus = AssetLoadStatus.NotFound
}
}
}

override fun read(buffer: ByteArray, offset: Int, length: Int): Int {
try {
if (_byteQueue.isEmpty() && this._handle != null) {
poll()
}

val status = this._currentStatus
if (status is AssetLoadStatus.NotFound) {
throw IOException("Not Found")
Expand Down Expand Up @@ -152,23 +177,8 @@ private class EaseMusicDataSource : BaseDataSource(true) {

_currentDataSpec = dataSpec

val sessionId = ++_sessionId

try {
val self = this
this._handle = apiOpenAsset(key, dataSpec.position.toULong(), object : IAssetLoadDelegateForeign {
override fun onStatus(status: AssetLoadStatus) {
if (sessionId == _sessionId) {
self._currentStatus = status
}
}

override fun onChunk(chunk: ByteArray) {
if (sessionId == _sessionId) {
self._byteQueue.put(chunk)
}
}
})
this._handle = apiOpenAsset(key, dataSpec.position.toULong())
return C.LENGTH_UNSET.toLong()
} catch (e: Exception) {
println(e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,11 @@ private fun MusicPanel(
buttonType = EaseIconButtonType.Primary,
painter = painterResource(id = R.drawable.icon_play),
disabled = state.loading,
overrideColors = if (state.loading) {
EaseIconButtonColors(
buttonDisabledBg = MaterialTheme.colorScheme.secondary,
)
} else { null },
onClick = {
bridge.dispatchClick(MusicControlWidget.PLAY)
}
Expand Down
76 changes: 36 additions & 40 deletions rust-libs/Cargo.lock

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

31 changes: 16 additions & 15 deletions rust-libs/ease-client-android/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{
};

use ease_client::{build_client, Action, ViewAction};
use ease_client_backend::Backend;
use ease_client_backend::{AssetChunkRead, Backend};
use ease_client_shared::backends::{
app::ArgInitializeApp, encode_message_payload, generated::Code, player::PlayerDelegateEvent,
storage::DataSourceKey, MessagePayload,
Expand All @@ -16,10 +16,10 @@ use tracing::subscriber::set_global_default;

use crate::{
foreigns::{
AssetLoadDelegate, IAssetLoadDelegateForeign, IAsyncAdapterForeign,
IPermissionServiceForeign, IPlayerDelegateForeign, IRouterServiceForeign,
IToastServiceForeign, IViewStateServiceForeign, PermissionServiceDelegate, PlayerDelegate,
RouterServiceDelegate, ToastServiceDelegate, ViewStateServiceDelegate,
IAsyncAdapterForeign, IPermissionServiceForeign, IPlayerDelegateForeign,
IRouterServiceForeign, IToastServiceForeign, IViewStateServiceForeign,
PermissionServiceDelegate, PlayerDelegate, RouterServiceDelegate, ToastServiceDelegate,
ViewStateServiceDelegate,
},
inst::{BACKEND, CLIENTS, RT},
};
Expand Down Expand Up @@ -190,7 +190,7 @@ pub fn api_flush_backend_spawned_local() {
pub async fn api_load_asset(key: DataSourceKey) -> Option<Vec<u8>> {
RT.spawn(async move {
if let Some(backend) = BACKEND.try_backend() {
let file = backend.asset_server().load(key, 0).await;
let file = backend.asset_loader().load(key, 0).await;
if let Ok(Some(file)) = file {
return file.bytes().await.ok().map(|v| v.to_vec());
}
Expand All @@ -202,24 +202,25 @@ pub async fn api_load_asset(key: DataSourceKey) -> Option<Vec<u8>> {
}

#[uniffi::export]
pub fn api_open_asset(
key: DataSourceKey,
offset: u64,
listener: Arc<dyn IAssetLoadDelegateForeign>,
) -> u64 {
pub fn api_open_asset(key: DataSourceKey, offset: u64) -> u64 {
let _guard = RT.enter();
let backend = BACKEND.backend();
backend.asset_loader().open(key, offset)
}

#[uniffi::export]
pub fn api_poll_asset(handle: u64) -> AssetChunkRead {
let _guard = RT.enter();
let backend = BACKEND.backend();
backend
.asset_server()
.open(key, offset as usize, AssetLoadDelegate::new(listener))
backend.asset_loader().poll(handle)
}

#[uniffi::export]
pub fn api_close_asset(id: u64) {
let _guard = RT.enter();
let backend = BACKEND.try_backend();
if let Some(backend) = backend {
backend.asset_server().close(id);
backend.asset_loader().close(id);
}
}

Expand Down
7 changes: 1 addition & 6 deletions rust-libs/ease-client-android/src/foreigns/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use ease_client::{
IPermissionService, IRouterService, IToastService, IViewStateService, RootViewModelState,
RoutesKey,
};
use ease_client_backend::{AssetLoadStatus, IAssetLoadDelegate, IPlayerDelegate, MusicToPlay};
use ease_client_backend::{IPlayerDelegate, MusicToPlay};
use ease_client_shared::backends::{music::MusicId, player::PlayerDurations};

macro_rules! generate_delegate {
Expand Down Expand Up @@ -60,11 +60,6 @@ generate_delegate!(PlayerDelegate, IPlayerDelegate, IPlayerDelegateForeign, {
request_total_duration(id: MusicId);
});

generate_delegate!(AssetLoadDelegate, IAssetLoadDelegate, IAssetLoadDelegateForeign, {
on_status(status: AssetLoadStatus);
on_chunk(chunk: Vec<u8>);
});

#[uniffi::export(with_foreign)]
pub trait IAsyncAdapterForeign: Send + Sync + 'static {
fn on_spawn_locals(&self, app_id: Option<u64>);
Expand Down
6 changes: 3 additions & 3 deletions rust-libs/ease-client-backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ ease-client-shared = { path = "../ease-client-shared" }
once_cell = "1.18.0"
serde = { version = "1.0", features = ["derive"] }
tracing = "0.1"
tokio-util = { version = "0.7.8", features = ["io"] }
num-traits = "0.2"
num-derive = "0.2"
bytes = "1.5.0"
Expand All @@ -25,9 +24,10 @@ getset = "0.1.3"
serde_json = "1.0"
serde_bytes = "0.11.14"
futures = "0.3.30"
id3 = "1.8.0"
lofty = "0.18.0"
nom = "7"
unicode-segmentation = "1.10.1"
base64 = "0.22.1"
uniffi = "=0.28.3"
redb = "2.2.0"
lru = "0.12.5"
rmp-serde = "1.3.0"
Loading

0 comments on commit 5ae1435

Please sign in to comment.