Skip to content

Commit

Permalink
optimize EPG
Browse files Browse the repository at this point in the history
  • Loading branch information
lizongying committed Dec 20, 2024
1 parent b4e7792 commit eca2257
Show file tree
Hide file tree
Showing 14 changed files with 189 additions and 90 deletions.
8 changes: 8 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
## 更新日誌

### v1.3.8.9-kitkat

* 優化EPG

### v1.3.8.9

* 優化EPG

### v1.3.8.8-kitkat

* 通過網絡獲取默認視頻源列表
Expand Down
75 changes: 75 additions & 0 deletions app/src/main/java/com/lizongying/mytv0/ImageHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.lizongying.mytv0

import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Handler
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target

fun loadNextUrl(
context: Context,
imageView: ImageView,
bitmap: Bitmap,
urlList: List<String>,
index: Int,
handler: Handler,
onSuccess: (Int) -> Unit
) {
if (urlList.isEmpty()) {
return
}
if (index >= urlList.size) {
return
}
val url = urlList[index]
if (url.isEmpty()) {
Glide.with(context)
.load(bitmap)
.fitCenter()
.into(imageView)
} else {
Glide.with(context)
.load(url)
.listener(object : RequestListener<Drawable> {
override fun onResourceReady(
resource: Drawable,
model: Any,
target: Target<Drawable>?,
dataSource: DataSource,
isFirstResource: Boolean
): Boolean {
onSuccess(index)
return false
}

override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>,
isFirstResource: Boolean
): Boolean {
handler.post {
loadNextUrl(
context,
imageView,
bitmap,
urlList,
index + 1,
handler,
onSuccess
)
}
return true
}
})
.placeholder(BitmapDrawable(context.resources, bitmap))
.fitCenter()
.into(imageView)
}
}
26 changes: 12 additions & 14 deletions app/src/main/java/com/lizongying/mytv0/InfoFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.lizongying.mytv0
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.os.Handler
import android.util.Log
Expand All @@ -15,7 +14,7 @@ import androidx.core.view.marginBottom
import androidx.core.view.marginStart
import androidx.core.view.marginTop
import androidx.fragment.app.Fragment
import com.bumptech.glide.Glide
import com.lizongying.mytv0.Utils.getUrls
import com.lizongying.mytv0.databinding.InfoBinding
import com.lizongying.mytv0.models.TVModel

Expand Down Expand Up @@ -104,18 +103,17 @@ class InfoFragment : Fragment() {
val y = height / 2f - (paint.descent() + paint.ascent()) / 2
canvas.drawText(text, x, y, paint)

if (tvModel.tv.logo.isNullOrBlank()) {
Glide.with(this)
.load(BitmapDrawable(context.resources, bitmap))
// .centerInside()
.into(binding.logo)
} else {
Glide.with(this)
.load(tvModel.tv.logo)
// .placeholder(BitmapDrawable(context.resources, bitmap))
.error(BitmapDrawable(context.resources, bitmap))
// .centerInside()
.into(binding.logo)
val url = tvModel.tv.logo
val name = tvModel.tv.name
var urls =
getUrls(
"live.fanmingming.com/tv/$name.png"
) + getUrls("https://raw.githubusercontent.com/fanmingming/live/main/tv/$name.png")
if (url.isNotEmpty()) {
urls = (getUrls(url) + urls).distinct()
}
loadNextUrl(context, binding.logo, bitmap, urls, 0, handler) {
tvModel.tv.logo = urls[it]
}
}
}
Expand Down
33 changes: 17 additions & 16 deletions app/src/main/java/com/lizongying/mytv0/ListAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.drawable.BitmapDrawable
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.KeyEvent
import android.view.LayoutInflater
Expand All @@ -18,7 +19,7 @@ import androidx.core.view.marginStart
import androidx.core.view.setPadding
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.lizongying.mytv0.Utils.getUrls
import com.lizongying.mytv0.databinding.ListItemBinding
import com.lizongying.mytv0.models.TVListModel
import com.lizongying.mytv0.models.TVModel
Expand Down Expand Up @@ -175,19 +176,22 @@ class ListAdapter(

viewHolder.bindTitle(tvModel.tv.title)

viewHolder.bindImage(tvModel.tv.logo, tvModel.tv.id)
viewHolder.bindImage(tvModel.tv.logo, tvModel.tv.id, tvModel.tv.name, tvModel)
}
}

