When adding tracks to the library only 40 tracks are added initially. A background coroutine for adding the remainder of the tracks continues. The coroutine does not block the main thread. #43
This commit is contained in:
@@ -48,7 +48,7 @@ class MusicFiles (private val demoPath: File) {
|
|||||||
|
|
||||||
fun searchForMp3Songs() {
|
fun searchForMp3Songs() {
|
||||||
try {
|
try {
|
||||||
var pathList: MutableList<String>? = null
|
var pathList: MutableList<String>?
|
||||||
pathList = mutableListOf()
|
pathList = mutableListOf()
|
||||||
|
|
||||||
var fileSearch = File(demoPath.absolutePath)
|
var fileSearch = File(demoPath.absolutePath)
|
||||||
@@ -56,12 +56,13 @@ class MusicFiles (private val demoPath: File) {
|
|||||||
println(it.absolutePath)
|
println(it.absolutePath)
|
||||||
if (!ignoreThisDirectory(it.absolutePath)) {
|
if (!ignoreThisDirectory(it.absolutePath)) {
|
||||||
if (it.isFile) {
|
if (it.isFile) {
|
||||||
if (it.extension.toString().equals(FileTypes.Mp3)) {
|
if (it.extension == (FileTypes.Mp3)) {
|
||||||
pathList.add(it.absolutePath)
|
pathList.add(it.absolutePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
allSongs = pathList
|
allSongs = pathList
|
||||||
}
|
}
|
||||||
catch (ex: Exception) {
|
catch (ex: Exception) {
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ package com.example.mear.management
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.media.MediaMetadataRetriever
|
import android.media.MediaMetadataRetriever
|
||||||
|
|
||||||
|
import java.io.FileInputStream
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
|
||||||
import com.example.mear.constants.Filenames
|
import com.example.mear.constants.Filenames
|
||||||
import com.example.mear.constants.SongSearch
|
import com.example.mear.constants.SongSearch
|
||||||
@@ -13,8 +15,17 @@ import com.example.mear.repositories.TrackRepository
|
|||||||
import com.example.mear.util.ConvertByteArray
|
import com.example.mear.util.ConvertByteArray
|
||||||
|
|
||||||
class TrackManager(var allSongPath: MutableList<String>) {
|
class TrackManager(var allSongPath: MutableList<String>) {
|
||||||
private var songCount: Int? = null
|
|
||||||
private var allTracks: MutableList<Track>? = null
|
private var allTracks: MutableList<Track>? = null
|
||||||
|
private var ctx: Context? = null
|
||||||
|
private var songCount: Int? = null
|
||||||
|
private var songIndex: Int? = null
|
||||||
|
private var moreSongs = true
|
||||||
|
var allTracksAdded = false
|
||||||
|
|
||||||
|
fun initializeContext(context: Context) {
|
||||||
|
ctx = context
|
||||||
|
}
|
||||||
|
|
||||||
fun configureTracks(ctx: Context): Int {
|
fun configureTracks(ctx: Context): Int {
|
||||||
var id = 0
|
var id = 0
|
||||||
@@ -49,21 +60,57 @@ class TrackManager(var allSongPath: MutableList<String>) {
|
|||||||
TrackRepository(ctx).createSongCount(id)
|
TrackRepository(ctx).createSongCount(id)
|
||||||
return id.dec()
|
return id.dec()
|
||||||
}
|
}
|
||||||
fun addTracks(ctx: Context) {
|
fun addTracks() {
|
||||||
var initTracks = initialTracks()
|
var initTracks = initialTracks()
|
||||||
addToDatabase(ctx, initTracks)
|
addToDatabase(initTracks)
|
||||||
TrackRepository(ctx).createSongCount(songCount!!)
|
|
||||||
|
if (moreSongs) {
|
||||||
|
GlobalScope.launch {
|
||||||
|
val remainingTracks = remainingTracks()
|
||||||
|
addToDatabase(remainingTracks)
|
||||||
|
allTracksAdded = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initialTracks(): MutableList<Track> {
|
private fun initialTracks(): MutableList<Track> {
|
||||||
var tracks = mutableListOf<Track>()
|
var tracks = mutableListOf<Track>()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (i in 0.. (SongSearch.INITIAL_SEARCH_AMOUNT - 1)) {
|
var initSongSearch = SongSearch.INITIAL_SEARCH_AMOUNT -1
|
||||||
|
|
||||||
|
if (allSongPath!!.size < SongSearch.INITIAL_SEARCH_AMOUNT) {
|
||||||
|
initSongSearch = allSongPath.size
|
||||||
|
moreSongs = false
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i in 0.. initSongSearch) {
|
||||||
var songPath = allSongPath[i]
|
var songPath = allSongPath[i]
|
||||||
val track = configureTrack(songPath, i)
|
val track = configureTrack(songPath, i)
|
||||||
tracks.add(track)
|
tracks.add(track)
|
||||||
}
|
}
|
||||||
|
|
||||||
songCount = tracks.size
|
songCount = tracks.size
|
||||||
|
songIndex = songCount!!
|
||||||
|
}
|
||||||
|
catch (ex: Exception) {
|
||||||
|
val exMsg = ex.message
|
||||||
|
}
|
||||||
|
|
||||||
|
return tracks
|
||||||
|
}
|
||||||
|
private fun remainingTracks(): MutableList<Track> {
|
||||||
|
val tracks = mutableListOf<Track>()
|
||||||
|
try {
|
||||||
|
for (i in songIndex!! .. (allSongPath.size - 1)) {
|
||||||
|
val songPath = allSongPath[i]
|
||||||
|
val track = configureTrack(songPath, i)
|
||||||
|
if (track.id != Int.MAX_VALUE) {
|
||||||
|
tracks.add(track)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
songCount = songCount!!.plus(tracks.size)
|
||||||
}
|
}
|
||||||
catch (ex: Exception) {
|
catch (ex: Exception) {
|
||||||
val exMsg = ex.message
|
val exMsg = ex.message
|
||||||
@@ -73,17 +120,33 @@ class TrackManager(var allSongPath: MutableList<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun configureTrack(songPath: String, id: Int): Track {
|
private fun configureTrack(songPath: String, id: Int): Track {
|
||||||
val metaData = MediaMetadataRetriever()
|
try {
|
||||||
metaData.setDataSource(songPath)
|
val metaData = MediaMetadataRetriever()
|
||||||
|
val fp = FileInputStream(songPath)
|
||||||
|
metaData.setDataSource(fp.fd)
|
||||||
|
|
||||||
val title = metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE)
|
val title = metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE)
|
||||||
val artist = metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)
|
val artist = metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)
|
||||||
val album = metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM)
|
val album = metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM)
|
||||||
val duration = (metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION).toInt()) / 1000
|
val duration = (metaData.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION).toInt()) / 1000
|
||||||
|
|
||||||
return Track(id, title, artist, album, duration, ByteArray(0), songPath)
|
fp.close()
|
||||||
|
metaData.release()
|
||||||
|
|
||||||
|
return Track(id, title, artist, album, duration, ByteArray(0), songPath)
|
||||||
|
}
|
||||||
|
catch (ex: Exception) {
|
||||||
|
val exMsg = ex.message
|
||||||
|
}
|
||||||
|
|
||||||
|
return Track()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addToDatabase(tracks: List<Track>) {
|
||||||
|
TrackRepository(ctx!!).insertTracks(tracks)
|
||||||
|
PlayCountRepository(ctx!!).insertPlayCounts(tracks)
|
||||||
|
TrackRepository(ctx!!).createSongCount(songCount!!)
|
||||||
|
}
|
||||||
private fun addToDatabase(ctx: Context, tracks: List<Track>) {
|
private fun addToDatabase(ctx: Context, tracks: List<Track>) {
|
||||||
TrackRepository(ctx).insertTracks(tracks)
|
TrackRepository(ctx).insertTracks(tracks)
|
||||||
PlayCountRepository(ctx).insertPlayCounts(tracks)
|
PlayCountRepository(ctx).insertPlayCounts(tracks)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.example.mear.models
|
package com.example.mear.models
|
||||||
|
|
||||||
data class Track (val id: Int, val title: String, val artist: String, val album: String,
|
data class Track (val id: Int = Int.MAX_VALUE, val title: String = "UNTITLED", val artist: String = "UNTITLED",
|
||||||
val length: Int, val TrackCover: ByteArray, val songPath: String) {
|
val album: String = "UNTITLED", val length: Int = Int.MAX_VALUE,
|
||||||
|
val TrackCover: ByteArray = ByteArray(0), val songPath: String = "UNTITLED") {
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,9 @@ class MusicService: Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var trackPlayer: MediaPlayer? = null
|
private var trackPlayer: MediaPlayer? = null
|
||||||
private var currentSongIndex: Int? = null
|
private var trackMgr: TrackManager? = null
|
||||||
|
private var currentTrack = Track()
|
||||||
|
private var currentSongIndex: Int? = null
|
||||||
private var shuffleOn: Boolean? = null
|
private var shuffleOn: Boolean? = null
|
||||||
private var repeatOn: Boolean? = null
|
private var repeatOn: Boolean? = null
|
||||||
private val mBinder = LocalBinder()
|
private val mBinder = LocalBinder()
|
||||||
@@ -70,11 +72,17 @@ class MusicService: Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun playTrack(id: Int) {
|
fun playTrack(id: Int) {
|
||||||
currentSongIndex = id
|
try {
|
||||||
trackPlayer!!.reset()
|
currentSongIndex = id
|
||||||
trackPlayer!!.setDataSource(TrackRepository(this).getTrack(id).songPath)
|
trackPlayer!!.reset()
|
||||||
trackPlayer!!.prepare()
|
currentTrack = TrackRepository(this).getTrack(id)
|
||||||
trackPlayer!!.start()
|
trackPlayer!!.setDataSource(currentTrack.songPath)
|
||||||
|
trackPlayer!!.prepare()
|
||||||
|
trackPlayer!!.start()
|
||||||
|
}
|
||||||
|
catch (ex: Exception) {
|
||||||
|
val exMsg = ex.message
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun goToPosition(progress: Int) {
|
fun goToPosition(progress: Int) {
|
||||||
@@ -102,14 +110,15 @@ class MusicService: Service() {
|
|||||||
shuffleOn = retrieveShuffleMode()
|
shuffleOn = retrieveShuffleMode()
|
||||||
trackPlayer!!.reset()
|
trackPlayer!!.reset()
|
||||||
if (duration > seconds) {
|
if (duration > seconds) {
|
||||||
trackPlayer!!.setDataSource(TrackRepository(this).getTrack(currentSongIndex!!).songPath)
|
currentTrack = TrackRepository(this).getTrack(currentSongIndex!!)
|
||||||
|
trackPlayer!!.setDataSource(currentTrack.songPath)
|
||||||
trackPlayer!!.prepare()
|
trackPlayer!!.prepare()
|
||||||
trackPlayer!!.start()
|
trackPlayer!!.start()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val previousTrackNumber = fetchSongIndex(PlayTypes.PlayPreviousSong)
|
val previousTrackNumber = fetchSongIndex(PlayTypes.PlayPreviousSong)
|
||||||
val track = TrackRepository(this).getTrack(previousTrackNumber)
|
currentTrack = TrackRepository(this).getTrack(previousTrackNumber)
|
||||||
trackPlayer!!.setDataSource(track.songPath)
|
trackPlayer!!.setDataSource(currentTrack.songPath)
|
||||||
trackPlayer!!.prepare()
|
trackPlayer!!.prepare()
|
||||||
trackPlayer!!.start()
|
trackPlayer!!.start()
|
||||||
}
|
}
|
||||||
@@ -123,8 +132,9 @@ class MusicService: Service() {
|
|||||||
trackPlayer!!.reset()
|
trackPlayer!!.reset()
|
||||||
shuffleOn = retrieveShuffleMode()
|
shuffleOn = retrieveShuffleMode()
|
||||||
var nextTrack = fetchSongIndex(PlayTypes.PlayNextSong)
|
var nextTrack = fetchSongIndex(PlayTypes.PlayNextSong)
|
||||||
val track = TrackRepository(this).getTrack(nextTrack)
|
val allTracks = TrackRepository(this).getAll()
|
||||||
trackPlayer!!.setDataSource(track.songPath)
|
currentTrack = TrackRepository(this).getTrack(nextTrack)
|
||||||
|
trackPlayer!!.setDataSource(currentTrack.songPath)
|
||||||
trackPlayer!!.prepare()
|
trackPlayer!!.prepare()
|
||||||
trackPlayer!!.start()
|
trackPlayer!!.start()
|
||||||
}
|
}
|
||||||
@@ -180,16 +190,8 @@ class MusicService: Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getCurrentTrack(): Track {
|
fun getCurrentTrack(): Track {
|
||||||
var track: Track? = null
|
|
||||||
|
|
||||||
track = TrackRepository(this).getTrack(currentSongIndex!!)
|
return currentTrack
|
||||||
val info = trackPlayer!!.trackInfo
|
|
||||||
|
|
||||||
if (trackPlayer!!.isPlaying) {
|
|
||||||
val res = "songs are being played"
|
|
||||||
}
|
|
||||||
|
|
||||||
return track!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -266,8 +268,8 @@ class MusicService: Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
currentSongIndex = Random.nextInt(0, TrackRepository(this).getSongCount())
|
currentSongIndex = Random.nextInt(0, TrackRepository(this).getSongCount())
|
||||||
val trackToPlay = TrackRepository(this).getTrack(currentSongIndex!!)
|
currentTrack = TrackRepository(this).getTrack(currentSongIndex!!)
|
||||||
trackPlayer!!.setDataSource(trackToPlay.songPath)
|
trackPlayer!!.setDataSource(currentTrack.songPath)
|
||||||
trackPlayer!!.prepareAsync()
|
trackPlayer!!.prepareAsync()
|
||||||
trackPlayer!!.setOnCompletionListener {
|
trackPlayer!!.setOnCompletionListener {
|
||||||
playNextTrack()
|
playNextTrack()
|
||||||
@@ -281,8 +283,9 @@ class MusicService: Service() {
|
|||||||
var mp3Paths = MusicFiles(android.os.Environment.getExternalStorageDirectory())
|
var mp3Paths = MusicFiles(android.os.Environment.getExternalStorageDirectory())
|
||||||
mp3Paths.searchForMp3Songs()
|
mp3Paths.searchForMp3Songs()
|
||||||
val paths = mp3Paths.allSongs
|
val paths = mp3Paths.allSongs
|
||||||
val trackMgr = TrackManager(paths!!)
|
trackMgr = TrackManager(paths!!)
|
||||||
trackMgr.addTracks(this)
|
trackMgr!!.initializeContext(this)
|
||||||
|
trackMgr!!.addTracks()
|
||||||
initializeShuffleMode()
|
initializeShuffleMode()
|
||||||
initializeRepeatMode()
|
initializeRepeatMode()
|
||||||
}
|
}
|
||||||
@@ -375,11 +378,8 @@ class MusicService: Service() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
val count = TrackRepository(this).getSongCount()
|
val count = TrackRepository(this).getSongCount()
|
||||||
TrackRepository(this).delete()
|
|
||||||
|
|
||||||
// TODO: Replace this with the local count varialbe when issue #43 is resolved
|
return count
|
||||||
// as well as remove the call to delete the Track table
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
catch (ex: Exception) {
|
catch (ex: Exception) {
|
||||||
val exMsg = ex.message
|
val exMsg = ex.message
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 309 B |
Binary file not shown.
|
After Width: | Height: | Size: 181 B |
Binary file not shown.
|
After Width: | Height: | Size: 365 B |
Binary file not shown.
|
After Width: | Height: | Size: 661 B |
Binary file not shown.
|
After Width: | Height: | Size: 805 B |
Reference in New Issue
Block a user