换A 资源

This commit is contained in:
ocean 2024-05-24 14:56:30 +08:00
parent d0a2d1d2cf
commit f2a0d7d1a8
74 changed files with 330 additions and 230 deletions

View File

@ -80,6 +80,16 @@
</intent-filter> </intent-filter>
</service> </service>
<service
android:name=".service.LocalPlaybackService"
android:exported="true"
android:foregroundServiceType="mediaPlayback">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService" />
<action android:name="android.media.browse.MediaBrowserService" />
</intent-filter>
</service>
<service <service
android:name=".service.MyDownloadService" android:name=".service.MyDownloadService"
android:exported="false" android:exported="false"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 810 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 728 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 552 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 718 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 342 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 829 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 515 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 750 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 860 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 563 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 525 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 379 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 594 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

View File

@ -1,97 +1,82 @@
{ {
"categories": [ "categories": [
{ {
"name": "Real human voice", "name": "Sound of instrument",
"audios": [ "audios": [
{ {
"name": "Breathe", "name": "Big Ben",
"file": "Real human voice/Breathe.mp3", "file": "Sound of instrument data/Big Ben.mp3",
"image": "Real human voice pic/Breathe.png" "image": "Sound of instrument/Big Ben.jpg"
}, },
{ {
"name": "Shh Shh", "name": "Guitar sound",
"file": "Real human voice/Shh Shh.mp3", "file": "Sound of instrument data/Guitar sound.mp3",
"image": "Real human voice pic/Shh Shh.png" "image": "Sound of instrument/Guitar sound.jpg"
}, },
{ {
"name": "Shhh...", "name": "Piano",
"file": "Real human voice/Shhh….mp3", "file": "Sound of instrument data/Piano.mp3",
"image": "Real human voice pic/Shhh….png" "image": "Sound of instrument/Piano.png"
},
{
"name": "Mixing cup",
"file": "Sound of instrument data/The sound of mixing cup.mp3",
"image": "Sound of instrument/The sound of mixing cup.png"
} }
] ]
}, },
{ {
"name": "Sounds of appliances", "name": "White noise",
"audios": [ "audios": [
{ {
"name": "Fireplace", "name": "High -speed car",
"file": "Sounds of appliances/Fireplace.mp3", "file": "White noise data/High -speed car.mp3",
"image": "Sounds of appliances pic/Fireplace.png" "image": "White noise/High -speed car.png"
}, },
{ {
"name": "Mountain stream", "name": "High -voltage wire",
"file": "Sounds of appliances/Mountain stream.mp3", "file": "White noise data/High -voltage wire.mp3",
"image": "Sounds of appliances pic/Mountain stream.png" "image": "White noise/High -voltage wire.jpg"
}, },
{ {
"name": "TV", "name": "Mechanical failure",
"file": "Sounds of appliances/TV.mp3", "file": "White noise data/Mechanical failure.mp3",
"image": "Sounds of appliances pic/TV.png" "image": "White noise/Mechanical failure.png"
}, },
{ {
"name": "Water droplet", "name": "Rhythm",
"file": "Sounds of appliances/Water droplet.mp3", "file": "White noise data/Rhythm.mp3",
"image": "Sounds of appliances pic/Water droplet.png" "image": "White noise/Rhythm.jpg"
} }
] ]
}, },
{ {
"name": "Sounds of nature", "name": "Voice of Nature",
"audios": [ "audios": [
{ {
"name": "Beach", "name": "Flowing water",
"file": "Sounds of nature/Beach.mp3", "file": "Voice of Nature data/Flowing water.mp3",
"image": "Sounds of nature pic/Beach.png" "image": "Voice of Nature/Flowing water.jpg"
}, },
{ {
"name": "Call of Seagulls", "name": "High -speed stream",
"file": "Sounds of nature/Call of Seagulls.mp3", "file": "Voice of Nature data/High -speed stream.mp3",
"image": "Sounds of nature pic/Call of Seagulls.png" "image": "Voice of Nature/High -speed stream.jpg"
}, },
{ {
"name": "Chirping of Birds", "name": "Hundred Birds Calling",
"file": "Sounds of nature/Chirping of Birds.mp3", "file": "Voice of Nature data/Hundred Birds Calling.mp3",
"image": "Sounds of nature pic/Chirping of Birds.png" "image": "Voice of Nature/Hundred Birds Calling.png"
}, },
{ {
"name": "Cicada Chirping", "name": "Rain falls in the leaves",
"file": "Sounds of nature/Cicada Chirping.mp3", "file": "Voice of Nature data/Rain falls in the leaves.mp3",
"image": "Sounds of nature pic/Cicada Chirping.png" "image": "Voice of Nature/Rain falls in the leaves.png"
}, },
{ {
"name": "Howling Wind", "name": "Wind blow",
"file": "Sounds of nature/Howling Wind.mp3", "file": "Voice of Nature data/Wind blow.mp3",
"image": "Sounds of nature pic/Howling Wind.png" "image": "Voice of Nature/Wind blow.jpg"
},
{
"name": "Nocturnal Insects",
"file": "Sounds of nature/Nocturnal Insects.mp3",
"image": "Sounds of nature pic/Nocturnal Insects.png"
},
{
"name": "Seawater Surging",
"file": "Sounds of nature/Seawater Surging.mp3",
"image": "Sounds of nature pic/Seawater Surging.png"
},
{
"name": "Summer Insects",
"file": "Sounds of nature/Summer Insects.mp3",
"image": "Sounds of nature pic/Summer Insects.png"
},
{
"name": "waterfall",
"file": "Sounds of nature/waterfall.mp3",
"image": "Sounds of nature pic/waterfall.png"
} }
] ]
} }

View File

@ -11,6 +11,7 @@ import com.player.musicoo.database.AppOfflineDBManager
import com.player.musicoo.database.CurrentAudioDatabase import com.player.musicoo.database.CurrentAudioDatabase
import com.player.musicoo.database.CurrentAudioManager import com.player.musicoo.database.CurrentAudioManager
import com.player.musicoo.database.DatabaseManager import com.player.musicoo.database.DatabaseManager
import com.player.musicoo.media.LocalMediaControllerManager
import com.player.musicoo.media.MediaControllerManager import com.player.musicoo.media.MediaControllerManager
import com.player.musicoo.util.CacheManager import com.player.musicoo.util.CacheManager
import com.player.musicoo.util.DownloadUtil import com.player.musicoo.util.DownloadUtil
@ -93,9 +94,9 @@ class App : Application() {
for (category in resourcesList.categories) { for (category in resourcesList.categories) {
when (category.name) { when (category.name) {
"Real human voice" -> realHumanVoiceList = category.audios "Sound of instrument" -> realHumanVoiceList = category.audios
"Sounds of appliances" -> soundsOfAppliancesList = category.audios "White noise" -> soundsOfAppliancesList = category.audios
"Sounds of nature" -> soundsOfNatureList = category.audios "Voice of Nature" -> soundsOfNatureList = category.audios
} }
} }
} }
@ -106,6 +107,7 @@ class App : Application() {
app = this app = this
initialize(this) initialize(this)
MediaControllerManager.init(this) MediaControllerManager.init(this)
LocalMediaControllerManager.init(this)
appOfflineDBManager = AppOfflineDBManager.getInstance(this) appOfflineDBManager = AppOfflineDBManager.getInstance(this)
currentAudioManager = CurrentAudioManager.getInstance(this) currentAudioManager = CurrentAudioManager.getInstance(this)
databaseManager = DatabaseManager.getInstance(this) databaseManager = DatabaseManager.getInstance(this)

View File

@ -1,9 +1,7 @@
package com.player.musicoo.activity package com.player.musicoo.activity
import android.os.Bundle import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.player.musicoo.media.MediaControllerManager
open class BaseActivity : AppCompatActivity() { open class BaseActivity : AppCompatActivity() {

View File

@ -43,7 +43,7 @@ class LaunchActivity : BaseActivity() {
} }
private fun toMainActivity() { private fun toMainActivity() {
startActivity(Intent(this, PrimaryActivity::class.java)) startActivity(Intent(this, MainActivity::class.java))
finish() finish()
} }
} }

View File

@ -5,7 +5,6 @@ import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.os.Message import android.os.Message
import android.util.Log
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
@ -19,8 +18,7 @@ import com.player.musicoo.bean.Audio
import com.player.musicoo.databinding.ActivityMainBinding import com.player.musicoo.databinding.ActivityMainBinding
import com.player.musicoo.fragment.HomeFragment import com.player.musicoo.fragment.HomeFragment
import com.player.musicoo.fragment.ImportFragment import com.player.musicoo.fragment.ImportFragment
import com.player.musicoo.media.MediaControllerManager import com.player.musicoo.media.LocalMediaControllerManager
import com.player.musicoo.util.convertMillisToMinutesAndSecondsString
import com.player.musicoo.util.getAudioDurationFromAssets import com.player.musicoo.util.getAudioDurationFromAssets
@ -52,7 +50,7 @@ class MainActivity : BaseActivity() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
val currentPlayer = MediaControllerManager.getController() val currentPlayer = LocalMediaControllerManager.getController()
if (App.currentPlayingAudio == null) { if (App.currentPlayingAudio == null) {
binding.playingStatusLayout.visibility = View.GONE binding.playingStatusLayout.visibility = View.GONE
@ -121,7 +119,7 @@ class MainActivity : BaseActivity() {
} }
binding.playBlackBtn.setOnClickListener { binding.playBlackBtn.setOnClickListener {
val currentPlayer = MediaControllerManager.getController() val currentPlayer = LocalMediaControllerManager.getController()
if (currentPlayer != null) { if (currentPlayer != null) {
if (currentPlayer.playbackState == Player.STATE_READY) { if (currentPlayer.playbackState == Player.STATE_READY) {
if (currentPlayer.isPlaying) { if (currentPlayer.isPlaying) {
@ -133,7 +131,7 @@ class MainActivity : BaseActivity() {
} }
updateProgressState() updateProgressState()
} else { } else {
MediaControllerManager.setupMedia(this@MainActivity, App.currentPlayingAudio!!, LocalMediaControllerManager.setupMedia(this@MainActivity, App.currentPlayingAudio!!,
object : Player.Listener { object : Player.Listener {
override fun onPlayWhenReadyChanged( override fun onPlayWhenReadyChanged(
playWhenReady: Boolean, playWhenReady: Boolean,
@ -209,7 +207,7 @@ class MainActivity : BaseActivity() {
} }
private fun updateProgressState() { private fun updateProgressState() {
val currentPlayer = MediaControllerManager.getController() val currentPlayer = LocalMediaControllerManager.getController()
if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY && currentPlayer.isPlaying) { if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY && currentPlayer.isPlaying) {
progressHandler.removeCallbacksAndMessages(null) progressHandler.removeCallbacksAndMessages(null)
updatePlayState(currentPlayer.isPlaying) updatePlayState(currentPlayer.isPlaying)
@ -221,7 +219,7 @@ class MainActivity : BaseActivity() {
private val progressHandler = object : Handler(Looper.myLooper()!!) { private val progressHandler = object : Handler(Looper.myLooper()!!) {
override fun handleMessage(msg: Message) { override fun handleMessage(msg: Message) {
val currentPlayer = MediaControllerManager.getController() val currentPlayer = LocalMediaControllerManager.getController()
if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY && currentPlayer.isPlaying) { if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY && currentPlayer.isPlaying) {
val currentPosition = currentPlayer.currentPosition val currentPosition = currentPlayer.currentPosition
binding.progressBar.setProgress(currentPosition) binding.progressBar.setProgress(currentPosition)

View File

@ -157,8 +157,8 @@ class MoPlayDetailsActivity : MoBaseActivity(), Player.Listener {
val id = meController.currentMediaItem?.mediaId val id = meController.currentMediaItem?.mediaId
LogD(TAG, "initDownloadFlow id ->${id}") LogD(TAG, "initDownloadFlow id ->${id}")
val currentScreenDownloads = downloads[id] val currentScreenDownloads = downloads[id]
LogD(TAG, "currentScreenDownloads->${currentScreenDownloads}")
if (currentScreenDownloads != null) { if (currentScreenDownloads != null) {
LogD(TAG, "initDownloadFlow Download id->${currentScreenDownloads?.request?.id}")
updateDownloadUI(currentScreenDownloads) updateDownloadUI(currentScreenDownloads)
} }
} }

View File

@ -13,9 +13,9 @@ import android.renderscript.Allocation
import android.renderscript.Element import android.renderscript.Element
import android.renderscript.RenderScript import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicBlur import android.renderscript.ScriptIntrinsicBlur
import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.annotation.OptIn import androidx.annotation.OptIn
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi import androidx.media3.common.util.UnstableApi
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
@ -24,7 +24,8 @@ import com.gyf.immersionbar.ktx.immersionBar
import com.player.musicoo.R import com.player.musicoo.R
import com.player.musicoo.bean.Audio import com.player.musicoo.bean.Audio
import com.player.musicoo.databinding.ActivityPlayDetailsBinding import com.player.musicoo.databinding.ActivityPlayDetailsBinding
import com.player.musicoo.media.MediaControllerManager import com.player.musicoo.media.LocalMediaControllerManager
import com.player.musicoo.util.LogTag
import com.player.musicoo.util.containsContent import com.player.musicoo.util.containsContent
import com.player.musicoo.util.convertMillisToMinutesAndSecondsString import com.player.musicoo.util.convertMillisToMinutesAndSecondsString
import com.player.musicoo.util.getAudioDurationFromAssets import com.player.musicoo.util.getAudioDurationFromAssets
@ -53,7 +54,6 @@ class PlayDetailsActivity : BaseActivity() {
Toast.makeText(this, getString(R.string.data_error), Toast.LENGTH_SHORT).show() Toast.makeText(this, getString(R.string.data_error), Toast.LENGTH_SHORT).show()
} }
initView() initView()
} }
private fun initImmersionBar() { private fun initImmersionBar() {
@ -97,7 +97,7 @@ class PlayDetailsActivity : BaseActivity() {
binding.backBtn.setOnClickListener { binding.backBtn.setOnClickListener {
onBackPressed() onBackPressed()
} }
val currentPlayer = MediaControllerManager.getController() val currentPlayer = LocalMediaControllerManager.getController()
currentPlayer?.addListener(object : Player.Listener { currentPlayer?.addListener(object : Player.Listener {
override fun onPlayWhenReadyChanged( override fun onPlayWhenReadyChanged(
playWhenReady: Boolean, playWhenReady: Boolean,
@ -123,9 +123,12 @@ class PlayDetailsActivity : BaseActivity() {
updateProgressState() updateProgressState()
} }
} }
MediaControllerManager.setupMedia(this, LocalMediaControllerManager.setupMedia(this,
audio!!, audio!!,
object : Player.Listener { object : Player.Listener {
override fun onPlayerError(error: PlaybackException) {
LogTag.LogD("ocean","error->${error}")
}
override fun onPlayWhenReadyChanged( override fun onPlayWhenReadyChanged(
playWhenReady: Boolean, playWhenReady: Boolean,
reason: Int reason: Int
@ -154,7 +157,7 @@ class PlayDetailsActivity : BaseActivity() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
val currentPlayer = MediaControllerManager.getController() val currentPlayer = LocalMediaControllerManager.getController()
if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY) { if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY) {
val isPlaying = currentPlayer.isPlaying val isPlaying = currentPlayer.isPlaying
updatePlayState(isPlaying, "onResume") updatePlayState(isPlaying, "onResume")
@ -236,7 +239,7 @@ class PlayDetailsActivity : BaseActivity() {
} }
private fun updateProgressState() { private fun updateProgressState() {
val currentPlayer = MediaControllerManager.getController() val currentPlayer = LocalMediaControllerManager.getController()
if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY && currentPlayer.isPlaying) { if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY && currentPlayer.isPlaying) {
updatePlayState(currentPlayer.isPlaying, "playWhenReady") updatePlayState(currentPlayer.isPlaying, "playWhenReady")
progressHandler.removeCallbacksAndMessages(null) progressHandler.removeCallbacksAndMessages(null)
@ -248,7 +251,7 @@ class PlayDetailsActivity : BaseActivity() {
private val progressHandler = object : Handler(Looper.myLooper()!!) { private val progressHandler = object : Handler(Looper.myLooper()!!) {
override fun handleMessage(msg: Message) { override fun handleMessage(msg: Message) {
val currentPlayer = MediaControllerManager.getController() val currentPlayer = LocalMediaControllerManager.getController()
if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY && currentPlayer.isPlaying) { if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY && currentPlayer.isPlaying) {
val currentPosition = currentPlayer.currentPosition val currentPosition = currentPlayer.currentPosition
val currentString = convertMillisToMinutesAndSecondsString(currentPosition) val currentString = convertMillisToMinutesAndSecondsString(currentPosition)

View File

@ -0,0 +1,169 @@
package com.player.musicoo.media
import android.content.ComponentName
import android.content.Context
import android.net.Uri
import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.session.MediaController
import androidx.media3.session.SessionToken
import com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.MoreExecutors
import com.player.musicoo.App
import com.player.musicoo.R
import com.player.musicoo.bean.Audio
import com.player.musicoo.bean.CurrentPlayingAudio
import com.player.musicoo.service.LocalPlaybackService
import com.player.musicoo.util.containsContent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@UnstableApi
object LocalMediaControllerManager {
private var mediaController: MediaController? = null
private var controllerFuture: ListenableFuture<MediaController>? = null
private var currentAudioFile = ""
fun init(context: Context) {
val sessionToken =
SessionToken(context, ComponentName(context, LocalPlaybackService::class.java))
controllerFuture = MediaController.Builder(context, sessionToken).buildAsync()
controllerFuture?.addListener({
mediaController = controllerFuture?.get()
}, MoreExecutors.directExecutor())
}
fun getController(): MediaController? {
return if (mediaController != null && mediaController!!.isConnected) {
mediaController
} else {
null
}
}
fun setupMedia(context: Context, audio: Audio, listener: Player.Listener) {
if (currentAudioFile != audio.file) {
currentAudioFile = audio.file
val uri: Uri? = if (containsContent(audio.file)) {
Uri.parse(audio.file)
} else {
Uri.parse("file:///android_asset/$currentAudioFile")
}
val resourceId = R.mipmap.musicoo_logo_img
val imgUri: Uri? = if (audio.image.isNotEmpty()) {
Uri.parse("file:///android_asset/${audio.image}")
} else {
Uri.parse("android.resource://${context.packageName}/$resourceId")
}
val mediaItem =
MediaItem.Builder()
.setUri(uri)
.setMediaMetadata(
MediaMetadata.Builder()
.setArtist(audio.name)
.setTitle(audio.name)
.setArtworkUri(imgUri)
.build()
)
.build()
if (isConnected()) {
mediaController?.let {
it.addListener(listener)
it.setMediaItem(mediaItem)
it.repeatMode = Player.REPEAT_MODE_ALL
it.prepare()
it.play()
val currentPlayingAudio =
CurrentPlayingAudio(
audio.id,
audio.name,
audio.file,
audio.image,
audio.duration,
false
)
CoroutineScope(Dispatchers.IO).launch {
App.currentAudioManager.setCurrentPlayingAudio(currentPlayingAudio)
withContext(Dispatchers.Main) {
App.initCurrentPlayingAudio()//更新到入口变量中
}
}
}
}
}
}
fun setupMedia(context: Context, audio: CurrentPlayingAudio, listener: Player.Listener) {
if (currentAudioFile != audio.file) {
currentAudioFile = audio.file
val uri: Uri? = if (containsContent(audio.file)) {
Uri.parse(audio.file)
} else {
Uri.parse("file:///android_asset/$currentAudioFile")
}
val resourceId = R.mipmap.musicoo_logo_img
val imgUri: Uri? = if (audio.image.isNotEmpty()) {
Uri.parse("file:///android_asset/${audio.image}")
} else {
Uri.parse("android.resource://${context.packageName}/$resourceId")
}
// val uri = Uri.parse("file:///android_asset/$currentAudioFile")
//// val mediaItem = MediaItem.fromUri(uri)
// val imgUri = Uri.parse("file:///android_asset/${audio.image}")
val mediaItem =
MediaItem.Builder()
.setUri(uri)
.setMediaMetadata(
MediaMetadata.Builder()
.setArtist(audio.name)
.setTitle(audio.name)
.setArtworkUri(imgUri)
.build()
)
.build()
if (isConnected()) {
mediaController?.let {
it.addListener(listener)
it.setMediaItem(mediaItem)
it.repeatMode = Player.REPEAT_MODE_ALL
it.prepare()
it.play()
val currentPlayingAudio =
CurrentPlayingAudio(
audio.id,
audio.name,
audio.file,
audio.image,
audio.duration,
false
)
CoroutineScope(Dispatchers.IO).launch {
App.currentAudioManager.setCurrentPlayingAudio(currentPlayingAudio)
withContext(Dispatchers.Main) {
App.initCurrentPlayingAudio()//更新到入口变量中
}
}
}
}
}
}
fun isConnected(): Boolean {
mediaController?.let {
return it.isConnected
}
return false
}
}

View File

@ -7,6 +7,7 @@ import android.os.Binder
import androidx.media3.common.MediaItem import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata import androidx.media3.common.MediaMetadata
import androidx.media3.common.Player import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.session.MediaController import androidx.media3.session.MediaController
import androidx.media3.session.SessionToken import androidx.media3.session.SessionToken
import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.ListenableFuture
@ -22,10 +23,10 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@UnstableApi
object MediaControllerManager { object MediaControllerManager {
private var mediaController: MediaController? = null private var mediaController: MediaController? = null
private var controllerFuture: ListenableFuture<MediaController>? = null private var controllerFuture: ListenableFuture<MediaController>? = null
private var currentAudioFile = ""
fun init(context: Context) { fun init(context: Context) {
val sessionToken = val sessionToken =
@ -44,129 +45,6 @@ object MediaControllerManager {
} }
} }
fun setupMedia(context: Context, audio: Audio, listener: Player.Listener) {
if (currentAudioFile != audio.file) {
currentAudioFile = audio.file
val uri: Uri? = if (containsContent(audio.file)) {
Uri.parse(audio.file)
} else {
Uri.parse("file:///android_asset/$currentAudioFile")
}
val resourceId = R.mipmap.musicoo_logo_img
val imgUri: Uri? = if (audio.image.isNotEmpty()) {
Uri.parse("file:///android_asset/${audio.image}")
} else {
Uri.parse("android.resource://${context.packageName}/$resourceId")
}
val mediaItem =
MediaItem.Builder()
.setUri(uri)
.setMediaMetadata(
MediaMetadata.Builder()
.setArtist(audio.name)
.setTitle(audio.name)
.setArtworkUri(imgUri)
.build()
)
.build()
if (isConnected()) {
mediaController?.let {
it.addListener(listener)
it.setMediaItem(mediaItem)
it.repeatMode = Player.REPEAT_MODE_ALL
it.prepare()
it.play()
val currentPlayingAudio =
CurrentPlayingAudio(
audio.id,
audio.name,
audio.file,
audio.image,
audio.duration,
false
)
CoroutineScope(Dispatchers.IO).launch {
App.currentAudioManager.setCurrentPlayingAudio(currentPlayingAudio)
withContext(Dispatchers.Main) {
App.initCurrentPlayingAudio()//更新到入口变量中
}
}
}
}
}
}
fun setupMedia(context: Context, audio: CurrentPlayingAudio, listener: Player.Listener) {
if (currentAudioFile != audio.file) {
currentAudioFile = audio.file
val uri: Uri? = if (containsContent(audio.file)) {
Uri.parse(audio.file)
} else {
Uri.parse("file:///android_asset/$currentAudioFile")
}
val resourceId = R.mipmap.musicoo_logo_img
val imgUri: Uri? = if (audio.image.isNotEmpty()) {
Uri.parse("file:///android_asset/${audio.image}")
} else {
Uri.parse("android.resource://${context.packageName}/$resourceId")
}
// val uri = Uri.parse("file:///android_asset/$currentAudioFile")
//// val mediaItem = MediaItem.fromUri(uri)
// val imgUri = Uri.parse("file:///android_asset/${audio.image}")
val mediaItem =
MediaItem.Builder()
.setUri(uri)
.setMediaMetadata(
MediaMetadata.Builder()
.setArtist(audio.name)
.setTitle(audio.name)
.setArtworkUri(imgUri)
.build()
)
.build()
if (isConnected()) {
mediaController?.let {
it.addListener(listener)
it.setMediaItem(mediaItem)
it.repeatMode = Player.REPEAT_MODE_ALL
it.prepare()
it.play()
val currentPlayingAudio =
CurrentPlayingAudio(
audio.id,
audio.name,
audio.file,
audio.image,
audio.duration,
false
)
CoroutineScope(Dispatchers.IO).launch {
App.currentAudioManager.setCurrentPlayingAudio(currentPlayingAudio)
withContext(Dispatchers.Main) {
App.initCurrentPlayingAudio()//更新到入口变量中
}
}
}
}
}
}
fun isConnected(): Boolean {
mediaController?.let {
return it.isConnected
}
return false
}
fun getDuration(): Long { fun getDuration(): Long {
mediaController?.let { mediaController?.let {
if (it.duration > 0) { if (it.duration > 0) {

View File

@ -0,0 +1,56 @@
package com.player.musicoo.service
import android.content.Intent
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSessionService
import com.player.musicoo.R
@UnstableApi
class LocalPlaybackService : MediaSessionService() {
private var mediaSession: MediaSession? = null
// Create your player and media session in the onCreate lifecycle event
override fun onCreate() {
super.onCreate()
val player = ExoPlayer.Builder(this).build()
mediaSession = MediaSession.Builder(this, player)
.setId(getString(R.string.app_name) + "LocalPlay")
.build()
// setMediaNotificationProvider(MyMediaNotificationProvider(this))
}
// The user dismissed the app from the recent tasks
override fun onTaskRemoved(rootIntent: Intent?) {
val player = mediaSession?.player!!
if (!player.playWhenReady
|| player.mediaItemCount == 0
|| player.playbackState == Player.STATE_ENDED
) {
// Stop the service if not playing, continue playing in the background
// otherwise.
stopSelf()
}
}
override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? =
mediaSession
// Remember to release the player and media session in onDestroy
override fun onDestroy() {
mediaSession?.run {
player.release()
release()
mediaSession = null
}
super.onDestroy()
}
}

View File

@ -92,6 +92,7 @@ class PlaybackService : MediaSessionService(), Player.Listener {
player.addListener(this) player.addListener(this)
mediaSession = MediaSession.Builder(this, player) mediaSession = MediaSession.Builder(this, player)
.setId(getString(R.string.app_name) + "OnlinePlay")
.build() .build()

View File

@ -6,8 +6,8 @@ import android.net.Uri
import android.widget.Toast import android.widget.Toast
import com.player.musicoo.R import com.player.musicoo.R
const val PRIVACY_POLICY_URL = "https://musicoo.app/privacy" const val PRIVACY_POLICY_URL = "https://sites.google.com/view/musiclax-privacy/home"
const val TERMS_OF_SERVICE_URL = "https://musicoo.app/terms" const val TERMS_OF_SERVICE_URL = "https://sites.google.com/view/musiclax-terms/home"
fun openPrivacyPolicy(context: Context, privacyPolicyUrl: String) { fun openPrivacyPolicy(context: Context, privacyPolicyUrl: String) {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(privacyPolicyUrl)) val intent = Intent(Intent.ACTION_VIEW, Uri.parse(privacyPolicyUrl))

View File

@ -14,12 +14,26 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@mipmap/splash_bg_img" />
<LinearLayout
android:layout_width="match_parent"
android:gravity="center"
android:orientation="vertical"
android:layout_height="match_parent">
<ImageView
android:layout_width="98dp"
android:layout_height="98dp"
android:src="@mipmap/musicoo_logo_img"/>
<TextView
android:layout_width="wrap_content"
android:textColor="@color/white_60"
android:textSize="32dp"
android:text="@string/app_name"
android:fontFamily="@font/bold_font_italic"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -31,7 +45,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/listen_music_anytime" android:text="@string/resource_loading"
android:textColor="#CCFFFFFF" android:textColor="#CCFFFFFF"
android:textSize="16dp" /> android:textSize="16dp" />
@ -41,13 +55,6 @@
android:layout_height="6dp" android:layout_height="6dp"
android:layout_marginTop="10dp" /> android:layout_marginTop="10dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/resource_loading"
android:textColor="#99FFFFFF"
android:textSize="12dp" />
</LinearLayout> </LinearLayout>
</RelativeLayout> </RelativeLayout>
</LinearLayout> </LinearLayout>

View File

@ -4,13 +4,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/main_bg_color"> android:background="@color/main_bg_color">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@mipmap/settings_bg_img" />
<View <View
android:id="@+id/view" android:id="@+id/view"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -1,5 +1,5 @@
<resources> <resources>
<string name="app_name">Musicoo</string> <string name="app_name">Musiclax</string>
<string name="ready_to_sleep">Ready to sleep</string> <string name="ready_to_sleep">Ready to sleep</string>
<string name="home_top_desc">We\'ve carefully prepared sounds for you </string> <string name="home_top_desc">We\'ve carefully prepared sounds for you </string>
<string name="data_error">Data Error</string> <string name="data_error">Data Error</string>