override fun getItemCount() = listTVModel?.size() ?: 0

class ViewHolder(private val context: Context, val binding: ListItemBinding) :
RecyclerView.ViewHolder(binding.root) {

val handler = Handler(Looper.getMainLooper())

fun bindTitle(text: String) {
binding.title.text = text
}

fun bindImage(url: String?, id: Int) {
fun bindImage(url: String?, id: Int, name: String, tvModel: TVModel) {
val width = Utils.dpToPx(40)
val height = Utils.dpToPx(40)
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
Expand All @@ -203,18 +207,15 @@ class ListAdapter(
val y = height / 2f - (paint.descent() + paint.ascent()) / 2
canvas.drawText(text, x, y, paint)

if (url.isNullOrBlank()) {
Glide.with(context)
.load(BitmapDrawable(context.resources, bitmap))
.centerInside()
.into(binding.icon)
// binding.imageView.setImageDrawable(null)
} else {
Glide.with(context)
.load(url)
.centerInside()
.error(BitmapDrawable(context.resources, bitmap))
.into(binding.icon)
var urls =
getUrls(
"live.fanmingming.com/tv/$name.png"
) + getUrls("https://raw.githubusercontent.com/fanmingming/live/main/tv/$name.png")
if (!url.isNullOrEmpty()) {
urls = (getUrls(url) + urls).distinct()
}
loadNextUrl(context, binding.icon, bitmap, urls, 0, handler) {
tvModel.tv.logo = urls[it]
}
}

Expand Down
75 changes: 33 additions & 42 deletions app/src/main/java/com/lizongying/mytv0/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.google.gson.JsonSyntaxException
import com.lizongying.mytv0.R
import com.lizongying.mytv0.SP
import com.lizongying.mytv0.Utils.getDateFormat
import com.lizongying.mytv0.Utils.getUrls
import com.lizongying.mytv0.bodyAlias
import com.lizongying.mytv0.codeAlias
import com.lizongying.mytv0.data.Source
Expand Down Expand Up @@ -39,6 +40,8 @@ class MainViewModel : ViewModel() {
private var cacheChannels = ""
private var initialized = false

private var epgUrl = SP.epg

val sources = Sources()

private val _channelsOk = MutableLiveData<Boolean>()
Expand All @@ -55,8 +58,12 @@ class MainViewModel : ViewModel() {
}

fun updateEPG() {
if (!SP.epg.isNullOrEmpty()) {
viewModelScope.launch {
viewModelScope.launch {
var success = false
if (!epgUrl.isNullOrEmpty()) {
success = updateEPG(epgUrl!!)
}
if (!success && !SP.epg.isNullOrEmpty()) {
updateEPG(SP.epg!!)
}
}
Expand All @@ -69,9 +76,7 @@ class MainViewModel : ViewModel() {
viewModelScope.launch {
Log.i(TAG, "updateConfig $it")
importFromUrl(it)
SP.epg?.let { i ->
updateEPG(i)
}
updateEPG()
}
}
}
Expand Down Expand Up @@ -99,8 +104,9 @@ class MainViewModel : ViewModel() {
cacheChannels = getCache()

if (cacheChannels.isEmpty()) {
cacheChannels = context.resources.openRawResource(DEFAULT_CHANNELS_FILE).bufferedReader()
.use { it.readText() }
cacheChannels =
context.resources.openRawResource(DEFAULT_CHANNELS_FILE).bufferedReader()
.use { it.readText() }
}

Log.i(TAG, "cacheChannels $cacheChannels")
Expand All @@ -118,12 +124,15 @@ class MainViewModel : ViewModel() {
_channelsOk.value = true
}

private suspend fun updateEPG(epg: String) {
var shouldBreak = false
val request = okhttp3.Request.Builder().url(epg).build()
for (i in 0..2) {
private suspend fun updateEPG(url: String): Boolean {
val urls = getUrls(url)

var success = false
for (a in urls) {
Log.i(TAG, "request $a")
try {
withContext(Dispatchers.IO) {
val request = okhttp3.Request.Builder().url(a).build()
val response = HttpClient.okHttpClient.newCall(request).execute()

if (response.isSuccessful) {
Expand All @@ -136,61 +145,43 @@ class MainViewModel : ViewModel() {
continue
}

for ((a, b) in res) {
if (name.contains(a, ignoreCase = true)) {
m.setEpg(b)
for ((n, epg) in res) {
if (name.contains(n, ignoreCase = true)) {
m.setEpg(epg)
if (m.tv.logo.isEmpty()) {
m.tv.logo = "https://live.fanmingming.com/tv/$a.png"
m.tv.logo = "https://live.fanmingming.com/tv/$n.png"
}
break
}
}
}
}

shouldBreak = true
success = true
Log.i(TAG, "EPG success")
} else {
Log.e(TAG, "EPG ${response.codeAlias()}")
}
}
} catch (e: Exception) {
Log.i(TAG, "EPG request error:", e)
Log.i(TAG, "EPG request error: $a", e)
// R.string.epg_request_err.showToast()
}

if (shouldBreak) {
if (success) {
break
}
}

if (!shouldBreak) {
if (!success) {
// R.string.epg_status_err.showToast()
}

return success
}

private suspend fun importFromUrl(url: String, id: String = "") {
val urls =
if (url.startsWith("https://raw.githubusercontent.com") || url.startsWith("https://github.com")) {
listOf(
"https://ghp.ci/",
"https://gh.llkk.cc/",
"https://github.moeyy.xyz/",
"https://mirror.ghproxy.com/",
"https://ghproxy.cn/",
"https://ghproxy.net/",
"https://ghproxy.click/",
"https://ghproxy.com/",
"https://github.moeyy.cn/",
"https://gh-proxy.llyke.com/",
"https://www.ghproxy.cc/",
"https://cf.ghproxy.cc/"
).map {
Pair("$it$url", url)
}
} else {
listOf(Pair(url, url))
}
val urls = getUrls(url).map { Pair(it, url) }

var err = 0
var shouldBreak = false
Expand Down Expand Up @@ -343,7 +334,7 @@ class MainViewModel : ViewModel() {
for ((index, line) in lines.withIndex()) {
val trimmedLine = line.trim()
if (trimmedLine.startsWith("#EXTM3U")) {
SP.epg = epgRegex.find(trimmedLine)?.groupValues?.get(1)?.trim()
epgUrl = epgRegex.find(trimmedLine)?.groupValues?.get(1)?.trim()
} else if (trimmedLine.startsWith("#EXTINF")) {
val info = trimmedLine.split(",")
val title = info.last().trim()
Expand Down Expand Up @@ -380,7 +371,7 @@ class MainViewModel : ViewModel() {
val t1 = TV(
-1,
t0.name,
t0.name,
t0.title,
"",
t0.logo,
"",
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/lizongying/mytv0/SP.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ object SP {
const val DEFAULT_TIME = true
const val DEFAULT_BOOT_STARTUP = false
const val DEFAULT_PROXY = ""
const val DEFAULT_EPG = "https://live.fanmingming.com/e.xml"
const val DEFAULT_EPG = "https://raw.githubusercontent.com/fanmingming/live/main/e.xml"
const val DEFAULT_CHANNEL = 0
const val DEFAULT_SHOW_ALL_CHANNELS = false
const val DEFAULT_COMPACT_MENU = true
const val DEFAULT_DISPLAY_SECONDS = false
const val DEFAULT_DISPLAY_SECONDS = true
const val DEFAULT_LOG_TIMES = 10

// 0 favorite; 1 all
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/com/lizongying/mytv0/SimpleServer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ class SimpleServer(private val context: Context, private val viewModel: MainView
val req = Gson().fromJson(it, ReqSettings::class.java)
if (req.epg != null) {
SP.epg = req.epg
viewModel.updateEPG()
R.string.default_epg_set_success.showToast()
} else {
R.string.default_epg_set_failure.showToast()
Expand Down
Loading

0 comments on commit eca2257

Please sign in to comment.