Skip to content

Commit

Permalink
support epg
Browse files Browse the repository at this point in the history
  • Loading branch information
lizongying committed Jul 6, 2024
1 parent 82395f9 commit 3cb45ce
Show file tree
Hide file tree
Showing 13 changed files with 157 additions and 21 deletions.
5 changes: 5 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## 更新日志

### v1.2.7

* 簡單支持EPG
* 類別樣式優化

### v1.2.6

* 解決切換頻道時黑屏問題
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ gen-version:

#make gen v=v1.1.3
gen:
echo $(v) | sed 's/v/ /g' | sed 's/\./ /g' | sed 's/-/ /g' | awk '{print "{\"version_code\": " ($$1*16777216)+($$2*65536)+($$3*256)+$$4 ", \"version_name\": \"" "$(v)" "\"}"}' > version.json
echo $(v) | sed 's/v/ /g' | sed 's/\./ /g' | sed 's/-/ /g' | awk '{print "{\"version_code\": " ($$1*16777216)+($$2*65536)+($$3*256)+$$4 ", \"version_name\": \"" "v$(v)" "\"}"}' > version.json

channels:
gua64 -f -e files/channels.json -o app/src/main/res/raw/channels.txt
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,8 @@ adb install my-tv-0.apk

## 赞赏

![image](./screenshots/appreciate.jpeg)
![image](./screenshots/appreciate.jpeg)

## 感谢

