Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Commit 34e565c

Browse files
committed
Delete YouTube URL matcher
1 parent 1515f61 commit 34e565c

File tree

3 files changed

+49
-73
lines changed

3 files changed

+49
-73
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Then, add dependencies in app level build.gradle:
3636

3737
```kotlin
3838
dependencies {
39-
implementation 'com.github.maxrave-dev:kotlin-youtubeExtractor:0.0.6'
39+
implementation 'com.github.maxrave-dev:kotlin-youtubeExtractor:0.0.7'
4040
}
4141
```
4242

kotlinYoutubeExtractor/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ plugins {
44
id 'maven-publish'
55
}
66
group = 'com.github.maxrave-dev'
7-
version = '0.0.6'
7+
version = '0.0.7'
88

99
android {
1010
namespace 'com.maxrave.kotlinyoutubeextractor'
@@ -59,7 +59,7 @@ afterEvaluate {
5959
from components.release
6060
groupId = 'com.github.maxrave-dev'
6161
artifactId = 'kotlin-youtubeExtractor'
62-
version = '0.0.6'
62+
version = '0.0.7'
6363
}
6464
}
6565
}

kotlinYoutubeExtractor/src/main/java/com/maxrave/kotlinyoutubeextractor/YTExtractor.kt

Lines changed: 46 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,6 @@ class YTExtractor(val con: Context, val CACHING: Boolean = false, val LOGGING: B
6565
"Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"
6666
//Old User Agent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.98 Safari/537.36"
6767

68-
private val patYouTubePageLink =
69-
Pattern.compile("(http|https)://(www\\.|m.|)youtube\\.com/watch\\?v=(.+?)( |\\z|&)")
70-
private val patYouTubeShortLink =
71-
Pattern.compile("(http|https)://(www\\.|)youtu.be/(.+?)( |\\z|&)")
72-
7368
private val patPlayerResponse =
7469
Pattern.compile("var ytInitialPlayerResponse\\s*=\\s*(\\{.+?\\})\\s*;")
7570
private val patSigEncUrl = Pattern.compile("url=(.+?)(\\u0026|$)")
@@ -321,7 +316,7 @@ class YTExtractor(val con: Context, val CACHING: Boolean = false, val LOGGING: B
321316
if (!mat.find()) mat =
322317
patDecryptionJsFileWithoutSlash.matcher(pageHtml)
323318
if (mat.find()) {
324-
curJsFileName = mat.group(0).replace("\\/", "/")
319+
curJsFileName = mat.group(0)!!.replace("\\/", "/")
325320
if (decipherJsFileName == null || decipherJsFileName != curJsFileName) {
326321
decipherFunctions = null
327322
decipherFunctionName = null
@@ -332,7 +327,6 @@ class YTExtractor(val con: Context, val CACHING: Boolean = false, val LOGGING: B
332327
LOG_TAG,
333328
"Decipher signatures: " + encSignatures.size() + ", videos: " + ytFiles.size()
334329
)
335-
val signature: String?
336330
decipheredSignature = null
337331
if (decipherSignature(encSignatures)) {
338332
lock.lock()
@@ -342,7 +336,7 @@ class YTExtractor(val con: Context, val CACHING: Boolean = false, val LOGGING: B
342336
lock.unlock()
343337
}
344338
}
345-
signature = decipheredSignature
339+
val signature: String? = decipheredSignature
346340
if (signature == null) {
347341
return null
348342
} else {
@@ -417,7 +411,7 @@ class YTExtractor(val con: Context, val CACHING: Boolean = false, val LOGGING: B
417411
decipherFunctionName = mat.group(1)
418412
if (LOGGING) Log.d(
419413
LOG_TAG,
420-
"Decipher Functname: " + decipherFunctionName
414+
"Decipher Functname: $decipherFunctionName"
421415
)
422416
val patMainVariable = Pattern.compile(
423417
"(var |\\s|,|;)" + decipherFunctionName?.replace("$", "\\$") +
@@ -460,18 +454,18 @@ class YTExtractor(val con: Context, val CACHING: Boolean = false, val LOGGING: B
460454
continue
461455
}
462456
startIndex = javascriptFile.indexOf(variableDef) + variableDef.length
463-
var braces = 1
464-
var i = startIndex
465-
while (i < javascriptFile.length) {
466-
if (braces == 0) {
457+
var bracesVariable = 1
458+
var i1 = startIndex
459+
while (i1 < javascriptFile.length) {
460+
if (bracesVariable == 0) {
467461
decipherFunctions += variableDef + javascriptFile.substring(
468462
startIndex,
469-
i
463+
i1
470464
) + ";"
471465
break
472466
}
473-
if (javascriptFile[i] == '{') braces++ else if (javascriptFile[i] == '}') braces--
474-
i++
467+
if (javascriptFile[i1] == '{') bracesVariable++ else if (javascriptFile[i1] == '}') bracesVariable--
468+
i1++
475469
}
476470
}
477471
// Search for functions
@@ -482,23 +476,23 @@ class YTExtractor(val con: Context, val CACHING: Boolean = false, val LOGGING: B
482476
continue
483477
}
484478
startIndex = javascriptFile.indexOf(functionDef) + functionDef.length
485-
var braces = 0
486-
var i = startIndex
487-
while (i < javascriptFile.length) {
488-
if (braces == 0 && startIndex + 5 < i) {
479+
var bracesFunction = 0
480+
var i2 = startIndex
481+
while (i2 < javascriptFile.length) {
482+
if (bracesFunction == 0 && startIndex + 5 < i2) {
489483
decipherFunctions += functionDef + javascriptFile.substring(
490484
startIndex,
491-
i
485+
i2
492486
) + ";"
493487
break
494488
}
495-
if (javascriptFile[i] == '{') braces++ else if (javascriptFile[i] == '}') braces--
496-
i++
489+
if (javascriptFile[i2] == '{') bracesFunction++ else if (javascriptFile[i2] == '}') bracesFunction--
490+
i2++
497491
}
498492
}
499493
if (LOGGING) Log.d(
500494
LOG_TAG,
501-
"Decipher Function: " + decipherFunctions
495+
"Decipher Function: $decipherFunctions"
502496
)
503497
decipherViaWebView(encSignatures)
504498
if (CACHING) {
@@ -514,7 +508,7 @@ class YTExtractor(val con: Context, val CACHING: Boolean = false, val LOGGING: B
514508
}
515509

516510
private fun readDecipherFunctFromCache() {
517-
val cacheFile = File(cacheDirPath + "/" + CACHE_FILE_NAME)
511+
val cacheFile = File("$cacheDirPath/$CACHE_FILE_NAME")
518512
// The cached functions are valid for 2 weeks
519513
if (cacheFile.exists() && System.currentTimeMillis() - cacheFile.lastModified() < 1209600000) {
520514
var reader: BufferedReader? = null
@@ -539,7 +533,7 @@ class YTExtractor(val con: Context, val CACHING: Boolean = false, val LOGGING: B
539533

540534
private fun decipherViaWebView(encSignatures: SparseArray<String>) {
541535
val context = refContext!!.get() ?: return
542-
val stb = StringBuilder(decipherFunctions + " function decipher(")
536+
val stb = StringBuilder("$decipherFunctions function decipher(")
543537
stb.append("){return ")
544538
for (i in 0 until encSignatures.size()) {
545539
val key = encSignatures.keyAt(i)
@@ -580,22 +574,20 @@ class YTExtractor(val con: Context, val CACHING: Boolean = false, val LOGGING: B
580574
}
581575
}
582576

583-
fun setDefaultHttpProtocol(useHttp: Boolean) {}
584-
585577
private fun writeDeciperFunctToChache() {
586-
val cacheFile = File(cacheDirPath + "/" + CACHE_FILE_NAME)
578+
val cacheFile = File("$cacheDirPath/$CACHE_FILE_NAME")
587579
var writer: BufferedWriter? = null
588580
try {
589581
writer = BufferedWriter(OutputStreamWriter(FileOutputStream(cacheFile), "UTF-8"))
590582
writer.write(
591583
"""
592-
${decipherJsFileName}
584+
$decipherJsFileName
593585
594586
""".trimIndent()
595587
)
596588
writer.write(
597589
"""
598-
${decipherFunctionName}
590+
$decipherFunctionName
599591
600592
""".trimIndent()
601593
)
@@ -623,58 +615,42 @@ class YTExtractor(val con: Context, val CACHING: Boolean = false, val LOGGING: B
623615
withContext(Dispatchers.IO) {
624616
ytFiles = async {
625617
state = State.LOADING
626-
var retry: Int = 0
618+
var retry = 0
627619
while (state != State.SUCCESS && retry < retryCount) {
628620
if (LOGGING) Log.d(
629621
LOG_TAG,
630622
"Retry: $retry"
631623
)
632-
var mat = patYouTubePageLink.matcher(videoId)
633-
if (mat.find()) {
634-
videoID = mat.group(3)
635-
} else {
636-
mat = patYouTubeShortLink.matcher(videoId)
637-
if (mat.find()) {
638-
videoID = mat.group(3)
639-
} else if (videoId.matches("\\p{Graph}+?".toRegex())) {
640-
videoID = videoId
641-
}
642-
}
643-
if (videoID != null) {
624+
videoID = videoId
625+
try {
626+
val temp = getStreamUrls()
644627
try {
645-
val temp = getStreamUrls()
646-
try {
647-
if (temp != null) {
648-
val test = testHttp403Code(temp.getAudioOnly().bestQuality()?.url)
649-
if (!test) {
650-
if (LOGGING) Log.d(
651-
LOG_TAG,
652-
"NO Error"
653-
)
654-
state = State.SUCCESS
655-
return@async temp
656-
}
657-
else {
658-
retry++
659-
state = State.ERROR
660-
Log.e(LOG_TAG, "Extraction failed cause 403 HTTP Error")
661-
}
628+
if (temp != null) {
629+
val test = testHttp403Code(temp.getAudioOnly().bestQuality()?.url)
630+
if (!test) {
631+
if (LOGGING) Log.d(
632+
LOG_TAG,
633+
"NO Error"
634+
)
635+
state = State.SUCCESS
636+
return@async temp
637+
}
638+
else {
639+
retry++
640+
state = State.ERROR
641+
Log.e(LOG_TAG, "Extraction failed cause 403 HTTP Error")
662642
}
663643
}
664-
catch (e: IOException){
665-
retry++
666-
state = State.ERROR
667-
Log.e(LOG_TAG, "Extraction failed cause 403 HTTP Error", e)
668-
}
669-
} catch (e: java.lang.Exception) {
644+
}
645+
catch (e: IOException){
670646
retry++
671647
state = State.ERROR
672-
Log.e(LOG_TAG, "Extraction failed", e)
648+
Log.e(LOG_TAG, "Extraction failed cause 403 HTTP Error", e)
673649
}
674-
} else {
650+
} catch (e: java.lang.Exception) {
675651
retry++
676652
state = State.ERROR
677-
Log.e(LOG_TAG, "Wrong YouTube link format")
653+
Log.e(LOG_TAG, "Extraction failed", e)
678654
}
679655
}
680656
return@async null

0 commit comments

Comments
 (0)