mirror of
https://github.com/lizongying/my-tv.git
synced 2026-10-28 15:16:30 +08:00
Compare commits
6
Commits
v2.1.4
...
JELLY_BEAN_MR1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
acff1d41fc | ||
|
|
ab71075c85 | ||
|
|
5d4353249f | ||
|
|
a8944e75b1 | ||
|
|
d1eae8947e | ||
|
|
fccd64c07b |
@@ -1,5 +1,13 @@
|
|||||||
## 更新日誌
|
## 更新日誌
|
||||||
|
|
||||||
|
### v2.1.8
|
||||||
|
|
||||||
|
* 支持x86設備
|
||||||
|
|
||||||
|
### v2.1.7
|
||||||
|
|
||||||
|
*
|
||||||
|
|
||||||
### v2.1.4
|
### v2.1.4
|
||||||
|
|
||||||
* 解決切換頻道時黑屏問題
|
* 解決切換頻道時黑屏問題
|
||||||
|
|||||||
+4
-6
@@ -26,8 +26,8 @@ android {
|
|||||||
cmake {
|
cmake {
|
||||||
arguments "-DIS_SO_BUILD=${project.hasProperty('IS_SO_BUILD') ? project.IS_SO_BUILD : true}"
|
arguments "-DIS_SO_BUILD=${project.hasProperty('IS_SO_BUILD') ? project.IS_SO_BUILD : true}"
|
||||||
|
|
||||||
// abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
|
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
|
||||||
abiFilters "armeabi-v7a", "arm64-v8a"
|
// abiFilters "armeabi-v7a", "arm64-v8a"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +37,8 @@ android {
|
|||||||
ndk {
|
ndk {
|
||||||
// Specifies the ABI configurations of your native
|
// Specifies the ABI configurations of your native
|
||||||
// libraries Gradle should build and package with your app.
|
// libraries Gradle should build and package with your app.
|
||||||
abiFilters "armeabi-v7a", "arm64-v8a"
|
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
|
||||||
|
// abiFilters "armeabi-v7a", "arm64-v8a"
|
||||||
}
|
}
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
}
|
}
|
||||||
@@ -100,9 +101,6 @@ static def VersionName() {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(libs.media3.ui)
|
implementation(libs.media3.ui)
|
||||||
implementation(libs.failureaccess)
|
|
||||||
implementation(libs.guava)
|
|
||||||
implementation(libs.media3.common)
|
|
||||||
implementation(libs.media3.exoplayer)
|
implementation(libs.media3.exoplayer)
|
||||||
implementation(libs.media3.exoplayer.hls)
|
implementation(libs.media3.exoplayer.hls)
|
||||||
implementation(libs.protobuf.kotlin)
|
implementation(libs.protobuf.kotlin)
|
||||||
|
|||||||
Vendored
+1
-7
@@ -18,10 +18,4 @@
|
|||||||
|
|
||||||
# If you keep the line number information, uncomment this to
|
# If you keep the line number information, uncomment this to
|
||||||
# hide the original source file name.
|
# hide the original source file name.
|
||||||
#-renamesourcefileattribute SourceFile
|
#-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
-keep class com.google.gson.** { *; }
|
|
||||||
-dontwarn com.google.gson.**
|
|
||||||
|
|
||||||
-keep class com.google.guava.** { *; }
|
|
||||||
-dontwarn com.google.guava.**
|
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -2,6 +2,7 @@ package com.lizongying.mytv
|
|||||||
|
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.util.Log
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.lizongying.mytv.api.TimeResponse
|
import com.lizongying.mytv.api.TimeResponse
|
||||||
@@ -18,6 +19,10 @@ import java.util.Locale
|
|||||||
object Utils {
|
object Utils {
|
||||||
private var between: Long = 0
|
private var between: Long = 0
|
||||||
|
|
||||||
|
private var a: String = ""
|
||||||
|
var b: String = ""
|
||||||
|
private var c: String = ""
|
||||||
|
|
||||||
private var listener: Request.RequestListener? = null
|
private var listener: Request.RequestListener? = null
|
||||||
|
|
||||||
fun getDateFormat(format: String): String {
|
fun getDateFormat(format: String): String {
|
||||||
@@ -45,6 +50,31 @@ object Utils {
|
|||||||
println("Failed to retrieve timestamp from server: ${e.message}")
|
println("Failed to retrieve timestamp from server: ${e.message}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var x = ""
|
||||||
|
try {
|
||||||
|
x = getNothing()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
x = ""
|
||||||
|
println("a ${e.message}")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x != "") {
|
||||||
|
try {
|
||||||
|
x = getNothing2(x)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
x = ""
|
||||||
|
println("b ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (x != "") {
|
||||||
|
// try {
|
||||||
|
// getNothing3(x)
|
||||||
|
// } catch (e: Exception) {
|
||||||
|
// println("b ${e.message}")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
listener?.onRequestFinished(null)
|
listener?.onRequestFinished(null)
|
||||||
}
|
}
|
||||||
@@ -88,6 +118,115 @@ object Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val regex = Regex("""chunk-vendors\.([^.]+)\.js""")
|
||||||
|
|
||||||
|
private suspend fun getNothing(): String {
|
||||||
|
return withContext(Dispatchers.IO) {
|
||||||
|
val client = okhttp3.OkHttpClient.Builder()
|
||||||
|
.addInterceptor(RetryInterceptor(3))
|
||||||
|
.build()
|
||||||
|
val request = okhttp3.Request.Builder()
|
||||||
|
.url("https://www.yangshipin.cn")
|
||||||
|
.build()
|
||||||
|
try {
|
||||||
|
client.newCall(request).execute().use { response ->
|
||||||
|
if (!response.isSuccessful) throw IOException("Unexpected code $response")
|
||||||
|
val string = response.body()?.string()
|
||||||
|
|
||||||
|
val matchResult = string?.let { regex.find(it) }
|
||||||
|
var x = ""
|
||||||
|
if (matchResult != null) {
|
||||||
|
x = matchResult.groupValues[1]
|
||||||
|
}
|
||||||
|
x
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw IOException("Error during network request", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val regex2 = Regex(""""ysp_tx"[^:]+:"([^"]+)[^:]+:"([^"]+)""")
|
||||||
|
|
||||||
|
private val regex3 = Regex(""""(https[^"]+wasm([^"]+))""")
|
||||||
|
|
||||||
|
private suspend fun getNothing2(x: String): String {
|
||||||
|
return withContext(Dispatchers.IO) {
|
||||||
|
val client = okhttp3.OkHttpClient.Builder()
|
||||||
|
.addInterceptor(RetryInterceptor(3))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val request = okhttp3.Request.Builder()
|
||||||
|
.url("https://www.yangshipin.cn/js/chunk-vendors.$x.js")
|
||||||
|
.build()
|
||||||
|
try {
|
||||||
|
client.newCall(request).execute().use { response ->
|
||||||
|
if (!response.isSuccessful) throw IOException("Unexpected code $response")
|
||||||
|
val string = response.body()?.string()
|
||||||
|
|
||||||
|
val matches = string?.let { regex2.findAll(it) }
|
||||||
|
|
||||||
|
var matchResult = matches?.lastOrNull()
|
||||||
|
|
||||||
|
if (matchResult != null) {
|
||||||
|
val (aa, bb) = matchResult.destructured
|
||||||
|
a = aa
|
||||||
|
b = bb
|
||||||
|
}
|
||||||
|
|
||||||
|
matchResult = string?.let { regex3.find(it) }
|
||||||
|
|
||||||
|
if (matchResult != null) {
|
||||||
|
val (cc) = matchResult.destructured
|
||||||
|
c = cc
|
||||||
|
Log.i("", "ccccc $c")
|
||||||
|
}
|
||||||
|
c
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw IOException("Error during network request", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun getNothing3(x: String): String {
|
||||||
|
return withContext(Dispatchers.IO) {
|
||||||
|
val client = okhttp3.OkHttpClient.Builder()
|
||||||
|
.addInterceptor(RetryInterceptor(3))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val request = okhttp3.Request.Builder()
|
||||||
|
.url("https://www.yangshipin.cn/js/chunk-vendors.$x.js")
|
||||||
|
.build()
|
||||||
|
try {
|
||||||
|
client.newCall(request).execute().use { response ->
|
||||||
|
if (!response.isSuccessful) throw IOException("Unexpected code $response")
|
||||||
|
val string = response.body()?.string()
|
||||||
|
|
||||||
|
val matches = string?.let { regex2.findAll(it) }
|
||||||
|
|
||||||
|
var matchResult = matches?.lastOrNull()
|
||||||
|
|
||||||
|
if (matchResult != null) {
|
||||||
|
val (aa, bb) = matchResult.destructured
|
||||||
|
a = aa
|
||||||
|
b = bb
|
||||||
|
}
|
||||||
|
|
||||||
|
matchResult = string?.let { regex3.find(it) }
|
||||||
|
|
||||||
|
if (matchResult != null) {
|
||||||
|
val (cc) = matchResult.destructured
|
||||||
|
c = cc
|
||||||
|
}
|
||||||
|
c
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw IOException("Error during network request", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun dpToPx(dp: Float): Int {
|
fun dpToPx(dp: Float): Int {
|
||||||
return TypedValue.applyDimension(
|
return TypedValue.applyDimension(
|
||||||
TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().displayMetrics
|
TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().displayMetrics
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ class Encryptor {
|
|||||||
|
|
||||||
external fun hash2(data: ByteArray): ByteArray?
|
external fun hash2(data: ByteArray): ByteArray?
|
||||||
|
|
||||||
|
external fun hash3(data: ByteArray): ByteArray?
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
init {
|
init {
|
||||||
System.loadLibrary("native")
|
System.loadLibrary("native")
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.lizongying.mytv.api
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.lizongying.mytv.SP
|
import com.lizongying.mytv.SP
|
||||||
|
import com.lizongying.mytv.Utils
|
||||||
import com.lizongying.mytv.Utils.getDateTimestamp
|
import com.lizongying.mytv.Utils.getDateTimestamp
|
||||||
import com.lizongying.mytv.models.TVViewModel
|
import com.lizongying.mytv.models.TVViewModel
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
@@ -182,13 +183,13 @@ object YSP {
|
|||||||
|
|
||||||
private fun getAuthSignature(): String {
|
private fun getAuthSignature(): String {
|
||||||
val e =
|
val e =
|
||||||
"appid=${appid}&guid=${guid}&pid=${livepid}&rand_str=${randStr}".toByteArray()
|
"appid=${appid}&guid=${guid}&pid=${livepid}&rand_str=${randStr}${Utils.b}".toByteArray()
|
||||||
val hashedData = encryptor.hash2(e) ?: return ""
|
val hashedData = encryptor.hash3(e) ?: return ""
|
||||||
return hashedData.let { it -> it.joinToString("") { "%02x".format(it) } }
|
return hashedData.let { it -> it.joinToString("") { "%02x".format(it) } }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAuthSignature(e: String): String {
|
fun getAuthSignature(e: String): String {
|
||||||
val hashedData = encryptor.hash2(e.toByteArray()) ?: return ""
|
val hashedData = encryptor.hash3("$e${Utils.b}".toByteArray()) ?: return ""
|
||||||
return hashedData.let { it -> it.joinToString("") { "%02x".format(it) } }
|
return hashedData.let { it -> it.joinToString("") { "%02x".format(it) } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -334,21 +334,8 @@ object Request {
|
|||||||
val liveInfo = response.body()
|
val liveInfo = response.body()
|
||||||
|
|
||||||
if (liveInfo?.data?.playurl != null) {
|
if (liveInfo?.data?.playurl != null) {
|
||||||
val chanll = liveInfo.data.chanll
|
if (liveInfo.data.extended_param != null) {
|
||||||
val decodedBytes = Base64.decode(
|
val url = liveInfo.data.playurl + "&revoi=" + liveInfo.data.extended_param
|
||||||
chanll.substring(9, chanll.length - 3),
|
|
||||||
Base64.DEFAULT
|
|
||||||
)
|
|
||||||
val decodedString = String(decodedBytes)
|
|
||||||
val matchResult = regex.find(decodedString)
|
|
||||||
if (matchResult != null) {
|
|
||||||
val (key, iv) = matchResult.destructured
|
|
||||||
val keyBytes = Base64.decode(key, Base64.DEFAULT)
|
|
||||||
val ivBytes = Base64.decode(iv, Base64.DEFAULT)
|
|
||||||
val url = liveInfo.data.playurl + "&revoi=" + encryptTripleDES(
|
|
||||||
keyBytes + byteArrayOf(0, 0, 0, 0, 0, 0, 0, 0),
|
|
||||||
ivBytes
|
|
||||||
).uppercase() + liveInfo.data.extended_param
|
|
||||||
Log.d(TAG, "$title url $url")
|
Log.d(TAG, "$title url $url")
|
||||||
tvModel.addVideoUrl(url)
|
tvModel.addVideoUrl(url)
|
||||||
tvModel.allReady()
|
tvModel.allReady()
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
#Fri Dec 01 13:53:24 HKT 2023
|
#Fri Dec 01 13:53:24 HKT 2023
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-rc-1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version_code": 33620992, "version_name": "v2.1.4"}
|
{"version_code": 33622016, "version_name": "v2.1.8"}
|
||||||
|
|||||||
Reference in New Issue
Block a user