mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-22 17:14:32 +01:00
Online M4a Converter (WIP)
This commit is contained in:
parent
ac209e8509
commit
ec8f77d121
@ -22,6 +22,8 @@ dependencies {
|
|||||||
implementation("org.jetbrains.kotlin:kotlin-reflect:${Versions.kotlinVersion}")
|
implementation("org.jetbrains.kotlin:kotlin-reflect:${Versions.kotlinVersion}")
|
||||||
implementation("io.ktor:ktor-client-core:1.5.4")
|
implementation("io.ktor:ktor-client-core:1.5.4")
|
||||||
implementation("io.ktor:ktor-client-apache:1.5.4")
|
implementation("io.ktor:ktor-client-apache:1.5.4")
|
||||||
|
implementation("io.ktor:ktor-client-logging:1.5.4")
|
||||||
|
implementation(Ktor.slf4j)
|
||||||
implementation("io.ktor:ktor-client-serialization:1.5.4")
|
implementation("io.ktor:ktor-client-serialization:1.5.4")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.1")
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.1")
|
||||||
// testDeps
|
// testDeps
|
||||||
|
@ -6,6 +6,10 @@ import io.ktor.client.HttpClient
|
|||||||
import io.ktor.client.features.HttpTimeout
|
import io.ktor.client.features.HttpTimeout
|
||||||
import io.ktor.client.features.json.JsonFeature
|
import io.ktor.client.features.json.JsonFeature
|
||||||
import io.ktor.client.features.json.serializer.KotlinxSerializer
|
import io.ktor.client.features.json.serializer.KotlinxSerializer
|
||||||
|
import io.ktor.client.features.logging.DEFAULT
|
||||||
|
import io.ktor.client.features.logging.LogLevel
|
||||||
|
import io.ktor.client.features.logging.Logger
|
||||||
|
import io.ktor.client.features.logging.Logging
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
internal object Common {
|
internal object Common {
|
||||||
@ -24,6 +28,10 @@ internal val client = HttpClient {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
install(Logging) {
|
||||||
|
logger = Logger.DEFAULT
|
||||||
|
level = LogLevel.INFO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
internal data class GithubFileContent(
|
internal data class GithubFileContent(
|
||||||
val decryptedContent: String,
|
val decryptedContent: String,
|
||||||
|
116
maintenance-tasks/src/main/java/audio_conversion/AudioToMp3.kt
Normal file
116
maintenance-tasks/src/main/java/audio_conversion/AudioToMp3.kt
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
package audio_conversion
|
||||||
|
|
||||||
|
import analytics_html_img.client
|
||||||
|
import io.ktor.client.request.forms.formData
|
||||||
|
import io.ktor.client.request.forms.submitFormWithBinaryData
|
||||||
|
import io.ktor.client.request.get
|
||||||
|
import io.ktor.client.request.header
|
||||||
|
import io.ktor.client.request.headers
|
||||||
|
import io.ktor.client.statement.HttpStatement
|
||||||
|
import io.ktor.http.isSuccess
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import utils.debug
|
||||||
|
|
||||||
|
interface AudioToMp3 {
|
||||||
|
|
||||||
|
@Suppress("EnumEntryName")
|
||||||
|
enum class Quality(val kbps: String) {
|
||||||
|
`128KBPS`("128"),
|
||||||
|
`160KBPS`("160"),
|
||||||
|
`192KBPS`("192"),
|
||||||
|
`224KBPS`("224"),
|
||||||
|
`256KBPS`("256"),
|
||||||
|
`320KBPS`("320"),
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun convertToMp3(
|
||||||
|
URL: String,
|
||||||
|
quality: Quality = kotlin.runCatching { Quality.valueOf(URL.substringBeforeLast(".").takeLast(3)) }.getOrNull() ?: Quality.`160KBPS`,
|
||||||
|
): String? {
|
||||||
|
val activeHost = getHost() // ex - https://hostveryfast.onlineconverter.com/file/send
|
||||||
|
val jobLink = convertRequest(URL, activeHost, quality) // ex - https://www.onlineconverter.com/convert/309a0f2bbaeb5687b04f96b6d65b47bfdd
|
||||||
|
|
||||||
|
// (jobStatus = "d") == COMPLETION
|
||||||
|
var jobStatus: String
|
||||||
|
var retryCount = 20
|
||||||
|
|
||||||
|
do {
|
||||||
|
jobStatus = try {
|
||||||
|
client.get<String>(
|
||||||
|
"${activeHost.removeSuffix("send")}${jobLink.substringAfterLast("/")}"
|
||||||
|
)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
""
|
||||||
|
}
|
||||||
|
retryCount--
|
||||||
|
debug("Job Status", jobStatus)
|
||||||
|
if (!jobStatus.contains("d")) delay(200) // Add Delay , to give Server Time to process audio
|
||||||
|
} while (!jobStatus.contains("d", true) && retryCount != 0)
|
||||||
|
|
||||||
|
return if (jobStatus.equals("d", true)) {
|
||||||
|
// Return MP3 Download Link
|
||||||
|
"${activeHost.removeSuffix("send")}${jobLink.substringAfterLast("/")}/download"
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Response Link Ex : `https://www.onlineconverter.com/convert/11affb6d88d31861fe5bcd33da7b10a26c`
|
||||||
|
* - to start the conversion
|
||||||
|
* */
|
||||||
|
private suspend fun convertRequest(
|
||||||
|
URL: String,
|
||||||
|
host: String? = null,
|
||||||
|
quality: Quality = Quality.`320KBPS`,
|
||||||
|
): String {
|
||||||
|
val activeHost = host ?: getHost()
|
||||||
|
val res = client.submitFormWithBinaryData<String>(
|
||||||
|
url = activeHost,
|
||||||
|
formData = formData {
|
||||||
|
append("class", "audio")
|
||||||
|
append("from", "audio")
|
||||||
|
append("to", "mp3")
|
||||||
|
append("source", "url")
|
||||||
|
append("url", URL.replace("https:", "http:"))
|
||||||
|
append("audio_quality", quality.kbps)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
headers {
|
||||||
|
header("Host", activeHost.getHostURL().also { debug(it) })
|
||||||
|
header("Origin", "https://www.onlineconverter.com")
|
||||||
|
header("Referer", "https://www.onlineconverter.com/")
|
||||||
|
}
|
||||||
|
}.run {
|
||||||
|
debug(this)
|
||||||
|
dropLast(3) // last 3 are useless unicode char
|
||||||
|
}
|
||||||
|
|
||||||
|
val job = client.get<HttpStatement>(res) {
|
||||||
|
headers {
|
||||||
|
header("Host", "www.onlineconverter.com")
|
||||||
|
}
|
||||||
|
}.execute()
|
||||||
|
debug("Schedule Job ${job.status.isSuccess()}")
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun getHost(): String {
|
||||||
|
return client.get<String>("https://www.onlineconverter.com/get/host") {
|
||||||
|
headers {
|
||||||
|
header("Host", "www.onlineconverter.com")
|
||||||
|
}
|
||||||
|
}.also { debug("Active Host", it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String.getHostURL(): String {
|
||||||
|
return this.removePrefix("https://").substringBeforeLast(".") + "." + this.substringAfterLast(".").substringBefore("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val serializer = Json {
|
||||||
|
ignoreUnknownKeys = true
|
||||||
|
isLenient = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -56,6 +56,14 @@ interface JioSaavnRequests {
|
|||||||
.formatData(fetchLyrics)
|
.formatData(fetchLyrics)
|
||||||
return serializer.decodeFromJsonElement(SaavnSong.serializer(), data)
|
return serializer.decodeFromJsonElement(SaavnSong.serializer(), data)
|
||||||
}
|
}
|
||||||
|
suspend fun getSongFromID(
|
||||||
|
ID: String,
|
||||||
|
fetchLyrics: Boolean = false
|
||||||
|
): SaavnSong {
|
||||||
|
val data = ((serializer.parseToJsonElement(client.get(song_details_base_url + ID)) as JsonObject)[ID] as JsonObject)
|
||||||
|
.formatData(fetchLyrics)
|
||||||
|
return serializer.decodeFromJsonElement(SaavnSong.serializer(), data)
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun getSongID(
|
private suspend fun getSongID(
|
||||||
URL: String,
|
URL: String,
|
||||||
|
@ -1,24 +1,33 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
|
import audio_conversion.AudioToMp3
|
||||||
import io.github.shabinder.fuzzywuzzy.diffutils.FuzzySearch
|
import io.github.shabinder.fuzzywuzzy.diffutils.FuzzySearch
|
||||||
import jiosaavn.JioSaavnRequests
|
|
||||||
import jiosaavn.models.SaavnSearchResult
|
import jiosaavn.models.SaavnSearchResult
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
// Test Class- at development Time
|
// Test Class- at development Time
|
||||||
fun main(): Unit = runBlocking {
|
fun main(): Unit = runBlocking {
|
||||||
val jioSaavnClient = object : JioSaavnRequests {}
|
/*val jioSaavnClient = object : JioSaavnRequests {}
|
||||||
val resp = jioSaavnClient.searchForSong(
|
val resp = jioSaavnClient.searchForSong(
|
||||||
query = "Filhall"
|
query = "Ye Faasla"
|
||||||
)
|
)
|
||||||
println(resp.joinToString("\n"))
|
println(resp.joinToString("\n"))
|
||||||
|
|
||||||
val matches = sortByBestMatch(
|
val matches = sortByBestMatch(
|
||||||
tracks = resp,
|
tracks = resp,
|
||||||
trackName = "Filhall",
|
trackName = "Ye Faasla",
|
||||||
trackArtists = listOf("B.Praak", "Nupur Sanon")
|
trackArtists = listOf("Shaan", "Hardy")
|
||||||
)
|
)
|
||||||
debug(matches.toString())
|
debug(matches.toString())
|
||||||
|
|
||||||
|
val link = matches.keys.firstOrNull()?.let {
|
||||||
|
jioSaavnClient.getSongFromID(it).media_url
|
||||||
|
}
|
||||||
|
debug(link.toString())*/
|
||||||
|
val link = "https://aac.saavncdn.com/787/956c23404206e8f4822827eff5da61a0_320.mp4"
|
||||||
|
val audioConverter = object : AudioToMp3 {}
|
||||||
|
val mp3Link = audioConverter.convertToMp3(link.toString())
|
||||||
|
debug(mp3Link.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sortByBestMatch(
|
private fun sortByBestMatch(
|
||||||
|
Loading…
Reference in New Issue
Block a user