mirror of
https://github.com/lizongying/my-tv.git
synced 2026-10-28 23:26:29 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
088808c3fd | ||
|
|
73239a6677 |
@@ -9,17 +9,19 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:largeHeap="true"
|
||||
android:icon="@drawable/logo"
|
||||
android:logo="@drawable/logo"
|
||||
android:banner="@drawable/banner"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:networkSecurityConfig="@xml/network"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:theme="@style/Theme.MyTV">
|
||||
<activity
|
||||
android:keepScreenOn="true"
|
||||
android:name=".MainActivity"
|
||||
android:banner="@drawable/banner"
|
||||
android:exported="true"
|
||||
android:icon="@drawable/logo"
|
||||
android:logo="@drawable/logo"
|
||||
android:screenOrientation="landscape">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
@@ -35,8 +35,8 @@ class MainActivity : FragmentActivity() {
|
||||
private lateinit var gestureDetector: GestureDetector
|
||||
|
||||
private val handler = Handler()
|
||||
private val delay: Long = 4000
|
||||
private val delayHideHelp: Long = 10000
|
||||
private val delayHideMain: Long = 5000
|
||||
private val delayHideSetting: Long = 10000
|
||||
|
||||
lateinit var sharedPref: SharedPreferences
|
||||
private var channelReversal = false
|
||||
@@ -45,6 +45,7 @@ class MainActivity : FragmentActivity() {
|
||||
private var versionName = ""
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
Log.i(TAG, "onCreate")
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
@@ -131,11 +132,11 @@ class MainActivity : FragmentActivity() {
|
||||
}
|
||||
|
||||
fun keepRunnable() {
|
||||
handler.removeCallbacks(hideRunnable)
|
||||
handler.postDelayed(hideRunnable, delay)
|
||||
handler.removeCallbacks(hideMain)
|
||||
handler.postDelayed(hideMain, delayHideMain)
|
||||
}
|
||||
|
||||
private val hideRunnable = Runnable {
|
||||
private val hideMain = Runnable {
|
||||
if (!mainFragment.isHidden) {
|
||||
supportFragmentManager.beginTransaction().hide(mainFragment).commit()
|
||||
}
|
||||
@@ -221,7 +222,7 @@ class MainActivity : FragmentActivity() {
|
||||
this.channelNum = channelNum
|
||||
}
|
||||
|
||||
private fun showHelp() {
|
||||
private fun showSetting() {
|
||||
if (!mainFragment.isHidden) {
|
||||
return
|
||||
}
|
||||
@@ -229,15 +230,15 @@ class MainActivity : FragmentActivity() {
|
||||
Log.i(TAG, "settingFragment ${settingFragment.isVisible}")
|
||||
if (!settingFragment.isVisible) {
|
||||
settingFragment.show(supportFragmentManager, "setting")
|
||||
handler.removeCallbacks(hideHelp)
|
||||
handler.postDelayed(hideHelp, delayHideHelp)
|
||||
handler.removeCallbacks(hideSetting)
|
||||
handler.postDelayed(hideSetting, delayHideSetting)
|
||||
} else {
|
||||
handler.removeCallbacks(hideHelp)
|
||||
handler.removeCallbacks(hideSetting)
|
||||
settingFragment.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private val hideHelp = Runnable {
|
||||
private val hideSetting = Runnable {
|
||||
if (settingFragment.isVisible) {
|
||||
settingFragment.dismiss()
|
||||
}
|
||||
@@ -358,27 +359,27 @@ class MainActivity : FragmentActivity() {
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_BOOKMARK -> {
|
||||
showHelp()
|
||||
showSetting()
|
||||
return true
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_UNKNOWN -> {
|
||||
showHelp()
|
||||
showSetting()
|
||||
return true
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_HELP -> {
|
||||
showHelp()
|
||||
showSetting()
|
||||
return true
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_SETTINGS -> {
|
||||
showHelp()
|
||||
showSetting()
|
||||
return true
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_MENU -> {
|
||||
showHelp()
|
||||
showSetting()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -486,6 +487,22 @@ class MainActivity : FragmentActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
Log.i(TAG, "onStart")
|
||||
super.onStart()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
Log.i(TAG, "onResume")
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
Log.i(TAG, "onPause")
|
||||
super.onPause()
|
||||
handler.removeCallbacks(hideMain)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "MainActivity"
|
||||
private const val CHANNEL_REVERSAL = "channel_reversal"
|
||||
|
||||
@@ -44,10 +44,16 @@ class MainFragment : BrowseSupportFragment() {
|
||||
private var ready = 0
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
Log.i(TAG, "onCreate")
|
||||
super.onCreate(savedInstanceState)
|
||||
headersState = HEADERS_DISABLED
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
Log.i(TAG, "onStart")
|
||||
super.onStart()
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
@@ -298,7 +304,7 @@ class MainFragment : BrowseSupportFragment() {
|
||||
|
||||
inner class UpdateProgramRunnable : Runnable {
|
||||
override fun run() {
|
||||
tvListViewModel.tvListViewModel.value?.filter { it.programId.value != null }
|
||||
tvListViewModel.tvListViewModel.value?.filter { it.programId.value != null && it.programId.value != "" }
|
||||
?.forEach { tvViewModel ->
|
||||
updateProgram(
|
||||
tvViewModel
|
||||
@@ -308,6 +314,11 @@ class MainFragment : BrowseSupportFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
Log.i(TAG, "onResume")
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
Log.i(TAG, "onStop")
|
||||
super.onStop()
|
||||
@@ -315,7 +326,7 @@ class MainFragment : BrowseSupportFragment() {
|
||||
putInt(POSITION, itemPosition)
|
||||
apply()
|
||||
}
|
||||
Log.i(TAG, "POSITION saved")
|
||||
Log.i(TAG, "$POSITION saved")
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
@@ -324,11 +335,6 @@ class MainFragment : BrowseSupportFragment() {
|
||||
handler.removeCallbacks(mUpdateProgramRunnable)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
view?.post { view?.requestFocus() }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "MainFragment"
|
||||
private const val POSITION = "position"
|
||||
|
||||
@@ -81,14 +81,23 @@ class PlayerFragment : Fragment() {
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
Log.i(TAG, "onStart")
|
||||
super.onStart()
|
||||
if (playerView != null && playerView!!.player?.isPlaying == false) {
|
||||
playerView!!.player?.play()
|
||||
Log.i(TAG, "replay")
|
||||
playerView!!.player?.prepare()
|
||||
} else {
|
||||
Log.i(TAG, "playing")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
override fun onResume() {
|
||||
Log.i(TAG, "onResume")
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
if (playerView != null && playerView!!.player?.isPlaying == true) {
|
||||
playerView!!.player?.stop()
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ class Request {
|
||||
private lateinit var btraceRunnable: BtraceRunnable
|
||||
private var tokenRunnable: TokenRunnable = TokenRunnable()
|
||||
|
||||
private val regex = Regex("""des_key = "([^"]+).+var des_iv = "([^"]+)""")
|
||||
|
||||
private var mapping = mapOf(
|
||||
"CCTV4K" to "CCTV4K 超高清",
|
||||
"CCTV1" to "CCTV1 综合",
|
||||
@@ -121,7 +123,6 @@ class Request {
|
||||
Base64.DEFAULT
|
||||
)
|
||||
val decodedString = String(decodedBytes)
|
||||
val regex = Regex("""des_key = "([^"]+).+var des_iv = "([^"]+)""")
|
||||
val matchResult = regex.find(decodedString)
|
||||
if (matchResult != null) {
|
||||
val (key, iv) = matchResult.destructured
|
||||
@@ -142,8 +143,14 @@ class Request {
|
||||
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
|
||||
tvModel.retryTimes++
|
||||
if (tvModel.needToken) {
|
||||
token = ""
|
||||
fetchVideo(tvModel)
|
||||
if (tvModel.tokenRetryTimes == tvModel.tokenRetryMaxTimes) {
|
||||
if (!tvModel.mustToken) {
|
||||
fetchVideo(tvModel, cookie)
|
||||
}
|
||||
} else {
|
||||
token = ""
|
||||
fetchVideo(tvModel)
|
||||
}
|
||||
} else {
|
||||
fetchVideo(tvModel, cookie)
|
||||
}
|
||||
@@ -158,8 +165,14 @@ class Request {
|
||||
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
|
||||
tvModel.retryTimes++
|
||||
if (tvModel.needToken) {
|
||||
token = ""
|
||||
fetchVideo(tvModel)
|
||||
if (tvModel.tokenRetryTimes == tvModel.tokenRetryMaxTimes) {
|
||||
if (!tvModel.mustToken) {
|
||||
fetchVideo(tvModel, cookie)
|
||||
}
|
||||
} else {
|
||||
token = ""
|
||||
fetchVideo(tvModel)
|
||||
}
|
||||
} else {
|
||||
fetchVideo(tvModel, cookie)
|
||||
}
|
||||
@@ -171,8 +184,14 @@ class Request {
|
||||
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
|
||||
tvModel.retryTimes++
|
||||
if (tvModel.needToken) {
|
||||
token = ""
|
||||
fetchVideo(tvModel)
|
||||
if (tvModel.tokenRetryTimes == tvModel.tokenRetryMaxTimes) {
|
||||
if (!tvModel.mustToken) {
|
||||
fetchVideo(tvModel, cookie)
|
||||
}
|
||||
} else {
|
||||
token = ""
|
||||
fetchVideo(tvModel)
|
||||
}
|
||||
} else {
|
||||
fetchVideo(tvModel, cookie)
|
||||
}
|
||||
@@ -185,8 +204,14 @@ class Request {
|
||||
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
|
||||
tvModel.retryTimes++
|
||||
if (tvModel.needToken) {
|
||||
token = ""
|
||||
fetchVideo(tvModel)
|
||||
if (tvModel.tokenRetryTimes == tvModel.tokenRetryMaxTimes) {
|
||||
if (!tvModel.mustToken) {
|
||||
fetchVideo(tvModel, cookie)
|
||||
}
|
||||
} else {
|
||||
token = ""
|
||||
fetchVideo(tvModel)
|
||||
}
|
||||
} else {
|
||||
fetchVideo(tvModel, cookie)
|
||||
}
|
||||
@@ -208,18 +233,28 @@ class Request {
|
||||
fetchVideo(tvModel, cookie)
|
||||
} else {
|
||||
Log.e(TAG, "info status error")
|
||||
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
|
||||
tvModel.retryTimes++
|
||||
if (tvModel.tokenRetryTimes < tvModel.tokenRetryMaxTimes) {
|
||||
tvModel.tokenRetryTimes++
|
||||
fetchVideo(tvModel)
|
||||
} else {
|
||||
if (!tvModel.mustToken) {
|
||||
val cookie = "vplatform=109"
|
||||
fetchVideo(tvModel, cookie)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<Info>, t: Throwable) {
|
||||
Log.e(TAG, "info request error $t")
|
||||
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
|
||||
tvModel.retryTimes++
|
||||
if (tvModel.tokenRetryTimes < tvModel.tokenRetryMaxTimes) {
|
||||
tvModel.tokenRetryTimes++
|
||||
fetchVideo(tvModel)
|
||||
} else {
|
||||
if (!tvModel.mustToken) {
|
||||
val cookie = "vplatform=109"
|
||||
fetchVideo(tvModel, cookie)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -361,7 +396,7 @@ class Request {
|
||||
val program = response.body()
|
||||
if (program != null) {
|
||||
tvViewModel.addProgram(program.dataListList)
|
||||
Log.i(TAG, "$title program ${program.dataListList.size}")
|
||||
Log.d(TAG, "$title program ${program.dataListList.size}")
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "$title program error")
|
||||
|
||||
@@ -71,7 +71,7 @@ object TVList {
|
||||
)
|
||||
private var mappingEPG = mapOf(
|
||||
"CCTV4K 超高清" to "600002264",
|
||||
"CCTV8K 超高清" to "600156816",
|
||||
// "CCTV8K 超高清" to "600156816",
|
||||
"CCTV1 综合" to "600001859",
|
||||
"CCTV2 财经" to "600001800",
|
||||
"CCTV3 综艺" to "600001801",
|
||||
@@ -95,7 +95,7 @@ object TVList {
|
||||
"CGTN 俄语频道" to "600084758",
|
||||
"CGTN 阿拉伯语频道" to "600084782",
|
||||
"CGTN 西班牙语频道" to "600084744",
|
||||
"CGTN 记录频道" to "600084781",
|
||||
// "CGTN 记录频道" to "600084781",
|
||||
"风云剧场" to "600099658",
|
||||
"第一剧场" to "600099655",
|
||||
"怀旧剧场" to "600099620",
|
||||
@@ -130,8 +130,8 @@ object TVList {
|
||||
"四川卫视" to "600002516",
|
||||
"东南卫视" to "600002484",
|
||||
"海南卫视" to "600002506",
|
||||
"天津卫视" to "600152137",
|
||||
"新疆卫视" to "600152138",
|
||||
// "天津卫视" to "600152137",
|
||||
// "新疆卫视" to "600152138",
|
||||
)
|
||||
private var mappingVideo = mapOf(
|
||||
"CCTV4K 超高清" to arrayOf("600002264", "2000266303"),
|
||||
|
||||
@@ -19,8 +19,10 @@ class TVViewModel(private var tv: TV) : ViewModel() {
|
||||
private var rowPosition: Int = 0
|
||||
private var itemPosition: Int = 0
|
||||
|
||||
var retryTimes: Int = 0
|
||||
var retryMaxTimes: Int = 8
|
||||
var retryTimes = 0
|
||||
var tokenRetryTimes = 0
|
||||
var retryMaxTimes = 8
|
||||
var tokenRetryMaxTimes = 2
|
||||
var programUpdateTime: Long = 0
|
||||
|
||||
private val _errInfo = MutableLiveData<String>()
|
||||
@@ -77,6 +79,8 @@ class TVViewModel(private var tv: TV) : ViewModel() {
|
||||
|
||||
var needToken = false
|
||||
|
||||
var mustToken = false
|
||||
|
||||
private val channelsNeedToken = arrayOf(
|
||||
"CCTV4K 超高清",
|
||||
"CCTV2 财经",
|
||||
@@ -134,6 +138,25 @@ class TVViewModel(private var tv: TV) : ViewModel() {
|
||||
"新疆卫视",
|
||||
)
|
||||
|
||||
private val channelsMustToken = arrayOf(
|
||||
"CCTV3 综艺",
|
||||
"CCTV6 电影",
|
||||
"CCTV8 电视剧",
|
||||
"风云剧场",
|
||||
"第一剧场",
|
||||
"怀旧剧场",
|
||||
"世界地理",
|
||||
"风云音乐",
|
||||
"兵器科技",
|
||||
"风云足球",
|
||||
"高尔夫网球",
|
||||
"女性时尚",
|
||||
"央视文化精品",
|
||||
"央视台球",
|
||||
"电视指南",
|
||||
"卫生健康",
|
||||
)
|
||||
|
||||
fun addVideoUrl(url: String) {
|
||||
if (_videoUrl.value?.isNotEmpty() == true) {
|
||||
if (_videoUrl.value!!.last().contains("cctv.cn")) {
|
||||
@@ -188,6 +211,9 @@ class TVViewModel(private var tv: TV) : ViewModel() {
|
||||
if (tv.title in channelsNeedToken) {
|
||||
needToken = true
|
||||
}
|
||||
if (tv.title in channelsMustToken) {
|
||||
mustToken = true
|
||||
}
|
||||
}
|
||||
|
||||
fun getRowPosition(): Int {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<base-config cleartextTrafficPermitted="true">
|
||||
<trust-anchors>
|
||||
<certificates src="system" />
|
||||
<certificates src="user" />
|
||||
</trust-anchors>
|
||||
</base-config>
|
||||
</network-security-config>
|
||||
Reference in New Issue
Block a user