mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-22 17:14:32 +01:00
File less than 100kb Bug fix
This commit is contained in:
parent
8e32d4469b
commit
07285782a1
@ -193,7 +193,12 @@ class ForegroundService : LifecycleService() {
|
|||||||
dir.saveFileWithMetadata(
|
dir.saveFileWithMetadata(
|
||||||
it.byteArray,
|
it.byteArray,
|
||||||
track
|
track
|
||||||
) {}
|
).fold(
|
||||||
|
failure = { throwable ->
|
||||||
|
throwable.printStackTrace()
|
||||||
|
throw throwable
|
||||||
|
}, success = {}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send Converting Status
|
// Send Converting Status
|
||||||
@ -352,7 +357,7 @@ class ForegroundService : LifecycleService() {
|
|||||||
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
mNotificationManager.notify(NOTIFICATION_ID, createNotification())
|
mNotificationManager.notify(NOTIFICATION_ID, createNotification())
|
||||||
} else {
|
} else {
|
||||||
// Service is Inactive so clear status
|
// Service is Inactive so clear residual status
|
||||||
resetVar()
|
resetVar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ import com.shabinder.common.models.dispatcherIO
|
|||||||
import com.shabinder.common.models.event.coroutines.SuspendableEvent
|
import com.shabinder.common.models.event.coroutines.SuspendableEvent
|
||||||
import com.shabinder.common.models.event.coroutines.map
|
import com.shabinder.common.models.event.coroutines.map
|
||||||
import com.shabinder.common.models.Actions
|
import com.shabinder.common.models.Actions
|
||||||
|
import com.shabinder.common.models.AudioFormat
|
||||||
import com.shabinder.database.Database
|
import com.shabinder.database.Database
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@ -116,6 +117,9 @@ class AndroidFileManager(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Add Mp3 Tags and Add to Library
|
// Add Mp3 Tags and Add to Library
|
||||||
|
if(trackDetails.audioFormat != AudioFormat.MP3)
|
||||||
|
throw InvalidDataException("Audio Format is ${trackDetails.audioFormat}, Needs Conversion!")
|
||||||
|
|
||||||
Mp3File(File(songFile.absolutePath))
|
Mp3File(File(songFile.absolutePath))
|
||||||
.removeAllTags()
|
.removeAllTags()
|
||||||
.setId3v1Tags(trackDetails)
|
.setId3v1Tags(trackDetails)
|
||||||
|
@ -40,6 +40,7 @@ class AndroidMediaConverter(private val appContext: Context) : MediaConverter()
|
|||||||
override fun onSuccess(message: String?) {
|
override fun onSuccess(message: String?) {
|
||||||
//Log.d("FFmpeg Command", "Success $message")
|
//Log.d("FFmpeg Command", "Success $message")
|
||||||
progressing = false
|
progressing = false
|
||||||
|
Log.d("FFmpeg Success", "$message")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onProgress(message: String?) {
|
override fun onProgress(message: String?) {
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.shabinder.common.models
|
||||||
|
|
||||||
|
enum class AudioFormat {
|
||||||
|
MP3, MP4, FLAC, UNKNOWN
|
||||||
|
}
|
@ -42,6 +42,7 @@ data class TrackDetails(
|
|||||||
val downloadLink: String? = null,
|
val downloadLink: String? = null,
|
||||||
val downloaded: DownloadStatus = DownloadStatus.NotDownloaded,
|
val downloaded: DownloadStatus = DownloadStatus.NotDownloaded,
|
||||||
var audioQuality: AudioQuality = AudioQuality.KBPS192,
|
var audioQuality: AudioQuality = AudioQuality.KBPS192,
|
||||||
|
var audioFormat: AudioFormat = AudioFormat.MP4,
|
||||||
var outputFilePath: String, // UriString in Android
|
var outputFilePath: String, // UriString in Android
|
||||||
var videoID: String? = null,
|
var videoID: String? = null,
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
package com.shabinder.common.models.event.coroutines
|
package com.shabinder.common.models.event.coroutines
|
||||||
|
|
||||||
|
import kotlin.contracts.ExperimentalContracts
|
||||||
|
import kotlin.contracts.InvocationKind
|
||||||
|
import kotlin.contracts.contract
|
||||||
import kotlin.properties.ReadOnlyProperty
|
import kotlin.properties.ReadOnlyProperty
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
@ -77,6 +80,22 @@ suspend inline fun <V : Any?, E : Throwable, E2 : Throwable> SuspendableEvent<V,
|
|||||||
SuspendableEvent.error(ex as E)
|
SuspendableEvent.error(ex as E)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend inline fun <V, E : Throwable> SuspendableEvent<V, E>.onSuccess(crossinline f: suspend (V) -> Unit): SuspendableEvent<V, E> {
|
||||||
|
contract {
|
||||||
|
callsInPlace(f, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return fold({ f(it); this }, { this })
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
suspend inline fun <V, E : Throwable> SuspendableEvent<V, E>.onFailure(crossinline f: suspend (E) -> Unit): SuspendableEvent<V, E> {
|
||||||
|
contract {
|
||||||
|
callsInPlace(f, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
return fold({ this }, { f(it); this })
|
||||||
|
}
|
||||||
|
|
||||||
suspend inline fun <V : Any?, E : Throwable> SuspendableEvent<V, E>.any(
|
suspend inline fun <V : Any?, E : Throwable> SuspendableEvent<V, E>.any(
|
||||||
crossinline predicate: suspend (V) -> Boolean
|
crossinline predicate: suspend (V) -> Boolean
|
||||||
): Boolean = try {
|
): Boolean = try {
|
||||||
|
@ -23,6 +23,7 @@ import com.shabinder.common.database.DownloadRecordDatabaseQueries
|
|||||||
import com.shabinder.common.models.*
|
import com.shabinder.common.models.*
|
||||||
import com.shabinder.common.models.event.coroutines.SuspendableEvent
|
import com.shabinder.common.models.event.coroutines.SuspendableEvent
|
||||||
import com.shabinder.common.models.event.coroutines.flatMapError
|
import com.shabinder.common.models.event.coroutines.flatMapError
|
||||||
|
import com.shabinder.common.models.event.coroutines.onSuccess
|
||||||
import com.shabinder.common.models.event.coroutines.success
|
import com.shabinder.common.models.event.coroutines.success
|
||||||
import com.shabinder.common.models.spotify.Source
|
import com.shabinder.common.models.spotify.Source
|
||||||
import com.shabinder.common.providers.gaana.GaanaProvider
|
import com.shabinder.common.providers.gaana.GaanaProvider
|
||||||
@ -94,12 +95,14 @@ class FetchPlatformQueryResult(
|
|||||||
): SuspendableEvent<Pair<String, AudioQuality>, Throwable> {
|
): SuspendableEvent<Pair<String, AudioQuality>, Throwable> {
|
||||||
var downloadLink: String? = null
|
var downloadLink: String? = null
|
||||||
var audioQuality = AudioQuality.KBPS192
|
var audioQuality = AudioQuality.KBPS192
|
||||||
|
var audioFormat = AudioFormat.MP4
|
||||||
|
|
||||||
val errorTrace = buildString(track) {
|
val errorTrace = buildString(track) {
|
||||||
if (track.videoID != null) {
|
if (track.videoID != null) {
|
||||||
// We Already have VideoID
|
// We Already have VideoID
|
||||||
downloadLink = when (track.source) {
|
downloadLink = when (track.source) {
|
||||||
Source.JioSaavn -> {
|
Source.JioSaavn -> {
|
||||||
|
AudioFormat.MP4
|
||||||
saavnProvider.getSongFromID(track.videoID.requireNotNull()).component1()
|
saavnProvider.getSongFromID(track.videoID.requireNotNull()).component1()
|
||||||
?.also { audioQuality = it.audioQuality }
|
?.also { audioQuality = it.audioQuality }
|
||||||
?.media_url
|
?.media_url
|
||||||
@ -109,19 +112,23 @@ class FetchPlatformQueryResult(
|
|||||||
track.videoID.requireNotNull(),
|
track.videoID.requireNotNull(),
|
||||||
preferredQuality
|
preferredQuality
|
||||||
).let { ytMp3Link ->
|
).let { ytMp3Link ->
|
||||||
if (ytMp3Link is SuspendableEvent.Failure || ytMp3Link.component1()
|
if (
|
||||||
.isNullOrBlank()
|
ytMp3Link is SuspendableEvent.Failure
|
||||||
) {
|
||
|
||||||
appendPadded(
|
ytMp3Link.component1().isNullOrBlank()
|
||||||
"Yt1sMp3 Failed for ${track.videoID}:",
|
) {
|
||||||
ytMp3Link.component2()
|
appendPadded(
|
||||||
?: "couldn't fetch link for ${track.videoID} ,trying manual extraction"
|
"Yt1sMp3 Failed for ${track.videoID}:",
|
||||||
)
|
ytMp3Link.component2()?.stackTraceToString()
|
||||||
appendLine("Trying Local Extraction")
|
?: "couldn't fetch link for ${track.videoID} ,trying manual extraction"
|
||||||
youtubeProvider.ytDownloader.getVideo(track.videoID!!)
|
)
|
||||||
.get()?.url
|
appendLine("Trying Local Extraction")
|
||||||
} else ytMp3Link.component1()
|
null
|
||||||
|
} else {
|
||||||
|
audioFormat = AudioFormat.MP3
|
||||||
|
ytMp3Link.component1()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
appendPadded(
|
appendPadded(
|
||||||
@ -141,7 +148,7 @@ class FetchPlatformQueryResult(
|
|||||||
trackName = track.title,
|
trackName = track.title,
|
||||||
trackArtists = track.artists,
|
trackArtists = track.artists,
|
||||||
preferredQuality = preferredQuality
|
preferredQuality = preferredQuality
|
||||||
).flatMapError { saavnError ->
|
).onSuccess { audioFormat = AudioFormat.MP4 }.flatMapError { saavnError ->
|
||||||
appendPadded("Fetching From Saavn Failed:", saavnError.stackTraceToString())
|
appendPadded("Fetching From Saavn Failed:", saavnError.stackTraceToString())
|
||||||
// Saavn Failed, Lets Try Fetching Now From Youtube Music
|
// Saavn Failed, Lets Try Fetching Now From Youtube Music
|
||||||
youtubeMusic.findMp3SongDownloadURLYT(track, preferredQuality).also {
|
youtubeMusic.findMp3SongDownloadURLYT(track, preferredQuality).also {
|
||||||
@ -151,6 +158,7 @@ class FetchPlatformQueryResult(
|
|||||||
"Fetching From YT-Music Failed:",
|
"Fetching From YT-Music Failed:",
|
||||||
it.component2()?.stackTraceToString()
|
it.component2()?.stackTraceToString()
|
||||||
)
|
)
|
||||||
|
else audioFormat = AudioFormat.MP3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +170,10 @@ class FetchPlatformQueryResult(
|
|||||||
}
|
}
|
||||||
return if (downloadLink.isNullOrBlank()) SuspendableEvent.error(
|
return if (downloadLink.isNullOrBlank()) SuspendableEvent.error(
|
||||||
SpotiFlyerException.DownloadLinkFetchFailed(errorTrace)
|
SpotiFlyerException.DownloadLinkFetchFailed(errorTrace)
|
||||||
) else SuspendableEvent.success(Pair(downloadLink.requireNotNull(),audioQuality))
|
) else {
|
||||||
|
track.audioFormat = audioFormat
|
||||||
|
SuspendableEvent.success(Pair(downloadLink.requireNotNull(), audioQuality))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(DelicateCoroutinesApi::class)
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
|
@ -58,7 +58,7 @@ class YoutubeMusic constructor(
|
|||||||
?: 0) > 192
|
?: 0) > 192
|
||||||
) AudioQuality.KBPS192 else preferredQuality
|
) AudioQuality.KBPS192 else preferredQuality
|
||||||
// 1 Try getting Link from Yt1s
|
// 1 Try getting Link from Yt1s
|
||||||
youtubeMp3.getMp3DownloadLink(videoID, optimalQuality).flatMapError {
|
youtubeMp3.getMp3DownloadLink(videoID, optimalQuality)/*.flatMapError {
|
||||||
// 2 if Yt1s failed , Extract Manually
|
// 2 if Yt1s failed , Extract Manually
|
||||||
SuspendableEvent {
|
SuspendableEvent {
|
||||||
youtubeProvider.ytDownloader.getVideo(videoID).get()?.url
|
youtubeProvider.ytDownloader.getVideo(videoID).get()?.url
|
||||||
@ -67,7 +67,8 @@ class YoutubeMusic constructor(
|
|||||||
message = "Caught Following Errors While Finding Downloadable Link for $videoID : \n${it.stackTraceToString()}"
|
message = "Caught Following Errors While Finding Downloadable Link for $videoID : \n${it.stackTraceToString()}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}.map {
|
}*/.map {
|
||||||
|
trackDetails.audioFormat = AudioFormat.MP3
|
||||||
Pair(it,optimalQuality)
|
Pair(it,optimalQuality)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user