mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-12-22 20:57:54 +01:00
WIP:Download Impl
This commit is contained in:
parent
5ceb58e6de
commit
50fa91fbca
@ -20,6 +20,7 @@ internal class SpotiFlyerListImpl(
|
||||
private val store =
|
||||
instanceKeeper.getStore {
|
||||
SpotiFlyerListStoreProvider(
|
||||
dir = this.dir,
|
||||
storeFactory = storeFactory,
|
||||
fetchQuery = fetchQuery,
|
||||
link = link
|
||||
|
@ -2,6 +2,7 @@ package com.shabinder.common.list.store
|
||||
|
||||
import com.arkivanov.mvikotlin.core.store.*
|
||||
import com.arkivanov.mvikotlin.extensions.coroutines.SuspendExecutor
|
||||
import com.shabinder.common.di.Dir
|
||||
import com.shabinder.common.di.FetchPlatformQueryResult
|
||||
import com.shabinder.common.di.downloadTracks
|
||||
import com.shabinder.common.list.SpotiFlyerList.State
|
||||
@ -9,8 +10,10 @@ import com.shabinder.common.list.store.SpotiFlyerListStore.Intent
|
||||
import com.shabinder.common.models.DownloadStatus
|
||||
import com.shabinder.common.models.PlatformQueryResult
|
||||
import com.shabinder.common.models.TrackDetails
|
||||
import com.shabinder.common.ui.showPopUpMessage
|
||||
|
||||
internal class SpotiFlyerListStoreProvider(
|
||||
private val dir: Dir,
|
||||
private val storeFactory: StoreFactory,
|
||||
private val fetchQuery: FetchPlatformQueryResult,
|
||||
private val link: String
|
||||
@ -45,8 +48,8 @@ internal class SpotiFlyerListStoreProvider(
|
||||
is Intent.StartDownloadAll -> {
|
||||
val finalList =
|
||||
intent.trackList.filter { it.downloaded == DownloadStatus.NotDownloaded }
|
||||
if (finalList.isNullOrEmpty()) //TODO showDialog("All Songs are Processed")
|
||||
else downloadTracks(finalList)
|
||||
if (finalList.isNullOrEmpty()) showPopUpMessage("All Songs are Processed")
|
||||
else downloadTracks(finalList,fetchQuery.youtubeMusic::getYTIDBestMatch,dir::saveFileWithMetadata)
|
||||
|
||||
val list = intent.trackList.map {
|
||||
if (it.downloaded == DownloadStatus.NotDownloaded) {
|
||||
|
@ -25,9 +25,11 @@ import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.shabinder.common.di.giveDonation
|
||||
import com.shabinder.common.models.DownloadRecord
|
||||
import com.shabinder.common.main.SpotiFlyerMain.HomeCategory
|
||||
import com.shabinder.common.di.openPlatform
|
||||
import com.shabinder.common.di.shareApp
|
||||
import com.shabinder.common.ui.*
|
||||
import com.shabinder.common.ui.SpotiFlyerTypography
|
||||
|
||||
@ -73,10 +75,9 @@ fun HomeTabBar(
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("USELESS_CAST")//Showing Error in Latest Android Studio Canary
|
||||
TabRow(
|
||||
selectedTabIndex = selectedIndex,
|
||||
indicator = indicator as @Composable (List<TabPosition>) -> Unit,
|
||||
indicator = indicator,
|
||||
modifier = modifier,
|
||||
) {
|
||||
categories.forEachIndexed { index, category ->
|
||||
@ -245,51 +246,44 @@ fun AboutColumn(modifier: Modifier = Modifier) {
|
||||
)
|
||||
}
|
||||
}
|
||||
/*Row(
|
||||
Row(
|
||||
modifier = modifier.fillMaxWidth().padding(vertical = 6.dp)
|
||||
.clickable(onClick = { startPayment(mainActivity) }),
|
||||
.clickable(onClick = { giveDonation() }),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(Icons.Rounded.MailOutline.copy(defaultHeight = 32.dp,defaultWidth = 32.dp))
|
||||
Icon(Icons.Rounded.MailOutline,"Support Developer")
|
||||
Spacer(modifier = Modifier.padding(start = 16.dp))
|
||||
Column {
|
||||
Text(
|
||||
text = stringResource(R.string.donate),
|
||||
text = "Donate",
|
||||
style = SpotiFlyerTypography.h6
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.donate_subtitle),
|
||||
text = "If you think I deserve to get paid for my work, you can leave me some money here.",
|
||||
style = SpotiFlyerTypography.subtitle2
|
||||
)
|
||||
}
|
||||
}*/
|
||||
/*Row(
|
||||
}
|
||||
Row(
|
||||
modifier = modifier.fillMaxWidth().padding(vertical = 6.dp)
|
||||
.clickable(onClick = {
|
||||
val sendIntent: Intent = Intent().apply {
|
||||
action = Intent.ACTION_SEND
|
||||
putExtra(Intent.EXTRA_TEXT, "Hey, checkout this excellent Music Downloader http://github.com/Shabinder/SpotiFlyer")
|
||||
type = "text/plain"
|
||||
}
|
||||
|
||||
val shareIntent = Intent.createChooser(sendIntent, null)
|
||||
ctx.startActivity(shareIntent)
|
||||
shareApp()
|
||||
}),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(Icons.Rounded.Share.copy(defaultHeight = 32.dp,defaultWidth = 32.dp))
|
||||
Icon(Icons.Rounded.Share,"Share SpotiFlyer App")
|
||||
Spacer(modifier = Modifier.padding(start = 16.dp))
|
||||
Column {
|
||||
Text(
|
||||
text = stringResource(R.string.share),
|
||||
text = "Share",
|
||||
style = SpotiFlyerTypography.h6
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.share_subtitle),
|
||||
text = "Share this app with your friends and family.",
|
||||
style = SpotiFlyerTypography.subtitle2
|
||||
)
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,15 +34,16 @@ data class TrackDetails(
|
||||
var source: Source,
|
||||
var downloaded: DownloadStatus = DownloadStatus.NotDownloaded,
|
||||
var progress: Int = 2,//2 for visual progress bar hint
|
||||
var outputFile: String,
|
||||
var outputFilePath: String,
|
||||
var videoID:String? = null
|
||||
)
|
||||
|
||||
enum class DownloadStatus{
|
||||
Downloaded,
|
||||
Downloading,
|
||||
Queued,
|
||||
NotDownloaded,
|
||||
Converting,
|
||||
Failed
|
||||
@Serializable
|
||||
sealed class DownloadStatus {
|
||||
object Downloaded :DownloadStatus()
|
||||
data class Downloading(val progress: Int = 0):DownloadStatus()
|
||||
object Queued :DownloadStatus()
|
||||
object NotDownloaded :DownloadStatus()
|
||||
object Converting :DownloadStatus()
|
||||
object Failed :DownloadStatus()
|
||||
}
|
@ -22,13 +22,24 @@ actual fun openPlatform(packageID:String, platformLink:String){
|
||||
}
|
||||
|
||||
actual fun shareApp(){
|
||||
//TODO
|
||||
val sendIntent: Intent = Intent().apply {
|
||||
action = Intent.ACTION_SEND
|
||||
putExtra(Intent.EXTRA_TEXT, "Hey, checkout this excellent Music Downloader http://github.com/Shabinder/SpotiFlyer")
|
||||
type = "text/plain"
|
||||
}
|
||||
|
||||
val shareIntent = Intent.createChooser(sendIntent, null)
|
||||
appContext.startActivity(shareIntent)
|
||||
}
|
||||
|
||||
actual fun giveDonation(){
|
||||
//TODO
|
||||
}
|
||||
|
||||
actual fun downloadTracks(list: List<TrackDetails>){
|
||||
actual suspend fun downloadTracks(
|
||||
list: List<TrackDetails>,
|
||||
getYTIDBestMatch:suspend (String,TrackDetails)->String?,
|
||||
saveFileWithMetaData:suspend (mp3ByteArray:ByteArray, trackDetails: TrackDetails) -> Unit
|
||||
){
|
||||
//TODO
|
||||
}
|
@ -32,7 +32,7 @@ fun Mp3File.setId3v1Tags(track: TrackDetails): Mp3File {
|
||||
}
|
||||
|
||||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
suspend fun Mp3File.setId3v2TagsAndSaveFile(track: TrackDetails, filePath:String){
|
||||
suspend fun Mp3File.setId3v2TagsAndSaveFile(track: TrackDetails){
|
||||
val id3v2Tag = ID3v24Tag().apply {
|
||||
artist = track.artists.joinToString(",")
|
||||
title = track.title
|
||||
@ -50,7 +50,7 @@ suspend fun Mp3File.setId3v2TagsAndSaveFile(track: TrackDetails, filePath:String
|
||||
fis.close()
|
||||
id3v2Tag.setAlbumImage(bytesArray, "image/jpeg")
|
||||
this.id3v2Tag = id3v2Tag
|
||||
saveFile(filePath)
|
||||
saveFile(track.outputFilePath)
|
||||
}catch (e: java.io.FileNotFoundException){
|
||||
try {
|
||||
//Image Still Not Downloaded!
|
||||
@ -61,7 +61,7 @@ suspend fun Mp3File.setId3v2TagsAndSaveFile(track: TrackDetails, filePath:String
|
||||
is DownloadResult.Success -> {
|
||||
id3v2Tag.setAlbumImage(it.byteArray, "image/jpeg")
|
||||
this.id3v2Tag = id3v2Tag
|
||||
saveFile(filePath)
|
||||
saveFile(track.outputFilePath)
|
||||
}
|
||||
is DownloadResult.Progress -> {}//Nothing for Now , no progress bar to show
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ actual class YoutubeProvider actual constructor(
|
||||
else {
|
||||
DownloadStatus.NotDownloaded
|
||||
},
|
||||
outputFile = dir.finalOutputDir(it.title(), folderType, subFolder, dir.defaultDir(),".m4a"),
|
||||
outputFilePath = dir.finalOutputDir(it.title(), folderType, subFolder, dir.defaultDir(),".m4a"),
|
||||
videoID = it.videoId()
|
||||
)
|
||||
}
|
||||
@ -195,7 +195,7 @@ actual class YoutubeProvider actual constructor(
|
||||
else {
|
||||
DownloadStatus.NotDownloaded
|
||||
},
|
||||
outputFile = dir.finalOutputDir(name, folderType, subFolder, dir.defaultDir(),".m4a"),
|
||||
outputFilePath = dir.finalOutputDir(name, folderType, subFolder, dir.defaultDir(),".m4a"),
|
||||
videoID = searchId
|
||||
)
|
||||
)
|
||||
|
@ -33,7 +33,7 @@ fun commonModule(enableNetworkLogs: Boolean) = module {
|
||||
single { SpotifyProvider(get(),get(),get(),get()) }
|
||||
single { GaanaProvider(get(),get(),get(),get()) }
|
||||
single { YoutubeProvider(get(),get(),get(),get()) }
|
||||
single { FetchPlatformQueryResult(get(),get(),get(),get()) }
|
||||
single { FetchPlatformQueryResult(get(),get(),get(),get(),get()) }
|
||||
single { createHttpClient(enableNetworkLogs = enableNetworkLogs) }
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package com.shabinder.common.di
|
||||
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import co.touchlab.kermit.Kermit
|
||||
import com.shabinder.common.di.providers.YoutubeMusic
|
||||
import com.shabinder.common.models.DownloadResult
|
||||
import com.shabinder.common.models.TrackDetails
|
||||
import io.ktor.client.request.*
|
||||
@ -13,7 +14,7 @@ import kotlinx.coroutines.flow.flow
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
expect class Dir(
|
||||
logger: Kermit,
|
||||
logger: Kermit
|
||||
) {
|
||||
fun isPresent(path:String):Boolean
|
||||
fun fileSeparator(): String
|
||||
@ -23,7 +24,7 @@ expect class Dir(
|
||||
suspend fun cacheImage(image: Any,path: String) // in Android = ImageBitmap, Desktop = BufferedImage
|
||||
suspend fun loadImage(url:String): ImageBitmap?
|
||||
suspend fun clearCache()
|
||||
suspend fun saveFileWithMetadata(mp3ByteArray: ByteArray, path: String, trackDetails: TrackDetails)
|
||||
suspend fun saveFileWithMetadata(mp3ByteArray: ByteArray, trackDetails: TrackDetails)
|
||||
}
|
||||
|
||||
suspend fun downloadFile(url: String): Flow<DownloadResult> {
|
||||
|
@ -8,4 +8,8 @@ expect fun shareApp()
|
||||
|
||||
expect fun giveDonation()
|
||||
|
||||
expect fun downloadTracks(list: List<TrackDetails>)
|
||||
expect suspend fun downloadTracks(
|
||||
list: List<TrackDetails>,
|
||||
getYTIDBestMatch:suspend (String,TrackDetails)->String?,
|
||||
saveFileWithMetaData:suspend (mp3ByteArray:ByteArray, trackDetails: TrackDetails) -> Unit
|
||||
)
|
@ -4,6 +4,7 @@ import com.shabinder.common.models.PlatformQueryResult
|
||||
import com.shabinder.common.database.DownloadRecordDatabaseQueries
|
||||
import com.shabinder.common.di.providers.GaanaProvider
|
||||
import com.shabinder.common.di.providers.SpotifyProvider
|
||||
import com.shabinder.common.di.providers.YoutubeMusic
|
||||
import com.shabinder.database.Database
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
@ -12,6 +13,7 @@ class FetchPlatformQueryResult(
|
||||
private val gaanaProvider: GaanaProvider,
|
||||
private val spotifyProvider: SpotifyProvider,
|
||||
private val youtubeProvider: YoutubeProvider,
|
||||
val youtubeMusic: YoutubeMusic,
|
||||
private val database: Database
|
||||
) {
|
||||
private val db:DownloadRecordDatabaseQueries
|
||||
|
@ -1,5 +1,7 @@
|
||||
package com.shabinder.common.di
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Removing Illegal Chars from File Name
|
||||
* **/
|
||||
|
@ -220,7 +220,7 @@ class GaanaProvider(
|
||||
downloaded = it.downloaded ?: DownloadStatus.NotDownloaded,
|
||||
source = Source.Gaana,
|
||||
albumArtURL = it.artworkLink,
|
||||
outputFile = dir.finalOutputDir(it.track_title,type, subFolder,dir.defaultDir(),".m4a")
|
||||
outputFilePath = dir.finalOutputDir(it.track_title,type, subFolder,dir.defaultDir(),".m4a")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import com.shabinder.common.di.TokenStore
|
||||
import com.shabinder.common.di.finalOutputDir
|
||||
import com.shabinder.common.di.kotlinxSerializer
|
||||
import com.shabinder.common.di.spotify.SpotifyRequests
|
||||
import com.shabinder.common.di.spotify.authenticateSpotify
|
||||
import com.shabinder.common.models.PlatformQueryResult
|
||||
import com.shabinder.common.models.TrackDetails
|
||||
import com.shabinder.common.models.spotify.Album
|
||||
@ -35,7 +34,6 @@ import io.ktor.client.*
|
||||
import io.ktor.client.features.*
|
||||
import io.ktor.client.features.json.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.http.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
@ -273,7 +271,7 @@ class SpotifyProvider(
|
||||
downloaded = it.downloaded,
|
||||
source = Source.Spotify,
|
||||
albumArtURL = it.album?.images?.elementAtOrNull(1)?.url ?: it.album?.images?.firstOrNull()?.url.toString(),
|
||||
outputFile = dir.finalOutputDir(it.name.toString(),type, subFolder,dir.defaultDir(),".m4a")
|
||||
outputFilePath = dir.finalOutputDir(it.name.toString(),type, subFolder,dir.defaultDir(),".m4a")
|
||||
)
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package com.shabinder.common.di.providers
|
||||
|
||||
import co.touchlab.kermit.Logger
|
||||
import com.shabinder.common.models.TrackDetails
|
||||
import com.shabinder.common.models.YoutubeTrack
|
||||
import com.willowtreeapps.fuzzywuzzy.diffutils.FuzzySearch
|
||||
import io.ktor.client.*
|
||||
@ -16,6 +17,15 @@ class YoutubeMusic constructor(
|
||||
private val httpClient:HttpClient,
|
||||
) {
|
||||
private val tag = "YT Music"
|
||||
|
||||
suspend fun getYTIDBestMatch(query: String,trackDetails: TrackDetails):String?{
|
||||
return sortByBestMatch(
|
||||
getYTTracks(query),
|
||||
trackName = trackDetails.title,
|
||||
trackArtists = trackDetails.artists,
|
||||
trackDurationSec = trackDetails.durationSec
|
||||
).keys.firstOrNull()
|
||||
}
|
||||
suspend fun getYTTracks(query: String):List<YoutubeTrack>{
|
||||
val youtubeTracks = mutableListOf<YoutubeTrack>()
|
||||
|
||||
|
@ -1,6 +1,16 @@
|
||||
package com.shabinder.common.di
|
||||
|
||||
import com.github.kiulian.downloader.YoutubeDownloader
|
||||
import com.github.kiulian.downloader.model.YoutubeVideo
|
||||
import com.github.kiulian.downloader.model.formats.Format
|
||||
import com.github.kiulian.downloader.model.quality.AudioQuality
|
||||
import com.shabinder.common.models.DownloadResult
|
||||
import com.shabinder.common.models.DownloadStatus
|
||||
import com.shabinder.common.models.TrackDetails
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
actual fun openPlatform(packageID:String, platformLink:String){
|
||||
//TODO
|
||||
@ -14,6 +24,71 @@ actual fun giveDonation(){
|
||||
//TODO
|
||||
}
|
||||
|
||||
actual fun downloadTracks(list: List<TrackDetails>){
|
||||
//TODO
|
||||
val DownloadProgressFlow = MutableStateFlow(Pair<String,DownloadStatus>("",DownloadStatus.Queued))
|
||||
|
||||
actual suspend fun downloadTracks(
|
||||
list: List<TrackDetails>,
|
||||
getYTIDBestMatch:suspend (String,TrackDetails)->String?,
|
||||
saveFileWithMetaData:suspend (mp3ByteArray:ByteArray, trackDetails: TrackDetails) -> Unit
|
||||
){
|
||||
list.forEach {
|
||||
if (!it.videoID.isNullOrBlank()) {//Video ID already known!
|
||||
downloadTrack(it.videoID!!, it,saveFileWithMetaData)
|
||||
} else {
|
||||
val searchQuery = "${it.title} - ${it.artists.joinToString(",")}"
|
||||
val videoId = getYTIDBestMatch(searchQuery,it)
|
||||
if (videoId.isNullOrBlank()) {
|
||||
DownloadProgressFlow.emit(Pair(it.title,DownloadStatus.Failed))
|
||||
} else {//Found Youtube Video ID
|
||||
downloadTrack(videoId, it,saveFileWithMetaData)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val ytDownloader = YoutubeDownloader()
|
||||
|
||||
suspend fun downloadTrack(
|
||||
videoID: String,
|
||||
trackDetails: TrackDetails,
|
||||
saveFileWithMetaData:suspend (mp3ByteArray:ByteArray, trackDetails: TrackDetails) -> Unit
|
||||
) {
|
||||
try {
|
||||
val audioData = ytDownloader.getVideo(videoID).getData()
|
||||
|
||||
audioData?.let { format ->
|
||||
val url: String = format.url()
|
||||
downloadFile(url).collect {
|
||||
when(it){
|
||||
is DownloadResult.Error -> {
|
||||
//TODO()
|
||||
}
|
||||
is DownloadResult.Progress -> {
|
||||
DownloadProgressFlow.emit(Pair(trackDetails.title,DownloadStatus.Downloading(it.progress)))
|
||||
}
|
||||
is DownloadResult.Success -> {
|
||||
saveFileWithMetaData(it.byteArray,trackDetails)
|
||||
DownloadProgressFlow.emit(Pair(trackDetails.title,DownloadStatus.Downloaded))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (e: java.lang.Exception){
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
fun YoutubeVideo.getData(): Format?{
|
||||
return try {
|
||||
findAudioWithQuality(AudioQuality.medium)?.get(0) as Format
|
||||
} catch (e: java.lang.IndexOutOfBoundsException) {
|
||||
try {
|
||||
findAudioWithQuality(AudioQuality.high)?.get(0) as Format
|
||||
} catch (e: java.lang.IndexOutOfBoundsException) {
|
||||
try {
|
||||
findAudioWithQuality(AudioQuality.low)?.get(0) as Format
|
||||
} catch (e: java.lang.IndexOutOfBoundsException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -61,16 +61,15 @@ actual class Dir actual constructor(private val logger: Kermit) {
|
||||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
actual suspend fun saveFileWithMetadata(
|
||||
mp3ByteArray: ByteArray,
|
||||
path: String,
|
||||
trackDetails: TrackDetails
|
||||
) {
|
||||
val file = File(path)
|
||||
val file = File(trackDetails.outputFilePath)
|
||||
file.writeBytes(mp3ByteArray)
|
||||
|
||||
Mp3File(file)
|
||||
.removeAllTags()
|
||||
.setId3v1Tags(trackDetails)
|
||||
.setId3v2TagsAndSaveFile(trackDetails,path)
|
||||
.setId3v2TagsAndSaveFile(trackDetails)
|
||||
}
|
||||
|
||||
actual suspend fun loadImage(url: String): ImageBitmap? {
|
@ -33,7 +33,7 @@ fun Mp3File.setId3v1Tags(track: TrackDetails): Mp3File {
|
||||
}
|
||||
|
||||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
suspend fun Mp3File.setId3v2TagsAndSaveFile(track: TrackDetails, filePath:String){
|
||||
suspend fun Mp3File.setId3v2TagsAndSaveFile(track: TrackDetails){
|
||||
val id3v2Tag = ID3v24Tag().apply {
|
||||
artist = track.artists.joinToString(",")
|
||||
title = track.title
|
||||
@ -51,7 +51,7 @@ suspend fun Mp3File.setId3v2TagsAndSaveFile(track: TrackDetails, filePath:String
|
||||
fis.close()
|
||||
id3v2Tag.setAlbumImage(bytesArray, "image/jpeg")
|
||||
this.id3v2Tag = id3v2Tag
|
||||
saveFile(filePath)
|
||||
saveFile(track.outputFilePath)
|
||||
}catch (e: java.io.FileNotFoundException){
|
||||
try {
|
||||
//Image Still Not Downloaded!
|
||||
@ -62,7 +62,7 @@ suspend fun Mp3File.setId3v2TagsAndSaveFile(track: TrackDetails, filePath:String
|
||||
is DownloadResult.Success -> {
|
||||
id3v2Tag.setAlbumImage(it.byteArray, "image/jpeg")
|
||||
this.id3v2Tag = id3v2Tag
|
||||
saveFile(filePath)
|
||||
saveFile(track.outputFilePath)
|
||||
}
|
||||
is DownloadResult.Progress -> {}//Nothing for Now , no progress bar to show
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ actual class YoutubeProvider actual constructor(
|
||||
else {
|
||||
DownloadStatus.NotDownloaded
|
||||
},
|
||||
outputFile = dir.finalOutputDir(it.title(), folderType, subFolder, dir.defaultDir(),".m4a"),
|
||||
outputFilePath = dir.finalOutputDir(it.title(), folderType, subFolder, dir.defaultDir(),".m4a"),
|
||||
videoID = it.videoId()
|
||||
)
|
||||
}
|
||||
@ -196,7 +196,7 @@ actual class YoutubeProvider actual constructor(
|
||||
else {
|
||||
DownloadStatus.NotDownloaded
|
||||
},
|
||||
outputFile = dir.finalOutputDir(name, folderType, subFolder, dir.defaultDir(),".m4a"),
|
||||
outputFilePath = dir.finalOutputDir(name, folderType, subFolder, dir.defaultDir(),".m4a"),
|
||||
videoID = searchId
|
||||
)
|
||||
)
|
||||
|
@ -21,6 +21,6 @@
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M12,4c4.41,0 8,3.59 8,8s-3.59,8 -8,8s-8,-3.59 -8,-8S7.59,4 12,4M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10c5.52,0 10,-4.48 10,-10C22,6.48 17.52,2 12,2L12,2zM13,12l0,-4h-2l0,4H8l4,4l4,-4H13z"/>
|
||||
</vector>
|
||||
|
Loading…
Reference in New Issue
Block a user