diff --git a/README.md b/README.md index 5a8e87d..5724ddf 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 我的电视 -安卓电视直播软件,内置直播源 +电视直播软件,安装即可使用 ## 使用 @@ -14,16 +14,28 @@ ## 更新日志 +### v1.5.1(高版本专用) + +* 性能优化 + +### v1.5.0(通用版) + +* 修复部分情况下APP切换后无法继续播放的问题 + +### v1.4.9(高版本专用) + +* 同步v1.4.8 + ### v1.4.8(通用版) -* 频道号从1开始,cctv5+为18 -* 提高cctv6清晰度 +* 频道号从1开始,CCTV5+为18 +* 提高CCTV6清晰度 * 增加天津卫视、新疆卫视 ### v1.4.7(高版本专用) -* 修复部分用户cctv13播放过程中卡住的问题 -* 调整cctv的频道顺序 +* 修复部分用户CCTV13播放过程中卡住的问题 +* 调整CCTV的频道顺序 ### v1.4.6(通用版) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b38f486..5a058f9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,17 +9,19 @@ diff --git a/app/src/main/cpp/arm64-v8a/libnative.so b/app/src/main/cpp/arm64-v8a/libnative.so index f90b96a..bc205ee 100755 Binary files a/app/src/main/cpp/arm64-v8a/libnative.so and b/app/src/main/cpp/arm64-v8a/libnative.so differ diff --git a/app/src/main/cpp/armeabi-v7a/libnative.so b/app/src/main/cpp/armeabi-v7a/libnative.so index 4b62e3b..c7288c4 100755 Binary files a/app/src/main/cpp/armeabi-v7a/libnative.so and b/app/src/main/cpp/armeabi-v7a/libnative.so differ diff --git a/app/src/main/java/com/lizongying/mytv/InfoFragment.kt b/app/src/main/java/com/lizongying/mytv/InfoFragment.kt index 1f9a34e..7da7dcc 100644 --- a/app/src/main/java/com/lizongying/mytv/InfoFragment.kt +++ b/app/src/main/java/com/lizongying/mytv/InfoFragment.kt @@ -48,7 +48,6 @@ class InfoFragment : Fragment() { .into(binding.infoLogo) } - val program = tvViewModel.getProgramOne() if (program != null) { binding.infoDesc.text = program.name diff --git a/app/src/main/java/com/lizongying/mytv/MainActivity.kt b/app/src/main/java/com/lizongying/mytv/MainActivity.kt index cd0a298..792a709 100644 --- a/app/src/main/java/com/lizongying/mytv/MainActivity.kt +++ b/app/src/main/java/com/lizongying/mytv/MainActivity.kt @@ -35,16 +35,17 @@ 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 - private lateinit var sharedPref: SharedPreferences + lateinit var sharedPref: SharedPreferences private var channelReversal = false private var channelNum = true private var versionName = "" override fun onCreate(savedInstanceState: Bundle?) { + Log.i(TAG, "onCreate") super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) @@ -60,7 +61,6 @@ class MainActivity : FragmentActivity() { .add(R.id.main_browse_fragment, mainFragment) .hide(mainFragment) .commit() - mainFragment.view?.requestFocus() } gestureDetector = GestureDetector(this, GestureListener()) @@ -133,11 +133,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() } @@ -223,7 +223,7 @@ class MainActivity : FragmentActivity() { this.channelNum = channelNum } - private fun showHelp() { + private fun showSetting() { if (!mainFragment.isHidden) { return } @@ -231,15 +231,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() } @@ -360,27 +360,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 } @@ -478,7 +478,7 @@ class MainActivity : FragmentActivity() { private fun hashSignature(signature: Signature): String { return try { - val md = MessageDigest.getInstance("SHA-256") + val md = MessageDigest.getInstance("MD5") md.update(signature.toByteArray()) val digest = md.digest() digest.let { it -> it.joinToString("") { "%02x".format(it) } } @@ -488,6 +488,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" diff --git a/app/src/main/java/com/lizongying/mytv/MainFragment.kt b/app/src/main/java/com/lizongying/mytv/MainFragment.kt index 623aca0..9dfb048 100644 --- a/app/src/main/java/com/lizongying/mytv/MainFragment.kt +++ b/app/src/main/java/com/lizongying/mytv/MainFragment.kt @@ -1,6 +1,5 @@ package com.lizongying.mytv -import android.content.Context import android.content.SharedPreferences import android.os.Bundle import android.os.Handler @@ -36,7 +35,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener { var tvListViewModel = TVListViewModel() - private var sharedPref: SharedPreferences? = null + private lateinit var sharedPref: SharedPreferences private var lastVideoUrl = "" @@ -57,7 +56,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener { super.onActivityCreated(savedInstanceState) activity?.let { request.initYSP(it) } - sharedPref = activity?.getPreferences(Context.MODE_PRIVATE) + sharedPref = (activity as? MainActivity)?.sharedPref!! view?.post { val content = binding.content @@ -98,13 +97,13 @@ class MainFragment : Fragment(), CardAdapter.ItemListener { mUpdateProgramRunnable = UpdateProgramRunnable() handler.post(mUpdateProgramRunnable) - itemPosition = sharedPref?.getInt(POSITION, 0)!! + itemPosition = sharedPref.getInt(POSITION, 0) if (itemPosition >= tvListViewModel.size()) { itemPosition = 0 } tvListViewModel.setItemPosition(itemPosition) setPosition() - tvListViewModel.getTVListViewModel().value?.forEach { tvViewModel -> + tvListViewModel.tvListViewModel.value?.forEach { tvViewModel -> tvViewModel.errInfo.observe(viewLifecycleOwner) { _ -> if (tvViewModel.errInfo.value != null && tvViewModel.id.value == itemPosition @@ -262,7 +261,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener { tvViewModel.programUpdateTime = timestamp request.fetchProgram(tvViewModel) } else { - if (timestamp - tvViewModel.program.value!!.last().et < 600) { + if (tvViewModel.program.value!!.last().et - timestamp < 600) { tvViewModel.programUpdateTime = timestamp request.fetchProgram(tvViewModel) } @@ -272,7 +271,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener { inner class UpdateProgramRunnable : Runnable { override fun run() { - tvListViewModel.getTVListViewModel().value?.filter { it.programId.value != null } + tvListViewModel.tvListViewModel.value?.filter { it.programId.value != null } ?.forEach { tvViewModel -> updateProgram( tvViewModel @@ -282,14 +281,19 @@ class MainFragment : Fragment(), CardAdapter.ItemListener { } } + override fun onResume() { + Log.i(TAG, "onResume") + super.onResume() + } + override fun onStop() { Log.i(TAG, "onStop") super.onStop() - with(sharedPref!!.edit()) { + with(sharedPref.edit()) { putInt(POSITION, itemPosition) apply() } - Log.i(TAG, "POSITION saved") + Log.i(TAG, "$POSITION saved") } override fun onDestroy() { @@ -304,11 +308,6 @@ class MainFragment : Fragment(), CardAdapter.ItemListener { _binding = null } - override fun onResume() { - super.onResume() - view?.post { view?.requestFocus() } - } - companion object { private const val TAG = "MainFragment" private const val POSITION = "position" diff --git a/app/src/main/java/com/lizongying/mytv/PlayerFragment.kt b/app/src/main/java/com/lizongying/mytv/PlayerFragment.kt index f86658d..89aa03c 100644 --- a/app/src/main/java/com/lizongying/mytv/PlayerFragment.kt +++ b/app/src/main/java/com/lizongying/mytv/PlayerFragment.kt @@ -74,23 +74,31 @@ class PlayerFragment : Fragment() { @OptIn(UnstableApi::class) fun play(tvViewModel: TVViewModel) { this.tvViewModel = tvViewModel - val videoUrlCurrent = tvViewModel.getVideoUrlCurrent() playerView?.player?.run { - setMediaItem(MediaItem.fromUri(videoUrlCurrent)) + setMediaItem(MediaItem.fromUri(tvViewModel.getVideoUrlCurrent())) prepare() } } override fun onStart() { + Log.i(TAG, "onStart") super.onStart() - if (playerView != null) { - playerView!!.player?.play() + if (playerView != null && playerView!!.player?.isPlaying == false) { + Log.i(TAG, "replay") + playerView!!.player?.prepare() + } else { + Log.i(TAG, "playing") } } - override fun onStop() { - super.onStop() - if (playerView != null) { + override fun onResume() { + Log.i(TAG, "onResume") + super.onResume() + } + + override fun onPause() { + super.onPause() + if (playerView != null && playerView!!.player?.isPlaying == true) { playerView!!.player?.stop() } } diff --git a/app/src/main/java/com/lizongying/mytv/Request.kt b/app/src/main/java/com/lizongying/mytv/Request.kt index 4485e79..f1fd929 100644 --- a/app/src/main/java/com/lizongying/mytv/Request.kt +++ b/app/src/main/java/com/lizongying/mytv/Request.kt @@ -32,10 +32,12 @@ class Request { private var yspBtraceService: YSPBtraceService = ApiClient().yspBtraceService private var yspProtoService: YSPProtoService = ApiClient().yspProtoService private var ysp: YSP? = null + private var token = "" // TODO onDestroy private val handler = Handler(Looper.getMainLooper()) - private lateinit var myRunnable: MyRunnable + private lateinit var btraceRunnable: BtraceRunnable + private var tokenRunnable: TokenRunnable = TokenRunnable() private var mapping = mapOf( "CCTV4K" to "CCTV4K 超高清", @@ -85,6 +87,10 @@ class Request { "新疆卫视" to "新疆卫视", ) + init { + handler.post(tokenRunnable) + } + fun initYSP(context: Context) { ysp = YSP(context) } @@ -93,8 +99,8 @@ class Request { fun fetchVideo(tvModel: TVViewModel, cookie: String) { call?.cancel() - if (::myRunnable.isInitialized) { - handler.removeCallbacks(myRunnable) + if (::btraceRunnable.isInitialized) { + handler.removeCallbacks(btraceRunnable) } val title = tvModel.title.value @@ -125,17 +131,22 @@ class Request { keyBytes + byteArrayOf(0, 0, 0, 0, 0, 0, 0, 0), ivBytes ).uppercase() - Log.i(TAG, "$title url $url") +// Log.d(TAG, "$title url $url") tvModel.addVideoUrl(url) tvModel.allReady() tvModel.retryTimes = 0 - myRunnable = MyRunnable(tvModel) - handler.post(myRunnable) + btraceRunnable = BtraceRunnable(tvModel) + handler.post(btraceRunnable) } else { Log.e(TAG, "$title key error") if (tvModel.retryTimes < tvModel.retryMaxTimes) { tvModel.retryTimes++ - fetchVideo(tvModel, cookie) + if (tvModel.needToken) { + token = "" + fetchVideo(tvModel) + } else { + fetchVideo(tvModel, cookie) + } } } } else { @@ -146,7 +157,12 @@ class Request { Log.e(TAG, "$title url error $request $liveInfo") if (tvModel.retryTimes < tvModel.retryMaxTimes) { tvModel.retryTimes++ - fetchVideo(tvModel, cookie) + if (tvModel.needToken) { + token = "" + fetchVideo(tvModel) + } else { + fetchVideo(tvModel, cookie) + } } } } @@ -154,7 +170,12 @@ class Request { Log.e(TAG, "$title status error") if (tvModel.retryTimes < tvModel.retryMaxTimes) { tvModel.retryTimes++ - fetchVideo(tvModel, cookie) + if (tvModel.needToken) { + token = "" + fetchVideo(tvModel) + } else { + fetchVideo(tvModel, cookie) + } } } } @@ -163,39 +184,50 @@ class Request { Log.e(TAG, "$title request error") if (tvModel.retryTimes < tvModel.retryMaxTimes) { tvModel.retryTimes++ - fetchVideo(tvModel, cookie) + if (tvModel.needToken) { + token = "" + fetchVideo(tvModel) + } else { + fetchVideo(tvModel, cookie) + } } } }) } fun fetchVideo(tvModel: TVViewModel) { - yspTokenService.getInfo() - .enqueue(object : Callback { - override fun onResponse(call: Call, response: Response) { - if (response.isSuccessful) { - val token = response.body()?.data?.token - Log.i(TAG, "info success $token") - val cookie = - "vplatform=109; yspopenid=vu0-8lgGV2LW9QjDeuBFsX8yMnzs37Q3_HZF6XyVDpGR_I; vusession=$token" - fetchVideo(tvModel, cookie) - } else { - Log.e(TAG, "info status error") + if (token == "") { + yspTokenService.getInfo() + .enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + if (response.isSuccessful) { + token = response.body()?.data?.token!! + Log.i(TAG, "info success $token") + val cookie = + "vplatform=109; yspopenid=vu0-8lgGV2LW9QjDeuBFsX8yMnzs37Q3_HZF6XyVDpGR_I; vusession=$token" + fetchVideo(tvModel, cookie) + } else { + Log.e(TAG, "info status error") + if (tvModel.retryTimes < tvModel.retryMaxTimes) { + tvModel.retryTimes++ + fetchVideo(tvModel) + } + } + } + + override fun onFailure(call: Call, t: Throwable) { + Log.e(TAG, "info request error $t") if (tvModel.retryTimes < tvModel.retryMaxTimes) { tvModel.retryTimes++ fetchVideo(tvModel) } } - } - - override fun onFailure(call: Call, t: Throwable) { - Log.e(TAG, "info request error $t") - if (tvModel.retryTimes < tvModel.retryMaxTimes) { - tvModel.retryTimes++ - fetchVideo(tvModel) - } - } - }) + }) + } else { + val cookie = + "vplatform=109; yspopenid=vu0-8lgGV2LW9QjDeuBFsX8yMnzs37Q3_HZF6XyVDpGR_I; vusession=$token" + fetchVideo(tvModel, cookie) + } } fun fetchData(tvModel: TVViewModel) { @@ -207,7 +239,32 @@ class Request { } } - inner class MyRunnable(private val tvModel: TVViewModel) : Runnable { + inner class TokenRunnable : Runnable { + override fun run() { + fetchToken() + handler.postDelayed(this, 600000) + } + } + + fun fetchToken() { + yspTokenService.getInfo() + .enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + if (response.isSuccessful) { + token = response.body()?.data?.token!! + Log.i(TAG, "info success $token") + } else { + Log.e(TAG, "token status error") + } + } + + override fun onFailure(call: Call, t: Throwable) { + Log.e(TAG, "token request error $t") + } + }) + } + + inner class BtraceRunnable(private val tvModel: TVViewModel) : Runnable { override fun run() { fetchBtrace(tvModel) handler.postDelayed(this, 60000) @@ -304,8 +361,10 @@ 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") } } diff --git a/app/src/main/java/com/lizongying/mytv/TVList.kt b/app/src/main/java/com/lizongying/mytv/TVList.kt index fd2e98c..ca03d67 100644 --- a/app/src/main/java/com/lizongying/mytv/TVList.kt +++ b/app/src/main/java/com/lizongying/mytv/TVList.kt @@ -277,9 +277,6 @@ CGTN 纪录频道,https://livedoc.cgtn.com/500d/prog_index.m3u8 } if (!i.contains(",")) { channel = i.trim() - if (channel == "移动专区") { - break - } continue } val p = i.split(",") diff --git a/app/src/main/java/com/lizongying/mytv/api/YSP.kt b/app/src/main/java/com/lizongying/mytv/api/YSP.kt index 7c0eef7..75a9f25 100644 --- a/app/src/main/java/com/lizongying/mytv/api/YSP.kt +++ b/app/src/main/java/com/lizongying/mytv/api/YSP.kt @@ -2,6 +2,7 @@ package com.lizongying.mytv.api import android.content.Context import android.content.SharedPreferences +import android.util.Log import com.lizongying.mytv.Encryptor import com.lizongying.mytv.MainActivity import com.lizongying.mytv.Utils.getDateTimestamp @@ -51,14 +52,14 @@ class YSP(var context: Context) { private var signature = "" private var encryptor: Encryptor? = null - private var sharedPref: SharedPreferences? = null + private lateinit var sharedPref: SharedPreferences init { if (context is MainActivity) { encryptor = Encryptor() encryptor!!.init(context) - sharedPref = (context as MainActivity).getPreferences(Context.MODE_PRIVATE) + sharedPref = (context as MainActivity).sharedPref } guid = getGuid() @@ -77,15 +78,10 @@ class YSP(var context: Context) { timeStr = getTimeStr() -// guid = "lq3oqitm_1e15dnzgjnb" -// randStr = "BfcCPQp8Hq" -// timeStr = "1702166501" - cKey = encryptor!!.encrypt(cnlid, timeStr, appVer, guid, platform) signature = getSignature() return """{"cnlid":"$cnlid","livepid":"$livepid","stream":"$stream","guid":"$guid","cKey":"$cKey","adjust":$adjust,"sphttps":"$sphttps","platform":"$platform","cmd":"$cmd","encryptVer":"$encryptVer","dtype":"$dtype","devid":"$devid","otype":"$otype","appVer":"$appVer","app_version":"$appVersion","rand_str":"$randStr","channel":"$channel","defn":"$defn","signature":"$signature"}""" -// return """{"cnlid":"2000203803","livepid":"600001801","stream":"2","guid":"lq1y36mb_ccfwmja9zan","cKey":"--01A9F5E89BB86A0C61F4025BEDE15309B6913A79FD1AF1EE7F5EC9C7605F377D1D2281488385C32DEB9E7D0DD3559CB700BD7AF44DD5C9DE0AE14D94B8214027B5D664C108AEE23532348DCC61B86F7C8FBB6CF14D588E6093A25E97DF6D66F4882AB28F17016472DD43D45EF076B7F505176A5E8DEDF2662E5F9AB12B69CB20BCE1579BE724091F3AF6826AE34B713906F3FE139C3783F80EECBD08416DC525E1","adjust":1,"sphttps":"1","platform":"5910204","cmd":"2","encryptVer":"8.1","dtype":"1","devid":"devid","otype":"ojson","appVer":"V1.0.0","app_version":"V1.0.0","rand_str":"IOS2soOw44","channel":"ysp_tx","defn":"fhd","signature":"6ca945f651817de8c6e6910457ceafd6"}""" } private fun getTimeStr(): String { @@ -99,10 +95,10 @@ class YSP(var context: Context) { } fun getGuid(): String { - var guid = sharedPref?.getString("guid", "") + var guid = sharedPref.getString("guid", "") if (guid == null || guid.length < 18) { guid = generateGuid() - with(sharedPref!!.edit()) { + with(sharedPref.edit()) { putString("guid", guid) apply() } @@ -112,7 +108,7 @@ class YSP(var context: Context) { private fun newGuid(): String { guid = generateGuid() - with(sharedPref!!.edit()) { + with(sharedPref.edit()) { putString("guid", guid) apply() } diff --git a/app/src/main/java/com/lizongying/mytv/models/TVListViewModel.kt b/app/src/main/java/com/lizongying/mytv/models/TVListViewModel.kt index 1384f93..de70683 100644 --- a/app/src/main/java/com/lizongying/mytv/models/TVListViewModel.kt +++ b/app/src/main/java/com/lizongying/mytv/models/TVListViewModel.kt @@ -8,7 +8,9 @@ class TVListViewModel : ViewModel() { var maxNum = mutableListOf() - private val tvListViewModel = MutableLiveData>() + private val _tvListViewModel = MutableLiveData>() + val tvListViewModel: LiveData> + get() = _tvListViewModel private val _itemPosition = MutableLiveData() val itemPosition: LiveData @@ -18,22 +20,20 @@ class TVListViewModel : ViewModel() { val itemPositionCurrent: LiveData get() = _itemPositionCurrent - fun getTVListViewModel(): MutableLiveData> { - return tvListViewModel - } - fun addTVViewModel(tvViewModel: TVViewModel) { - val currentTVModelList = tvListViewModel.value ?: mutableListOf() - currentTVModelList.add(tvViewModel) - tvListViewModel.value = currentTVModelList + if (_tvListViewModel.value == null) { + _tvListViewModel.value = mutableListOf(tvViewModel) + } else { + _tvListViewModel.value?.add(tvViewModel) + } } fun getTVViewModel(id: Int): TVViewModel? { - return tvListViewModel.value?.get(id) + return _tvListViewModel.value?.get(id) } fun getTVViewModelCurrent(): TVViewModel? { - return _itemPositionCurrent.value?.let { tvListViewModel.value?.get(it) } + return _itemPositionCurrent.value?.let { _tvListViewModel.value?.get(it) } } fun setItemPosition(position: Int) { @@ -46,6 +46,9 @@ class TVListViewModel : ViewModel() { } fun size(): Int { - return tvListViewModel.value!!.size + if (_tvListViewModel.value == null) { + return 0 + } + return _tvListViewModel.value!!.size } } \ No newline at end of file diff --git a/app/src/main/java/com/lizongying/mytv/models/TVViewModel.kt b/app/src/main/java/com/lizongying/mytv/models/TVViewModel.kt index 66f20db..16d7a83 100644 --- a/app/src/main/java/com/lizongying/mytv/models/TVViewModel.kt +++ b/app/src/main/java/com/lizongying/mytv/models/TVViewModel.kt @@ -78,6 +78,20 @@ class TVViewModel(private var tv: TV) : ViewModel() { var needToken = false private val channelsNeedToken = arrayOf( + "CCTV4K 超高清", + "CCTV2 财经", + "CCTV5 体育", + "CCTV5+ 体育赛事", + "CCTV7 国防军事", + "CCTV9 记录", + "CCTV10 科教", + "CCTV11 戏曲", + "CCTV12 社会与法", + "CCTV14 少儿", + "CCTV15 音乐", + "CCTV16 奥林匹克", + "CCTV17 农业农村", + "CCTV3 综艺", "CCTV6 电影", "CCTV8 电视剧", @@ -94,6 +108,30 @@ class TVViewModel(private var tv: TV) : ViewModel() { "央视台球", "电视指南", "卫生健康", + + "东方卫视", + "湖南卫视", + "湖北卫视", + "辽宁卫视", + "江苏卫视", + "江西卫视", + "山东卫视", + "广东卫视", + "广西卫视", + "重庆卫视", + "河南卫视", + "河北卫视", + "贵州卫视", + "北京卫视", + "黑龙江卫视", + "浙江卫视", + "安徽卫视", + "深圳卫视", + "四川卫视", + "东南卫视", + "海南卫视", + "天津卫视", + "新疆卫视", ) fun addVideoUrl(url: String) { diff --git a/app/src/main/res/xml/network.xml b/app/src/main/res/xml/network.xml new file mode 100644 index 0000000..bb6ab93 --- /dev/null +++ b/app/src/main/res/xml/network.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file