Skip to content

Commit 0b1a437

Browse files
committed
support tvg-chno
1 parent 067bcf7 commit 0b1a437

File tree

13 files changed

+151
-65
lines changed

13 files changed

+151
-65
lines changed

.github/workflows/build.yml

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@ jobs:
2222
distribution: 'temurin'
2323
cache: 'gradle'
2424

25+
- name: Run build with Gradle wrapper
26+
run: ./gradlew clean && ./gradlew assembleRelease
27+
28+
- name: Sign app APK
29+
id: sign_app
30+
uses: r0adkll/sign-android-release@v1
31+
with:
32+
releaseDirectory: app/build/outputs/apk/release
33+
alias: ${{ secrets.ALIAS }}
34+
signingKeyBase64: ${{ secrets.KEYSTORE }}
35+
keyStorePassword: ${{ secrets.KEYSTORE_PASSWORD }}
36+
keyPassword: ${{ secrets.ALIAS_PASSWORD }}
37+
env:
38+
# override default build-tools version (29.0.3) -- optional
39+
BUILD_TOOLS_VERSION: "34.0.0"
40+
2541
- name: Get History
2642
id: get_history
2743
run: |
@@ -41,22 +57,6 @@ jobs:
4157
prerelease: false
4258
body_path: history.md
4359

44-
- name: Run build with Gradle wrapper
45-
run: ./gradlew clean && ./gradlew assembleRelease
46-
47-
- name: Sign app APK
48-
id: sign_app
49-
uses: r0adkll/sign-android-release@v1
50-
with:
51-
releaseDirectory: app/build/outputs/apk/release
52-
alias: ${{ secrets.ALIAS }}
53-
signingKeyBase64: ${{ secrets.KEYSTORE }}
54-
keyStorePassword: ${{ secrets.KEYSTORE_PASSWORD }}
55-
keyPassword: ${{ secrets.ALIAS_PASSWORD }}
56-
env:
57-
# override default build-tools version (29.0.3) -- optional
58-
BUILD_TOOLS_VERSION: "34.0.0"
59-
6060
- name: Set Asset Name
6161
id: set_asset_name
6262
run: |

HISTORY.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## 更新日誌
22

3+
### v1.3.9.3
4+
5+
* 支持m3u設置tvg-chno
6+
37
### v1.3.9.2
48

59
* 優化手機上遠程配置

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
* m3u
3232
```
3333
#EXTM3U x-tvg-url=""
34-
#EXTINF:-1 tvg-id="" tvg-name="標準標題" tvg-logo="图标" group-title="組名",標題
34+
#EXTINF:-1 tvg-id="" tvg-chno="" tvg-name="標準標題" tvg-logo="图标" group-title="組名",標題
3535
#EXTVLCOPT:http-user-agent=
3636
#EXTVLCOPT:http-referrer=
3737
視頻地址
@@ -44,6 +44,7 @@
4444
"name": "標準標題",
4545
"title": "標題",
4646
"logo": "图标",
47+
"number": "頻道號",
4748
"uris": [
4849
"視頻地址"
4950
],
@@ -86,6 +87,12 @@ adb install my-tv-0.apk
8687
* 支持回看
8788
* 淺色菜單
8889

90+
## 常見問題
91+
92+
* 為什麼遠程配置視頻源文本後,再次打開應用後又恢復到原來的配置?
93+
94+
如果“應用啟動后更新視頻源”開啟後,且存在視頻源地址,則會自動更新,可能會覆蓋已保存的視頻源文本。
95+
8996
## 讚賞
9097

9198
![image](./screenshots/appreciate.png)

app/src/main/java/com/lizongying/mytv0/ChannelFragment.kt

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.lizongying.mytv0
33
import MainViewModel
44
import android.os.Bundle
55
import android.os.Handler
6+
import android.util.Log
67
import android.view.LayoutInflater
78
import android.view.View
89
import android.view.ViewGroup
@@ -60,14 +61,17 @@ class ChannelFragment : Fragment() {
6061
handler.removeCallbacks(hideRunnable)
6162
handler.removeCallbacks(playRunnable)
6263
if (_binding != null) {
63-
binding.content.text = (tvViewModel.tv.id.plus(1)).toString()
64+
binding.content.text =
65+
if (tvViewModel.tv.number == -1) (tvViewModel.tv.id.plus(1)).toString() else tvViewModel.tv.number.toString()
6466
}
6567
view?.visibility = View.VISIBLE
6668
handler.postDelayed(hideRunnable, delay)
6769
}
6870

6971
fun show(channel: String) {
70-
if (viewModel.groupModel.getCurrent()!!.tv.id > 10 && viewModel.groupModel.getCurrent()!!.tv.id == this.channel - 1) {
72+
Log.d(TAG, "input $channel")
73+
val tv = viewModel.groupModel.getCurrent()!!.tv
74+
if (tv.id > 10 && tv.id == this.channel - 1) {
7175
this.channel = 0
7276
channelCount = 0
7377
}
@@ -78,9 +82,10 @@ class ChannelFragment : Fragment() {
7882
this.channel = "${this.channel}$channel".toInt()
7983
handler.removeCallbacks(hideRunnable)
8084
handler.removeCallbacks(playRunnable)
85+
Log.d(TAG, "channelCount $channelCount")
86+
binding.content.text = this.channel.toString()
87+
view?.visibility = View.VISIBLE
8188
if (channelCount < 3) {
82-
binding.content.text = this.channel.toString()
83-
view?.visibility = View.VISIBLE
8489
handler.postDelayed(playRunnable, delay)
8590
} else {
8691
handler.postDelayed(playRunnable, 0)
@@ -102,6 +107,7 @@ class ChannelFragment : Fragment() {
102107

103108
private val hideRunnable = Runnable {
104109
if (_binding != null) {
110+
Log.i(TAG, "channel num zero")
105111
binding.content.text = BLANK
106112
}
107113

@@ -110,8 +116,16 @@ class ChannelFragment : Fragment() {
110116
channelCount = 0
111117
}
112118

119+
fun hideSelf() {
120+
handler.postDelayed(hideRunnable, 0)
121+
}
122+
113123
private val playRunnable = Runnable {
114-
(activity as MainActivity).play(channel - 1)
124+
var c = channel - 1
125+
viewModel.listModel.find { it.tv.number == channel }?.let {
126+
c = it.tv.id
127+
}
128+
(activity as MainActivity).play(c)
115129
handler.postDelayed(hideRunnable, delay)
116130
}
117131

app/src/main/java/com/lizongying/mytv0/ImageHelper.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class ImageHelper(private val context: Context) {
5454
) {
5555
val file = files[key]
5656
if (file != null) {
57-
Log.i(TAG, "image exists ${file.absolutePath}")
57+
Log.d(TAG, "image exists ${file.absolutePath}")
5858
return
5959
}
6060

app/src/main/java/com/lizongying/mytv0/MainActivity.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,11 @@ class MainActivity : AppCompatActivity() {
614614
return
615615
}
616616

617+
if (channelFragment.isAdded && !channelFragment.isHidden) {
618+
channelFragment.hideSelf()
619+
return
620+
}
621+
617622
if (doubleBackToExitPressedOnce) {
618623
super.onBackPressed()
619624
return

app/src/main/java/com/lizongying/mytv0/MainViewModel.kt

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class MainViewModel : ViewModel() {
8484
SP.configUrl?.let {
8585
if (it.startsWith("http")) {
8686
viewModelScope.launch {
87-
Log.i(TAG, "updateConfig $it")
87+
Log.i(TAG, "update config url: $it")
8888
importFromUrl(it)
8989
updateEPG()
9090
}
@@ -117,12 +117,13 @@ class MainViewModel : ViewModel() {
117117
cacheChannels = getCache()
118118

119119
if (cacheChannels.isEmpty()) {
120+
Log.i(TAG, "cacheChannels isEmpty")
120121
cacheChannels =
121122
context.resources.openRawResource(DEFAULT_CHANNELS_FILE).bufferedReader()
122123
.use { it.readText() }
123124
}
124125

125-
Log.i(TAG, "cacheChannels $cacheChannels")
126+
Log.i(TAG, "cacheChannels $cacheFile $cacheChannels")
126127

127128
try {
128129
str2Channels(cacheChannels)
@@ -344,7 +345,9 @@ class MainViewModel : ViewModel() {
344345
fun tryStr2Channels(str: String, file: File?, url: String, id: String = "") {
345346
try {
346347
if (str2Channels(str)) {
348+
Log.i(TAG, "write to cacheFile $cacheFile $str")
347349
cacheFile!!.writeText(str)
350+
Log.i(TAG, "cacheFile ${getCache()}")
348351
cacheChannels = str
349352
if (url.isNotEmpty()) {
350353
SP.configUrl = url
@@ -358,11 +361,13 @@ class MainViewModel : ViewModel() {
358361
}
359362
_channelsOk.value = true
360363
R.string.channel_import_success.showToast()
364+
Log.i(TAG, "channel import success")
361365
} else {
362366
R.string.channel_import_error.showToast()
367+
Log.w(TAG, "channel import error")
363368
}
364369
} catch (e: Exception) {
365-
e.printStackTrace()
370+
Log.e(TAG, "tryStr2Channels", e)
366371
file?.deleteOnExit()
367372
R.string.channel_read_error.showToast()
368373
}
@@ -407,6 +412,7 @@ class MainViewModel : ViewModel() {
407412
val lines = string.lines()
408413
val nameRegex = Regex("""tvg-name="([^"]+)"""")
409414
val logRegex = Regex("""tvg-logo="([^"]+)"""")
415+
val numRegex = Regex("""tvg-chno="([^"]+)"""")
410416
val epgRegex = Regex("""x-tvg-url="([^"]+)"""")
411417
val groupRegex = Regex("""group-title="([^"]+)"""")
412418

@@ -422,7 +428,6 @@ class MainViewModel : ViewModel() {
422428
if (trimmedLine.startsWith("#EXTM3U")) {
423429
epgUrl = epgRegex.find(trimmedLine)?.groupValues?.get(1)?.trim()
424430
} else if (trimmedLine.startsWith("#EXTINF")) {
425-
Log.i(TAG, "TV $tv")
426431
val key = tv.group + tv.name
427432
if (key.isNotEmpty()) {
428433
tvMap[key] =
@@ -434,6 +439,8 @@ class MainViewModel : ViewModel() {
434439
var name = nameRegex.find(info.first())?.groupValues?.get(1)?.trim()
435440
tv.name = if (name.isNullOrEmpty()) tv.title else name
436441
tv.logo = logRegex.find(info.first())?.groupValues?.get(1)?.trim() ?: ""
442+
tv.number =
443+
numRegex.find(info.first())?.groupValues?.get(1)?.trim()?.toInt() ?: -1
437444
tv.group = groupRegex.find(info.first())?.groupValues?.get(1)?.trim() ?: ""
438445
} else if (trimmedLine.startsWith("#EXTVLCOPT:http-")) {
439446
val keyValue =
@@ -476,6 +483,7 @@ class MainViewModel : ViewModel() {
476483
t0.headers,
477484
t0.group,
478485
SourceType.UNKNOWN,
486+
t0.number,
479487
emptyList(),
480488
)
481489
l.add(t1)
@@ -525,12 +533,14 @@ class MainViewModel : ViewModel() {
525533
emptyMap(),
526534
channelGroup,
527535
SourceType.UNKNOWN,
536+
-1,
528537
emptyList(),
529538
)
530539

531540
l.add(tv)
532541
}
533542
list = l
543+
Log.d(TAG, "导入频道 $list")
534544
Log.i(TAG, "导入频道 ${list.size}")
535545
}
536546
}
@@ -565,6 +575,10 @@ class MainViewModel : ViewModel() {
565575

566576
listModel = listModelNew
567577

578+
for (ii in listModel) {
579+
Log.d(TAG, "${ii.tv.title} ${ii.tv.number}")
580+
}
581+
568582
// 全部频道
569583
groupModel.tvGroupValue[1].setTVListModel(listModel)
570584

app/src/main/java/com/lizongying/mytv0/SP.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ object SP {
6161
private const val KEY_SOFT_DECODE = "soft_decode"
6262

6363
const val DEFAULT_CHANNEL_REVERSAL = false
64-
const val DEFAULT_CONFIG_URL = ""
6564
const val DEFAULT_CHANNEL_NUM = false
6665
const val DEFAULT_TIME = true
6766
const val DEFAULT_BOOT_STARTUP = false
67+
const val DEFAULT_CONFIG_URL = ""
6868
const val DEFAULT_PROXY = ""
6969
const val DEFAULT_EPG =
7070
"https://live.fanmingming.cn/e.xml,https://raw.githubusercontent.com/fanmingming/live/main/e.xml"

app/src/main/java/com/lizongying/mytv0/SimpleServer.kt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ class SimpleServer(private val context: Context, private val viewModel: MainView
4343
return when (session.uri) {
4444
"/api/settings" -> handleSettings()
4545
"/api/sources" -> handleSources()
46-
"/api/import-text" -> handleImportFromText(session)
47-
"/api/import-uri" -> handleImportFromUri(session)
46+
"/api/import-text" -> handleImportText(session)
47+
"/api/import-uri" -> handleImportUri(session)
4848
"/api/proxy" -> handleProxy(session)
4949
"/api/epg" -> handleEPG(session)
50-
"/api/channel" -> handleDefaultChannel(session)
50+
"/api/default-channel" -> handleDefaultChannel(session)
5151
"/api/remove-source" -> handleRemoveSource(session)
5252
else -> handleStaticContent()
5353
}
@@ -96,7 +96,6 @@ class SimpleServer(private val context: Context, private val viewModel: MainView
9696
e.message
9797
)
9898
}
99-
10099
return newFixedLengthResponse(Response.Status.OK, "application/json", response)
101100
}
102101

@@ -141,7 +140,7 @@ class SimpleServer(private val context: Context, private val viewModel: MainView
141140
)
142141
}
143142

144-
private fun handleImportFromText(session: IHTTPSession): Response {
143+
private fun handleImportText(session: IHTTPSession): Response {
145144
R.string.start_config_channel.showToast()
146145
val response = ""
147146
try {
@@ -151,7 +150,7 @@ class SimpleServer(private val context: Context, private val viewModel: MainView
151150
}
152151
}
153152
} catch (e: Exception) {
154-
Log.e(TAG, "handleImportFromText", e)
153+
Log.e(TAG, "handleImportText", e)
155154
return newFixedLengthResponse(
156155
Response.Status.INTERNAL_ERROR,
157156
MIME_PLAINTEXT,
@@ -161,7 +160,7 @@ class SimpleServer(private val context: Context, private val viewModel: MainView
161160
return newFixedLengthResponse(Response.Status.OK, "text/plain", response)
162161
}
163162

164-
private fun handleImportFromUri(session: IHTTPSession): Response {
163+
private fun handleImportUri(session: IHTTPSession): Response {
165164
R.string.start_config_channel.showToast()
166165
val response = ""
167166
try {
@@ -173,7 +172,7 @@ class SimpleServer(private val context: Context, private val viewModel: MainView
173172
}
174173
}
175174
} catch (e: Exception) {
176-
Log.e(TAG, "handleImportFromUri", e)
175+
Log.e(TAG, "handleImportUri", e)
177176
return newFixedLengthResponse(
178177
Response.Status.INTERNAL_ERROR,
179178
MIME_PLAINTEXT,

app/src/main/java/com/lizongying/mytv0/data/TV.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ data class TV(
1414
var headers: Map<String, String>? = null,
1515
var group: String = "",
1616
var sourceType: SourceType = SourceType.UNKNOWN,
17+
var number: Int = -1,
1718
var child: List<TV> = emptyList(),
1819
) : Serializable {
1920

@@ -29,6 +30,7 @@ data class TV(
2930
", headers=" + headers +
3031
", group='" + group + '\'' +
3132
", sourceType='" + sourceType + '\'' +
33+
", number=" + number +
3234
'}'
3335
}
3436
}

0 commit comments

Comments
 (0)