[live](https://github.com/fanmingming/live)
2 changes: 1 addition & 1 deletion app/src/main/java/com/lizongying/mytv0/GroupAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ class GroupAdapter(

fun focus(hasFocus: Boolean) {
if (hasFocus) {
binding.title.setTextColor(ContextCompat.getColor(context, R.color.white))
binding.title.setTextColor(ContextCompat.getColor(context, R.color.focus))
} else {
binding.title.setTextColor(
ContextCompat.getColor(
Expand Down
12 changes: 8 additions & 4 deletions app/src/main/java/com/lizongying/mytv0/InfoFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.graphics.Paint
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.os.Handler
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
Expand Down Expand Up @@ -106,10 +107,13 @@ class InfoFragment : Fragment() {
}
}

// val program = tvViewModel.getProgramOne()
// if (program != null) {
// binding.infoDesc.text = program.name
// }
val epg = tvViewModel.epg.value?.filter { it.beginTime < Utils.getDateTimestamp() }
Log.i(TAG, "info epg $epg")
if (!epg.isNullOrEmpty()) {
binding.desc.text = epg.last().title
} else {
binding.desc.text = ""
}

handler.removeCallbacks(removeRunnable)
view?.visibility = View.VISIBLE
Expand Down
2 changes: 0 additions & 2 deletions app/src/main/java/com/lizongying/mytv0/ListAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,6 @@ class ListAdapter(
if (hasFocus) {
binding.title.setTextColor(ContextCompat.getColor(context, R.color.white))
binding.description.setTextColor(ContextCompat.getColor(context, R.color.white))
// binding.root.alpha = 1.0F
binding.root.setBackgroundResource(R.color.focus)
} else {
binding.title.setTextColor(ContextCompat.getColor(context, R.color.title_blur))
Expand All @@ -229,7 +228,6 @@ class ListAdapter(
R.color.description_blur
)
)
// binding.root.alpha = 0.8F
binding.root.setBackgroundResource(R.color.blur)
}
}
Expand Down
9 changes: 8 additions & 1 deletion app/src/main/java/com/lizongying/mytv0/SP.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ object SP {

private const val KEY_PROXY = "proxy"

private const val KEY_EPG = "epg"

private lateinit var sp: SharedPreferences

/**
Expand Down Expand Up @@ -82,7 +84,8 @@ object SP {
set(value) = sp.edit().putBoolean(KEY_REPEAT_INFO, value).apply()

var config: String?
get() = sp.getString(KEY_CONFIG, "")
get() = sp.getString(KEY_CONFIG,
"")
set(value) = sp.edit().putString(KEY_CONFIG, value).apply()

var configAutoLoad: Boolean
Expand Down Expand Up @@ -120,4 +123,8 @@ object SP {
var proxy: String?
get() = sp.getString(KEY_PROXY, "")
set(value) = sp.edit().putString(KEY_PROXY, value).apply()

var epg: String?
get() = sp.getString(KEY_EPG, "https://live.fanmingming.com/e.xml")
set(value) = sp.edit().putString(KEY_EPG, value).apply()
}
21 changes: 13 additions & 8 deletions app/src/main/java/com/lizongying/mytv0/Utils.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.lizongying.mytv0

import android.content.Context
import android.content.res.Resources
import android.os.Build
import android.util.TypedValue
import com.google.gson.Gson
import com.lizongying.mytv0.requests.TimeResponse
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Date
Expand All @@ -29,13 +29,20 @@ object Utils {
}

suspend fun init() {
var currentTimeMillis: Long = 0
try {
currentTimeMillis = getTimestampFromServer()
val currentTimeMillis = getTimestampFromServer()
if (currentTimeMillis > 0) {
between = System.currentTimeMillis() - currentTimeMillis
}
} catch (e: Exception) {
println("Failed to retrieve timestamp from server: ${e.message}")
}
between = System.currentTimeMillis() - currentTimeMillis
}

init {
CoroutineScope(Dispatchers.IO).launch(Dispatchers.IO) {
init()
}
}

/**
Expand All @@ -44,9 +51,7 @@ object Utils {
*/
private suspend fun getTimestampFromServer(): Long {
return withContext(Dispatchers.IO) {
val client = okhttp3.OkHttpClient.Builder()
.connectTimeout(500, java.util.concurrent.TimeUnit.MILLISECONDS)
.readTimeout(1, java.util.concurrent.TimeUnit.SECONDS).build()
val client = okhttp3.OkHttpClient.Builder().build()
val request = okhttp3.Request.Builder()
.url("https://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp")
.build()
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/java/com/lizongying/mytv0/models/EPG.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.lizongying.mytv0.models


data class EPG(
val title: String,
val beginTime: Int,
)
52 changes: 52 additions & 0 deletions app/src/main/java/com/lizongying/mytv0/models/EPGXmlParser.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.lizongying.mytv0.models

import android.util.Xml
import org.xmlpull.v1.XmlPullParser
import java.io.InputStream
import java.text.SimpleDateFormat
import java.util.Locale


class EPGXmlParser {

private val ns: String? = null

private val epg = mutableMapOf<String, MutableList<EPG>>()

private fun formatFTime(s: String): Int {
val dateFormat = SimpleDateFormat("yyyyMMddHHmmss Z", Locale.getDefault())
val date = dateFormat.parse(s)
if (date != null) {
return (date.time / 1000).toInt()
}
return 0
}

fun parse(inputStream: InputStream): MutableMap<String, MutableList<EPG>> {
inputStream.use { inputStream ->
val parser: XmlPullParser = Xml.newPullParser()
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false)
parser.setInput(inputStream, null)
parser.nextTag()
var channel = ""
while (parser.eventType != XmlPullParser.END_DOCUMENT) {
if (parser.eventType != XmlPullParser.START_TAG) {
parser.next()
continue
}
if (parser.name == "channel") {
parser.nextTag()
channel = parser.nextText()
epg[channel] = mutableListOf()
} else if (parser.name == "programme") {
val start = parser.getAttributeValue(ns, "start")
parser.nextTag()
val title = parser.nextText()
epg[channel]?.add(EPG(title, formatFTime(start)))
}
parser.next()
}
}
return epg
}
}
50 changes: 48 additions & 2 deletions app/src/main/java/com/lizongying/mytv0/models/TVList.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ object TVList {
private lateinit var list: List<TV>
var listModel: List<TVModel> = listOf()
val groupModel = TVGroupModel()
private var epg = SP.epg

private val _position = MutableLiveData<Int>()
val position: LiveData<Int>
Expand Down Expand Up @@ -57,10 +58,44 @@ object TVList {
Toast.makeText(context, "读取频道失败,请在菜单中进行设置", Toast.LENGTH_LONG).show()
}

if (SP.configAutoLoad && !SP.config.isNullOrEmpty()) {
if (SP.config.isNullOrEmpty()) {
SP.config = "https://live.fanmingming.com/tv/m3u/index.m3u"
}

if (SP.configAutoLoad) {
SP.config?.let {
update(it)
}
} else if (!epg.isNullOrEmpty()) {
CoroutineScope(Dispatchers.IO).launch {
updateEPG()
}
}
}

private suspend fun updateEPG() {
// "EPG开始获取".showToast()
try {
val request = okhttp3.Request.Builder().url(epg!!).build()
val response = HttpClient.okHttpClient.newCall(request).execute()

if (response.isSuccessful) {
val epg = EPGXmlParser().parse(response.body()!!.byteStream())

withContext(Dispatchers.Main) {
for (m in listModel) {
epg[m.tv.name]?.let { m.setEpg(it) }
}
"EPG解析成功".showToast()
}
"EPG获取成功".showToast()
} else {
Log.e("", "request status ${response.code()}")
"EPG状态错误".showToast()
}
} catch (e: Exception) {
Log.e("", "request error $e")
"EPG请求错误".showToast()
}
}

Expand All @@ -82,6 +117,12 @@ object TVList {
file.writeText(str)
SP.config = serverUrl
"频道导入成功".showToast()

if (!epg.isNullOrEmpty()) {
CoroutineScope(Dispatchers.IO).launch {
updateEPG()
}
}
} else {
"频道导入错误".showToast()
}
Expand Down Expand Up @@ -146,6 +187,7 @@ object TVList {
if (string.isBlank()) {
return false
}

when (string[0]) {
'[' -> {
try {
Expand All @@ -163,12 +205,16 @@ object TVList {
val lines = string.lines()
val nameRegex = Regex("""tvg-name="([^"]+)"""")
val logRegex = Regex("""tvg-logo="([^"]+)"""")
val epgRegex = Regex("""x-tvg-url="([^"]+)"""")
val groupRegex = Regex("""group-title="([^"]+)"""")

val l = mutableListOf<TV>()
for ((index, line) in lines.withIndex()) {
val trimmedLine = line.trim()
if (trimmedLine.startsWith("#EXTINF")) {
if (trimmedLine.startsWith("#EXTM3U")) {
epg = epgRegex.find(trimmedLine)?.groupValues?.get(1)?.trim()
SP.epg = epg
} else if (trimmedLine.startsWith("#EXTINF")) {
val info = trimmedLine.split(",")
val title = info.last().trim()
val name = nameRegex.find(info.first())?.groupValues?.get(1)?.trim()
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/java/com/lizongying/mytv0/models/TVModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ class TVModel(var tv: TV) : ViewModel() {
_errInfo.value = info
}

private var _epg = MutableLiveData<MutableList<EPG>>()
val epg: LiveData<MutableList<EPG>>
get() = _epg

fun setEpg(epg: MutableList<EPG>) {
_epg.value = epg
}

private var _program = MutableLiveData<MutableList<Program>>()
val program: LiveData<MutableList<Program>>
get() = _program
Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version_code": 16909824, "version_name": "1.2.6"}
{"version_code": 16910080, "version_name": "v1.2.7"}

0 comments on commit 3cb45ce

Please sign in to comment.