change channel order
This commit is contained in:
parent
c17d62c698
commit
0f4a33a3fc
|
|
@ -14,6 +14,11 @@
|
||||||
|
|
||||||
## 更新日志
|
## 更新日志
|
||||||
|
|
||||||
|
### v1.4.7(高版本专用)
|
||||||
|
|
||||||
|
* 修复部分用户cctv13播放过程中卡住的问题
|
||||||
|
* 调整cctv的频道顺序
|
||||||
|
|
||||||
### v1.4.5(高版本专用)
|
### v1.4.5(高版本专用)
|
||||||
|
|
||||||
* 数字选台配置
|
* 数字选台配置
|
||||||
|
|
|
||||||
|
|
@ -25,19 +25,19 @@ import com.lizongying.mytv.models.TVViewModel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
|
||||||
class MainFragment : BrowseSupportFragment() {
|
class MainFragment : BrowseSupportFragment() {
|
||||||
var itemPosition: Int = 0
|
|
||||||
|
|
||||||
private var request: Request = Request()
|
private var itemPosition = 0
|
||||||
|
|
||||||
private var rowsAdapter: ArrayObjectAdapter? = null
|
private var rowsAdapter: ArrayObjectAdapter? = null
|
||||||
|
|
||||||
|
private var request = Request()
|
||||||
|
|
||||||
var tvListViewModel = TVListViewModel()
|
var tvListViewModel = TVListViewModel()
|
||||||
|
|
||||||
private var sharedPref: SharedPreferences? = null
|
private var sharedPref: SharedPreferences? = null
|
||||||
|
|
||||||
private var lastVideoUrl: String = ""
|
private var lastVideoUrl = ""
|
||||||
|
|
||||||
private val handler = Handler(Looper.getMainLooper())
|
private val handler = Handler(Looper.getMainLooper())
|
||||||
private lateinit var mUpdateProgramRunnable: UpdateProgramRunnable
|
private lateinit var mUpdateProgramRunnable: UpdateProgramRunnable
|
||||||
|
|
@ -159,63 +159,6 @@ class MainFragment : BrowseSupportFragment() {
|
||||||
tvListViewModel.setItemPosition(itemPosition)
|
tvListViewModel.setItemPosition(itemPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun check(tvViewModel: TVViewModel): Boolean {
|
|
||||||
val title = tvViewModel.title.value
|
|
||||||
val videoUrl = tvViewModel.videoIndex.value?.let { tvViewModel.videoUrl.value?.get(it) }
|
|
||||||
if (videoUrl == null || videoUrl == "") {
|
|
||||||
Log.e(TAG, "$title videoUrl is empty")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (videoUrl == lastVideoUrl) {
|
|
||||||
Log.e(TAG, "$title videoUrl is duplication")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
fun fragmentReady() {
|
|
||||||
ready++
|
|
||||||
Log.i(TAG, "ready $ready")
|
|
||||||
if (ready == 4) {
|
|
||||||
// request.fetchPage()
|
|
||||||
tvListViewModel.getTVViewModel(itemPosition)?.changed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun play(itemPosition: Int) {
|
|
||||||
view?.post {
|
|
||||||
if (itemPosition < tvListViewModel.size()) {
|
|
||||||
this.itemPosition = itemPosition
|
|
||||||
tvListViewModel.setItemPosition(itemPosition)
|
|
||||||
tvListViewModel.getTVViewModel(itemPosition)?.changed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun prev() {
|
|
||||||
view?.post {
|
|
||||||
itemPosition--
|
|
||||||
if (itemPosition == -1) {
|
|
||||||
itemPosition = tvListViewModel.size() - 1
|
|
||||||
}
|
|
||||||
tvListViewModel.setItemPosition(itemPosition)
|
|
||||||
tvListViewModel.getTVViewModel(itemPosition)?.changed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun next() {
|
|
||||||
view?.post {
|
|
||||||
itemPosition++
|
|
||||||
if (itemPosition == tvListViewModel.size()) {
|
|
||||||
itemPosition = 0
|
|
||||||
}
|
|
||||||
tvListViewModel.setItemPosition(itemPosition)
|
|
||||||
tvListViewModel.getTVViewModel(itemPosition)?.changed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun prevSource() {
|
fun prevSource() {
|
||||||
view?.post {
|
view?.post {
|
||||||
val tvViewModel = tvListViewModel.getTVViewModel(itemPosition)
|
val tvViewModel = tvListViewModel.getTVViewModel(itemPosition)
|
||||||
|
|
@ -281,6 +224,63 @@ class MainFragment : BrowseSupportFragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun check(tvViewModel: TVViewModel): Boolean {
|
||||||
|
val title = tvViewModel.title.value
|
||||||
|
val videoUrl = tvViewModel.videoIndex.value?.let { tvViewModel.videoUrl.value?.get(it) }
|
||||||
|
if (videoUrl == null || videoUrl == "") {
|
||||||
|
Log.e(TAG, "$title videoUrl is empty")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (videoUrl == lastVideoUrl) {
|
||||||
|
Log.e(TAG, "$title videoUrl is duplication")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fragmentReady() {
|
||||||
|
ready++
|
||||||
|
Log.i(TAG, "ready $ready")
|
||||||
|
if (ready == 4) {
|
||||||
|
// request.fetchPage()
|
||||||
|
tvListViewModel.getTVViewModel(itemPosition)?.changed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun play(itemPosition: Int) {
|
||||||
|
view?.post {
|
||||||
|
if (itemPosition < tvListViewModel.size()) {
|
||||||
|
this.itemPosition = itemPosition
|
||||||
|
tvListViewModel.setItemPosition(itemPosition)
|
||||||
|
tvListViewModel.getTVViewModel(itemPosition)?.changed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun prev() {
|
||||||
|
view?.post {
|
||||||
|
itemPosition--
|
||||||
|
if (itemPosition == -1) {
|
||||||
|
itemPosition = tvListViewModel.size() - 1
|
||||||
|
}
|
||||||
|
tvListViewModel.setItemPosition(itemPosition)
|
||||||
|
tvListViewModel.getTVViewModel(itemPosition)?.changed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun next() {
|
||||||
|
view?.post {
|
||||||
|
itemPosition++
|
||||||
|
if (itemPosition == tvListViewModel.size()) {
|
||||||
|
itemPosition = 0
|
||||||
|
}
|
||||||
|
tvListViewModel.setItemPosition(itemPosition)
|
||||||
|
tvListViewModel.getTVViewModel(itemPosition)?.changed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun updateProgram(tvViewModel: TVViewModel) {
|
fun updateProgram(tvViewModel: TVViewModel) {
|
||||||
val timestamp = getDateTimestamp()
|
val timestamp = getDateTimestamp()
|
||||||
if (timestamp - tvViewModel.programUpdateTime > 60) {
|
if (timestamp - tvViewModel.programUpdateTime > 60) {
|
||||||
|
|
|
||||||
|
|
@ -74,10 +74,9 @@ class PlayerFragment : Fragment() {
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
fun play(tvViewModel: TVViewModel) {
|
fun play(tvViewModel: TVViewModel) {
|
||||||
this.tvViewModel = tvViewModel
|
this.tvViewModel = tvViewModel
|
||||||
val videoUrlCurrent =
|
val videoUrlCurrent = tvViewModel.getVideoUrlCurrent()
|
||||||
tvViewModel.videoIndex.value?.let { tvViewModel.videoUrl.value?.get(it) }
|
|
||||||
playerView?.player?.run {
|
playerView?.player?.run {
|
||||||
videoUrlCurrent?.let { setMediaItem(MediaItem.fromUri(it)) }
|
setMediaItem(MediaItem.fromUri(videoUrlCurrent))
|
||||||
prepare()
|
prepare()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -196,8 +196,6 @@ object TVList {
|
||||||
private fun setupTV(): Map<String, List<TV>> {
|
private fun setupTV(): Map<String, List<TV>> {
|
||||||
val tvs = """
|
val tvs = """
|
||||||
央视频道
|
央视频道
|
||||||
CCTV4K 超高清,
|
|
||||||
CCTV8K 超高清,
|
|
||||||
CCTV1 综合,http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226231/index.m3u8
|
CCTV1 综合,http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226231/index.m3u8
|
||||||
CCTV2 财经,http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226195/index.m3u8
|
CCTV2 财经,http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226195/index.m3u8
|
||||||
CCTV3 综艺,http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226397/index.m3u8
|
CCTV3 综艺,http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226397/index.m3u8
|
||||||
|
|
@ -216,6 +214,8 @@ CCTV14 少儿,http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226193/inde
|
||||||
CCTV15 音乐,http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225785/index.m3u8
|
CCTV15 音乐,http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225785/index.m3u8
|
||||||
CCTV16 奥林匹克,http://39.134.24.162/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226921/index.m3u8;http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226921/index.m3u8
|
CCTV16 奥林匹克,http://39.134.24.162/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226921/index.m3u8;http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226921/index.m3u8
|
||||||
CCTV17 农业农村,http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226198/index.m3u8
|
CCTV17 农业农村,http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226198/index.m3u8
|
||||||
|
CCTV4K 超高清,
|
||||||
|
CCTV8K 超高清,
|
||||||
风云剧场,http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226950/index.m3u8
|
风云剧场,http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226950/index.m3u8
|
||||||
第一剧场,http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226959/index.m3u8
|
第一剧场,http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226959/index.m3u8
|
||||||
怀旧剧场,http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226972/index.m3u8
|
怀旧剧场,http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226972/index.m3u8
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.lizongying.mytv
|
package com.lizongying.mytv
|
||||||
|
|
||||||
|
import android.content.res.Resources
|
||||||
|
import android.util.TypedValue
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
@ -12,4 +14,20 @@ object Utils {
|
||||||
fun getDateTimestamp(): Long {
|
fun getDateTimestamp(): Long {
|
||||||
return Date().time / 1000
|
return Date().time / 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun dpToPx(dp: Float): Int {
|
||||||
|
return TypedValue.applyDimension(
|
||||||
|
TypedValue.COMPLEX_UNIT_DIP,
|
||||||
|
dp,
|
||||||
|
Resources.getSystem().displayMetrics
|
||||||
|
).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun dpToPx(dp: Int): Int {
|
||||||
|
return TypedValue.applyDimension(
|
||||||
|
TypedValue.COMPLEX_UNIT_DIP,
|
||||||
|
dp.toFloat(),
|
||||||
|
Resources.getSystem().displayMetrics
|
||||||
|
).toInt()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -222,18 +222,25 @@ class TVViewModel(private var tv: TV) : ViewModel() {
|
||||||
mMinimumLoadableRetryCount = minimumLoadableRetryCount
|
mMinimumLoadableRetryCount = minimumLoadableRetryCount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (playerView?.player as ExoPlayer).setMediaSource(tvViewModel.buildSource())
|
||||||
|
*/
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
fun buildSource(videoUrl: String, mHeaders: Map<String, String>?): HlsMediaSource {
|
fun buildSource(): HlsMediaSource {
|
||||||
val httpDataSource = DefaultHttpDataSource.Factory()
|
val httpDataSource = DefaultHttpDataSource.Factory()
|
||||||
mHeaders?.let { httpDataSource.setDefaultRequestProperties(it) }
|
mHeaders?.let { httpDataSource.setDefaultRequestProperties(it) }
|
||||||
|
|
||||||
return HlsMediaSource.Factory(httpDataSource).createMediaSource(
|
return HlsMediaSource.Factory(httpDataSource).createMediaSource(
|
||||||
MediaItem.fromUri(
|
MediaItem.fromUri(
|
||||||
Uri.parse(videoUrl)
|
Uri.parse(getVideoUrlCurrent())
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getVideoUrlCurrent(): String {
|
||||||
|
return _videoUrl.value!![_videoIndex.value!!]
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "TVViewModel"
|
private const val TAG = "TVViewModel"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application' version '8.2.0' apply false
|
id 'com.android.application' version '8.2.1' apply false
|
||||||
id 'com.android.library' version '8.2.0' apply false
|
id 'com.android.library' version '8.2.1' apply false
|
||||||
id 'org.jetbrains.kotlin.android' version '1.9.21' apply false
|
id 'org.jetbrains.kotlin.android' version '1.9.21' apply false
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue