Compare commits

...
23 Commits
Author SHA1 Message Date
Li ZongYing c16a4bcb9c optimize time 2024-05-09 22:26:37 +08:00
Li ZongYing 0286d118ed fix update 2024-05-07 17:55:08 +08:00
Li ZongYing fc83defe31 optimize version check 2024-05-07 12:56:34 +08:00
Li ZongYing 6fc73efd47 optimize version check 2024-05-07 12:55:11 +08:00
Li ZongYing b157f1eb28 fix time 2024-05-07 11:38:10 +08:00
Li ZongYing 2b172ae615 fix retry bug 2024-05-01 17:00:33 +08:00
Li ZongYing 39e5cc7c1f opitimize request 2024-05-01 16:52:33 +08:00
Li ZongYing df5b006024 optimize style 2024-04-29 12:12:59 +08:00
Li ZongYing fe888c36ac left->start 2024-04-27 19:11:08 +08:00
Li ZongYing 5aa08f51a1 error page 2024-04-26 19:57:12 +08:00
Li ZongYing fe92fa5853 optimize style 2024-04-25 22:36:37 +08:00
Li ZongYing 3d8ab65955 fix ysp 2024-04-23 19:41:30 +08:00
Li ZongYing 5485a686bc fix crash on 4.2 2024-04-19 20:13:43 +08:00
Li ZongYing 716efb5a83 change style 2024-04-19 19:26:06 +08:00
Li ZongYing ca82d5409f add time 2024-04-18 10:21:54 +08:00
Li ZongYing 3936629af8 add epg 2024-04-02 22:57:39 +08:00
Li ZongYing bb88e754a5 fix 368 2024-03-29 17:04:11 +08:00
Li ZongYing 49e96d18f4 fix version code 2024-03-17 09:38:46 +08:00
Li ZongYing 43343f8faa fix version code 2024-03-17 09:35:34 +08:00
Li ZongYing 0335f58a12 fix version name 2024-03-16 16:17:10 +08:00
Li ZongYing 9450de2c91 menu style 2024-03-16 13:14:14 +08:00
Li ZongYing d03de91c1e request optimize 2024-03-16 10:44:55 +08:00
Li ZongYing 7057e4a8b4 request optimize 2024-03-15 22:32:43 +08:00
109 changed files with 7468 additions and 2957 deletions
+314
View File
@@ -0,0 +1,314 @@
## 更新日志
### v1.9.8(通用)
* 优化在线升级
* 优化可能状态错误的问题
### v1.9.6(通用)
* 优化在线升级
* 优化可能状态错误的问题
### v1.9.4(通用)
* 修复默认时间不显示问题
* 设置页居中
* 频道号和时间对齐
### v1.9.2(通用)
* 修复一个重试的错误
### v1.9.0(通用)
* 减少视频播放失败情况
* 全面屏手机居中显示
### v1.8.8(通用)
* 样式优化
### v1.8.6(通用)
* 增加错误显示
* 节目预告优化
* 频道列表页单击切换频道
### v1.8.4(通用)
* 解決部分情況下打開後黑屏问题
* 延长频道信息显示时间,增加信息显示长度
* 调整频道列表间距
* 其他样式优化
### v1.8.2(通用)
* 修复无法播放问题
### 以下已不可用
### v1.8.0(通用)
* 修复返回键无法退出问题
* 设置中增加退出按钮
* 修改非电视上的样式
* 修复低版本闪退问题
### v1.7.8(通用)
* 修复播放过程中的卡顿问题
* 增加时间显示
* 频道号优化
* 遥控器左键打开频道列表
* 遥控器右键打开设置菜单
* 频道列表空白处点击隐藏频道列表
### v1.7.6(通用)
* 临时去掉部分频道,提高频道的可用性
* 部分频道增加节目单
### v1.7.5(安卓5及以上专用)
* 修复播放过程中的卡顿问题
* 增加时间显示
* 频道号优化
* 设置中增加退出按钮
### v1.7.4(通用)
* 修复368
### v1.7.3(安卓5及以上专用)
* 临时去掉部分频道,提高频道的可用性
* 部分频道增加节目单
* 遥控器左键进入节目列表
* 遥控器右键进入菜单
### v1.7.2(通用)
* 支持节目列表网格样式和行样式切换,软件重启后生效
* 节目列表样式变更
### v1.7.1(安卓5及以上专用)
* 解决设置页更新闪退的问题
* 凤凰卫视回归
* 解决368问题
### v1.7.0(通用)
* 网络请求优化
### v1.6.9(安卓5及以上专用)
* 去掉港澳台和国际频道
* 解决部分情况下3、6、8等频道无法播放的问题
* 解决部分情况下启动后黑屏问题
### v1.6.8(通用)
* 修复部分设备崩溃的问题
* 修复部分设备凤凰卫视无法播放的问题
### v1.6.7(安卓5及以上专用)
* 手机双击打开配置
* 自动更新
### v1.6.6(通用)
* 更新重庆卫视图标
* 凤凰卫视增强画质
* 凤凰卫视增加EPG
### v1.6.5(安卓5及以上专用)
* 增加CETV1图标
* 稳定性提升
### v1.6.4(通用)
* 增加CETV1
* 增加凤凰卫视
* 默认关闭开机启动
### v1.6.3(安卓5及以上专用)
* 增加CETV1
* 凤凰卫视增强画质
* 默认关闭开机启动
* 延迟菜单自动关闭时间
* 解决一些可能导致首次打开时黑屏的问题
### v1.6.2(通用)
* 修复按键无效的问题
* 新的频道列表样式
### v1.6.1(安卓5及以上专用)
* 增加凤凰卫视
### v1.6.0(通用)
* 通用(春晚緊急修復)
### v1.5.9(安卓5及以上专用)
* 解决天猫魔盒闪退问题
### v1.5.8(通用)
* 修复央视6画质差的问题
* 增加兵团卫视
* 播放失败重试
### v1.5.7(安卓5及以上专用)
* 修复播放失败的问题
### v1.5.6(通用)
* 解决部分设备系统时间不对导致播放失败的问题
### v1.5.5(安卓5及以上专用)
* 修复播放失败的问题
* 修复APP恢复后频道号、频道列表不自动消失的问题
### v1.5.4(通用)
* 修复播放失败的问题
### v1.5.3(安卓5及以上专用)
* 修复部分情况下APP切换后无法继续播放的问题
* 优化重试逻辑
### v1.5.2(通用)
* 修复APP恢复后频道号、频道列表不自动消失的问题
### v1.5.1(安卓5及以上专用)
* 性能优化
### v1.5.0(通用)
* 修复部分情况下APP切换后无法继续播放的问题
### v1.4.9(安卓5及以上专用)
* 同步v1.4.8
### v1.4.8(通用)
* 频道号从1开始,CCTV5+为18
* 提高CCTV6清晰度
* 增加天津卫视、新疆卫视
### v1.4.7(安卓5及以上专用)
* 修复部分用户CCTV13播放过程中卡住的问题
* 调整CCTV的频道顺序
### v1.4.6(通用)
* 10以下频道不再需要先按0
### v1.4.5(安卓5及以上专用)
* 数字选台配置
### v1.4.4(通用)
* 优化图标显示
* 增加换台反转
### v1.4.3(安卓5及以上专用)
* 支持频道反转配置
### v1.4.2(通用)
* 支持安卓4
### v1.4.1
* 解决部分用户无法打开菜单的问题
### v1.4.0
* 解决极个别高版本机型黑屏问题
### v1.3.9
* 提高稳定性
* 提高连接速度
### v1.3.4
* 部分错误会提示用户
* 菜单3秒钟后自动关闭
### v1.3.3
* 部分错误会提示用户
* 菜单3秒钟后自动关闭
### v1.3.2
* 增加重试,减少因网络问题导致的播放失败
* 优化横幅banner
### v1.3.1
* 增加CCTV 8K 超高清频道
* 增加国际频道栏目
### v1.3.0
* 处理368可能失败的情形
### v1.2.9
* 支持3、6、8
### v1.2.8
* 兼容16:10等分辨率
### v1.2.7
* 此版本是为了测试安卓6.0以下版本,如之前可以正常运行,请勿安装。
### v1.2.6
* 支持安卓4.2
* 解决部分频道无法播放的问题
* 修复切换时有时没有恢复播放的问题
* 左右键不再切换源
* 增大频道信息标题尺寸,缩小与节目信息的间隔
### v1.2.5
* 美化频道信息显示
* 优化节目单获取
### v1.2.4
* 改变换台滑动方向,上一个频道下滑,下一个频道上滑
* 软件退出时,退出播放器
* 播放相同的频道,不再重复加载
* 暂时移除部分频道
### v1.2.3
* 固定视频比列为16:9
* 隐藏全面屏底部的小横条
* 移除移动专区
* 修复一个闪退问题
* 更换图标和应用名
+9 -1
View File
@@ -1,6 +1,6 @@
.PHONY: all
all: info
all: info gen-version
branch := $(shell git rev-parse --abbrev-ref HEAD)
commit := $(shell git rev-parse --short HEAD)
@@ -9,3 +9,11 @@ info:
@echo 'SHELL='$(SHELL)
@echo 'branch='$(branch)
@echo 'commit='$(commit)
gen-version:
git describe --tags --always
git describe --tags --always | sed 's/v/ /g' | sed 's/\./ /g' | sed 's/-/ /g' | awk '{print ($$1*16777216)+($$2*65536)+($$3*256)+$$4}'
#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
+24 -211
View File
@@ -4,9 +4,16 @@
## 使用
下载安装 [releases](https://github.com/lizongying/my-tv/releases/)
更多地址 [my-tv](https://lyrics.run/my-tv.html)
1. 下载
* [github](https://github.com/lizongying/my-tv/releases/)
* [gitee](https://gitee.com/lizongying/my-tv/releases/)
2. 安裝
* U盘安装
* 小米电视可以使用小米电视助手进行安装
* 如电视可以启用ADB,也可以通过ADB进行安装
```shell
adb install my-tv.apk
```
![image](./screenshots/img_3.png)
![image](./screenshots/img_2.png)
@@ -14,223 +21,29 @@
## 更新日志
### v1.6.6(通用)
* 更新重庆卫视图标
* 凤凰卫视增强画质
* 凤凰卫视增加EPG
### v1.6.4(通用)
* 增加CETV1
* 增加凤凰卫视
* 默认关闭开机启动
### v1.6.3(安卓5及以上专用)
* 增加CETV1
* 凤凰卫视增强画质
* 默认关闭开机启动
* 延迟菜单自动关闭时间
* 解决一些可能导致首次打开时黑屏的问题
### v1.6.2(通用)
* 修复按键无效的问题
* 新的频道列表样式
### v1.6.1(安卓5及以上专用)
* 增加凤凰卫视
### v1.6.0(通用)
* 通用(春晚緊急修復)
### v1.5.9(安卓5及以上专用)
* 解决天猫魔盒闪退问题
### v1.5.8(通用)
* 修复央视6画质差的问题
* 增加兵团卫视
* 播放失败重试
### v1.5.7(安卓5及以上专用)
* 修复播放失败的问题
### v1.5.6(通用)
* 解决部分设备系统时间不对导致播放失败的问题
### v1.5.5(安卓5及以上专用)
* 修复播放失败的问题
* 修复APP恢复后频道号、频道列表不自动消失的问题
### v1.5.4(通用)
* 修复播放失败的问题
### 以下已不可用
### v1.5.3(安卓5及以上专用)
* 修复部分情况下APP切换后无法继续播放的问题
* 优化重试逻辑
### v1.5.2(通用)
* 修复APP恢复后频道号、频道列表不自动消失的问题
### v1.5.1(安卓5及以上专用)
* 性能优化
### v1.5.0(通用)
* 修复部分情况下APP切换后无法继续播放的问题
### v1.4.9(安卓5及以上专用)
* 同步v1.4.8
### v1.4.8(通用)
* 频道号从1开始,CCTV5+为18
* 提高CCTV6清晰度
* 增加天津卫视、新疆卫视
### v1.4.7(安卓5及以上专用)
* 修复部分用户CCTV13播放过程中卡住的问题
* 调整CCTV的频道顺序
### v1.4.6(通用)
* 10以下频道不再需要先按0
### v1.4.5(安卓5及以上专用)
* 数字选台配置
### v1.4.4(通用)
* 优化图标显示
* 增加换台反转
### v1.4.3(安卓5及以上专用)
* 支持频道反转配置
### v1.4.2(通用)
* 支持安卓4
### v1.4.1
* 解决部分用户无法打开菜单的问题
### v1.4.0
* 解决极个别高版本机型黑屏问题
### v1.3.9
* 提高稳定性
* 提高连接速度
### v1.3.4
* 部分错误会提示用户
* 菜单3秒钟后自动关闭
### v1.3.3
* 部分错误会提示用户
* 菜单3秒钟后自动关闭
### v1.3.2
* 增加重试,减少因网络问题导致的播放失败
* 优化横幅banner
### v1.3.1
* 增加CCTV 8K 超高清频道
* 增加国际频道栏目
### v1.3.0
* 处理368可能失败的情形
### v1.2.9
* 支持3、6、8
### v1.2.8
* 兼容16:10等分辨率
### v1.2.7
* 此版本是为了测试安卓6.0以下版本,如之前可以正常运行,请勿安装。
### v1.2.6
* 支持安卓4.2
* 解决部分频道无法播放的问题
* 修复切换时有时没有恢复播放的问题
* 左右键不再切换源
* 增大频道信息标题尺寸,缩小与节目信息的间隔
### v1.2.5
* 美化频道信息显示
* 优化节目单获取
### v1.2.4
* 改变换台滑动方向,上一个频道下滑,下一个频道上滑
* 软件退出时,退出播放器
* 播放相同的频道,不再重复加载
* 暂时移除部分频道
### v1.2.3
* 固定视频比列为16:9
* 隐藏全面屏底部的小横条
* 移除移动专区
* 修复一个闪退问题
* 更换图标和应用名
## 其他
小米电视可以使用小米电视助手进行安装
如电视可以启用ADB,也可以通过ADB进行安装:
```shell
adb install my-tv.apk
```
[更新日志](./HISTORY.md)
## TODO
* 音量不同
* 大湾区卫视、广东4k超高清、广东珠江、三沙卫视
* CETV教育频道
* CHC高清三个电影频道
* 地方频道
* 收藏夹
* 自定义源
* 海外
* 1.5.0 无法安装,1.5.1 可以安装
* 节目增加预告
* 频道列表优化
* epg更新后菜单更新
* 防止菜单第一个获取焦点
* 隐藏频道
* 亮度调节
* 音量调节
* 軟解
* 自動更新
## 版权说明
本项目仅供学习研究,禁止用于商业用途,请于下载二十四小时内删除。
本项目可能随时终止,请大家谨慎使用,建议使用官方渠道进行观看。
本项目使用的部分代码、图片、文字等资源来源于网络,如有侵权,请联系删除。
## 赞赏
+19 -7
View File
@@ -54,7 +54,7 @@ android {
}
kotlinOptions {
jvmTarget=17
jvmTarget = 17
}
// Encapsulates your external native build configurations.
@@ -71,9 +71,14 @@ android {
static def VersionCode() {
try {
def process = 'git rev-list --count HEAD'.execute()
def p = "git describe --tags --always"
def process = p.execute()
process.waitFor()
return process.text.toInteger()
def replace = [v: "", ".": " ", "-": " "]
def arr = (process.text.trim().replace(replace) + " 0").split(" ")
def versionCode = arr[0].toInteger() * 16777216 + arr[1].toInteger() * 65536 + arr[2].toInteger() * 256 + arr[3].toInteger()
println("VersionCode $versionCode")
return versionCode
} catch (ignored) {
return 0
}
@@ -81,7 +86,7 @@ static def VersionCode() {
static def VersionName() {
try {
def process = 'git describe --tags --always'.execute()
def process = "git describe --tags --always".execute()
process.waitFor()
return process.text.trim() - "v"
} catch (ignored) {
@@ -107,14 +112,21 @@ dependencies {
implementation "com.squareup.retrofit2:converter-gson:$retrofit2_version"
implementation "com.squareup.retrofit2:converter-protobuf:$retrofit2_version"
implementation "com.squareup.retrofit2:retrofit:$retrofit2_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2"
implementation 'androidx.core:core-ktx:1.11.0-beta02'
implementation 'androidx.leanback:leanback:1.2.0-alpha02'
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'androidx.core:core-ktx:1.11.0-beta02'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.leanback:leanback:1.2.0-alpha02'
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.2"
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2"
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0-RC")
implementation 'com.google.android.exoplayer:exoplayer-ui:2.13.3'
implementation 'com.google.android.exoplayer:exoplayer-core:2.13.3'
implementation 'com.google.android.exoplayer:exoplayer-hls:2.13.3'
implementation 'javax.annotation:javax.annotation-api:1.3.2'
}
+39 -8
View File
@@ -1,35 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<uses-feature
android:name="android.software.leanback"
android:required="true" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<application
android:name=".MyTvApplication"
android:allowBackup="true"
android:largeHeap="true"
android:icon="@drawable/logo"
android:logo="@drawable/logo"
android:banner="@drawable/banner"
android:icon="@drawable/logo"
android:label="@string/app_name"
android:supportsRtl="true"
android:largeHeap="true"
android:logo="@drawable/logo"
android:networkSecurityConfig="@xml/network"
android:usesCleartextTraffic="true"
android:theme="@style/Theme.MyTV">
android:supportsRtl="true"
android:theme="@style/Theme.MyTV"
android:usesCleartextTraffic="true">
<activity
android:keepScreenOn="true"
android:name=".MainActivity"
android:exported="true"
android:keepScreenOn="true"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.windowLayoutInDisplayCutoutMode"
android:value="shortEdges" />
</activity>
<receiver
android:name=".BootReceiver"
android:exported="true">
@@ -38,9 +50,28 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver
android:name=".NetworkChangeReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<provider
android:name=".InitializerProvider"
android:authorities="${applicationId}.InitializerProvider"
android:exported="false"/>
android:exported="false" />
<meta-data android:name="android.max_aspect" android:value="2.5" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>
Binary file not shown.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

@@ -1,18 +1,21 @@
package com.lizongying.mytv
import android.graphics.Color
import android.view.ContextThemeWrapper
import android.util.Log
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.ViewGroup
import android.view.animation.ScaleAnimation
import android.widget.ImageView
import androidx.leanback.widget.ImageCardView
import androidx.lifecycle.LifecycleOwner
import androidx.core.view.marginTop
import androidx.core.view.setPadding
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.lizongying.mytv.databinding.CardBinding
import com.lizongying.mytv.models.TVListViewModel
import com.lizongying.mytv.models.TVViewModel
import kotlin.math.abs
class CardAdapter(
@@ -25,14 +28,31 @@ class CardAdapter(
private var listener: ItemListener? = null
private var focused: View? = null
var visiable = false
var focusable = false
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val cardView = object :
ImageCardView(ContextThemeWrapper(parent.context, R.style.CustomImageCardTheme)) {}
val inflater = LayoutInflater.from(parent.context)
val binding = CardBinding.inflate(inflater, parent, false)
val application = mainFragment.requireActivity().applicationContext as MyTvApplication
binding.card.layoutParams.width = application.px2Px(binding.card.layoutParams.width)
binding.card.layoutParams.height = application.px2Px(binding.card.layoutParams.height)
binding.icon.layoutParams.height = application.px2Px(binding.icon.layoutParams.height)
binding.icon.setPadding(application.px2Px(binding.icon.paddingTop))
binding.main.layoutParams.height = application.px2Px(binding.main.layoutParams.height)
binding.main.setPadding(application.px2Px(binding.main.paddingTop))
binding.title.textSize = application.px2PxFont(binding.title.textSize)
binding.desc.textSize = application.px2PxFont(binding.desc.textSize)
val layoutParams = binding.desc.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.topMargin = application.px2Px(binding.desc.marginTop)
binding.desc.layoutParams = layoutParams
val cardView = binding.root
cardView.isClickable = true
cardView.isFocusable = true
cardView.isFocusableInTouchMode = true
return ViewHolder(cardView)
return ViewHolder(cardView, binding)
}
fun clear() {
@@ -40,14 +60,14 @@ class CardAdapter(
recyclerView.invalidate()
}
private fun startScaleAnimation(view: View, fromScale: Float, toScale: Float, duration: Long) {
private fun startScaleAnimation(view: View) {
val scaleAnimation = ScaleAnimation(
fromScale, toScale,
fromScale, toScale,
0.9f, 1.0f,
0.9f, 1.0f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f
)
scaleAnimation.duration = duration
scaleAnimation.duration = 200
scaleAnimation.fillAfter = false
view.startAnimation(scaleAnimation)
}
@@ -56,7 +76,7 @@ class CardAdapter(
val item = tvListViewModel.getTVViewModel(position)
val tvViewModel = item as TVViewModel
val cardView = viewHolder.view as ImageCardView
val cardView = viewHolder.view
cardView.tag = tvViewModel
val onFocusChangeListener = View.OnFocusChangeListener { view, hasFocus ->
@@ -64,16 +84,12 @@ class CardAdapter(
listener?.onItemHasFocus(item)
focused = cardView
startScaleAnimation(cardView, 0.9f, 1.0f, 200)
//
// if (mainFragment.shouldHasFocus(view.tag as TVViewModel)) {
// }
// if (visiable) {
// startScaleAnimation(cardView, 0.9f, 1.0f, 200)
// } else {
// visiable = true
// }
if (focusable) {
startScaleAnimation(cardView)
viewHolder.focus(true)
}
} else {
viewHolder.focus(false)
}
}
@@ -83,6 +99,34 @@ class CardAdapter(
listener?.onItemClicked(item)
}
var downX = 0f
var downY = 0f
val touchSlop = ViewConfiguration.get(cardView.context).scaledTouchSlop
cardView.setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
downX = event.x
downY = event.y
true
}
MotionEvent.ACTION_UP -> {
val upX = event.x
val upY = event.y
val deltaX = abs(upX - downX)
val deltaY = abs(upY - downY)
if (deltaX < touchSlop && deltaY < touchSlop) {
// 如果位移量小于阈值,则执行点击操作
cardView.performClick()
}
true
}
else -> false
}
}
cardView.setOnKeyListener { _, keyCode, event: KeyEvent? ->
if (event?.action == KeyEvent.ACTION_DOWN) {
return@setOnKeyListener listener?.onKey(keyCode) ?: false
@@ -90,28 +134,62 @@ class CardAdapter(
false
}
cardView.titleText = tvViewModel.title.value
viewHolder.binding.title.text = tvViewModel.getTV().title
Glide.with(viewHolder.view.context)
.load(tvViewModel.logo.value)
.centerInside()
.into(cardView.mainImageView)
cardView.mainImageView.setBackgroundColor(Color.WHITE)
cardView.setMainImageScaleType(ImageView.ScaleType.CENTER_INSIDE)
viewHolder.binding.icon.let {
Glide.with(viewHolder.view.context)
.load(tvViewModel.getTV().logo)
.centerInside()
.into(it)
}
val epg = tvViewModel.epg.value?.filter { it.beginTime < Utils.getDateTimestamp() }
if (!epg.isNullOrEmpty()) {
cardView.contentText = epg.last().title
viewHolder.binding.desc.text = epg.last().title
} else {
cardView.contentText = ""
viewHolder.binding.desc.text = ""
}
}
override fun getItemCount() = tvListViewModel.size()
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
class ViewHolder(itemView: View, var binding: CardBinding) : RecyclerView.ViewHolder(itemView) {
val view = itemView
fun focus(hasFocus: Boolean) {
if (hasFocus) {
binding.main.setBackgroundResource(R.drawable.rounded_light_bottom)
} else {
binding.main.setBackgroundResource(R.drawable.rounded_dark_bottom)
}
}
}
fun updateEPG() {
for (i in 0 until recyclerView.childCount) {
val childView = recyclerView.getChildAt(i)
val viewHolder = recyclerView.getChildViewHolder(childView) as ViewHolder
if (viewHolder.view.tag != null && viewHolder.view.tag is TVViewModel) {
val tvViewModel = viewHolder.view.tag as TVViewModel
val epg = tvViewModel.epg.value?.filter { it.beginTime < Utils.getDateTimestamp() }
if (!epg.isNullOrEmpty()) {
val title = epg.last().title
if (viewHolder.binding.desc.text != title) {
viewHolder.binding.desc.text = title
Log.i(TAG, "updateEPG $title")
}
} else {
if (viewHolder.binding.desc.text != "") {
viewHolder.binding.desc.text = ""
Log.i(TAG, "updateEPG")
}
}
}
}
}
fun toPosition(position: Int) {
@@ -1,10 +1,13 @@
package com.lizongying.mytv
import android.content.res.Resources
import android.os.Bundle
import android.os.Handler
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.marginEnd
import androidx.core.view.marginTop
import androidx.fragment.app.Fragment
import com.lizongying.mytv.databinding.ChannelBinding
import com.lizongying.mytv.models.TVViewModel
@@ -14,8 +17,9 @@ class ChannelFragment : Fragment() {
private val binding get() = _binding!!
private val handler = Handler()
private val delay: Long = 3000
private val delay: Long = 5000
private var channel = 0
private var channelCount = 0
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
@@ -23,24 +27,45 @@ class ChannelFragment : Fragment() {
): View {
_binding = ChannelBinding.inflate(inflater, container, false)
_binding!!.root.visibility = View.GONE
(activity as MainActivity).fragmentReady()
val application = requireActivity().applicationContext as MyTvApplication
binding.channel.layoutParams.width = application.px2Px(binding.channel.layoutParams.width)
binding.channel.layoutParams.height = application.px2Px(binding.channel.layoutParams.height)
val layoutParams = binding.channel.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.topMargin = application.px2Px(binding.channel.marginTop)
layoutParams.marginEnd = application.px2Px(binding.channel.marginEnd)
binding.channel.layoutParams = layoutParams
binding.content.textSize = application.px2PxFont(binding.content.textSize)
binding.time.textSize = application.px2PxFont(binding.time.textSize)
binding.main.layoutParams.width = application.shouldWidthPx()
binding.main.layoutParams.height = application.shouldHeightPx()
(activity as MainActivity).fragmentReady(TAG)
return binding.root
}
fun show(tvViewModel: TVViewModel) {
handler.removeCallbacks(hideRunnable)
handler.removeCallbacks(playRunnable)
binding.channelContent.text = (tvViewModel.id.value?.plus(1)).toString()
binding.content.text = (tvViewModel.getTV().id.plus(1)).toString()
view?.visibility = View.VISIBLE
handler.postDelayed(hideRunnable, delay)
}
fun show(channel: String) {
this.channel = "${binding.channelContent.text}$channel".toInt()
if (channelCount > 1) {
return
}
channelCount++
this.channel = "${this.channel}$channel".toInt()
handler.removeCallbacks(hideRunnable)
handler.removeCallbacks(playRunnable)
if (binding.channelContent.text == "") {
binding.channelContent.text = channel
if (channelCount < 2) {
binding.content.text = "${this.channel}"
view?.visibility = View.VISIBLE
handler.postDelayed(playRunnable, delay)
} else {
@@ -62,14 +87,18 @@ class ChannelFragment : Fragment() {
}
private val hideRunnable = Runnable {
binding.channelContent.text = ""
binding.content.text = ""
view?.visibility = View.GONE
channel = 0
channelCount = 0
}
private val playRunnable = Runnable {
(activity as MainActivity).play(channel - 1)
binding.channelContent.text = ""
binding.content.text = ""
view?.visibility = View.GONE
channel = 0
channelCount = 0
}
override fun onDestroyView() {
@@ -1,36 +0,0 @@
package com.lizongying.mytv
import android.app.AlertDialog
import android.app.Dialog
import android.os.Bundle
import androidx.fragment.app.DialogFragment
class ConfirmationDialogFragment(private val listener: ConfirmationDialogListener) :
DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let {
val builder = AlertDialog.Builder(it)
builder.setTitle("确认")
.setMessage("确认更新吗?")
.setPositiveButton(
"确定"
) { _, _ ->
listener.onConfirm()
}
.setNegativeButton(
"取消"
) { _, _ ->
listener.onCancel()
}
// 创建并返回 AlertDialog 对象
builder.create()
} ?: throw IllegalStateException("Activity cannot be null")
}
interface ConfirmationDialogListener {
fun onConfirm()
fun onCancel()
}
}
@@ -0,0 +1,46 @@
package com.lizongying.mytv
import android.app.AlertDialog
import android.app.Dialog
import android.os.Bundle
import androidx.fragment.app.DialogFragment
class ConfirmationFragment(
private val listener: ConfirmationListener,
private val message: String,
private val update: Boolean
) : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let {
val builder = AlertDialog.Builder(it)
builder.setTitle(message)
if (update) {
builder.setMessage("确定更新吗?")
.setPositiveButton(
"确定"
) { _, _ ->
listener.onConfirm()
}
.setNegativeButton(
"取消"
) { _, _ ->
listener.onCancel()
}
} else {
builder.setMessage("")
.setNegativeButton(
"好的"
) { _, _ ->
}
}
builder.create()
} ?: throw IllegalStateException("Activity cannot be null")
}
interface ConfirmationListener {
fun onConfirm()
fun onCancel()
}
}
@@ -0,0 +1,49 @@
package com.lizongying.mytv
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.marginStart
import androidx.core.view.marginTop
import androidx.fragment.app.Fragment
import com.lizongying.mytv.databinding.ErrorBinding
class ErrorFragment : Fragment() {
private var _binding: ErrorBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = ErrorBinding.inflate(inflater, container, false)
val application = requireActivity().applicationContext as MyTvApplication
binding.logo.layoutParams.width = application.px2Px(binding.logo.layoutParams.width)
binding.logo.layoutParams.height = application.px2Px(binding.logo.layoutParams.height)
val layoutParams = binding.msg.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.topMargin = application.px2Px(binding.msg.marginTop)
binding.msg.layoutParams = layoutParams
binding.msg.textSize = application.px2PxFont(binding.msg.textSize)
(activity as MainActivity).fragmentReady(TAG)
return binding.root
}
fun show(msg: String) {
binding.msg.text = msg
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
companion object {
private const val TAG = "ErrorFragment"
}
}
@@ -0,0 +1,105 @@
@file:Suppress("DEPRECATION")
package com.lizongying.mytv
import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.Signature
import android.content.pm.SigningInfo
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build
import android.util.Log
import java.security.MessageDigest
private const val TAG = "Extensions"
private val Context.packageInfo: PackageInfo
get() {
val flag = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
PackageManager.GET_SIGNATURES
} else {
PackageManager.GET_SIGNING_CERTIFICATES
}
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
packageManager.getPackageInfo(packageName, flag)
} else {
packageManager.getPackageInfo(
packageName,
PackageManager.PackageInfoFlags.of(PackageManager.GET_SIGNING_CERTIFICATES.toLong())
)
}
}
/**
* Return the version code of the app which is defined in build.gradle.
* eg:100
*/
val Context.appVersionCode: Long
get() {
val packageInfo = this.packageInfo
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
packageInfo.longVersionCode
} else {
packageInfo.versionCode.toLong()
}
}
/**
* Return the version name of the app which is defined in build.gradle.
* eg:1.0.0
*/
val Context.appVersionName: String get() = packageInfo.versionName
val Context.appSignature: String
get() {
val packageInfo = this.packageInfo
var sign: Signature? = null
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
val signatures: Array<out Signature>? = packageInfo.signatures
if (signatures != null) {
sign = signatures[0]
}
} else {
val signingInfo: SigningInfo? = packageInfo.signingInfo
if (signingInfo != null) {
sign = signingInfo.apkContentsSigners[0]
}
}
if (sign == null) {
return ""
}
return hashSignature(sign)
}
val Context.isNetworkConnected: Boolean
get() {
val connectivityManager =
this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val network = connectivityManager.activeNetwork
val networkCapabilities = connectivityManager.getNetworkCapabilities(network)
return networkCapabilities != null &&
(networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET))
} else {
val networkInfo = connectivityManager.activeNetworkInfo
return networkInfo != null && networkInfo.isConnectedOrConnecting
}
}
private fun hashSignature(signature: Signature): String {
return try {
val md = MessageDigest.getInstance("MD5")
md.update(signature.toByteArray())
val digest = md.digest()
digest.let { it -> it.joinToString("") { "%02x".format(it) } }
} catch (e: Exception) {
Log.e(TAG, "Error hashing signature", e)
""
}
}
@@ -1,51 +0,0 @@
package com.lizongying.mytv
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import android.view.View
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
class GrayOverlayItemDecoration(private val context: Context) : RecyclerView.ItemDecoration() {
private val grayOverlayPaint = Paint().apply {
color = ContextCompat.getColor(context, R.color.gray_overlay)
style = Paint.Style.FILL
}
override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
super.onDrawOver(c, parent, state)
val childCount = parent.childCount
for (i in 0 until childCount) {
val child = parent.getChildAt(i)
if (!child.hasFocus()) {
// child.alpha = 0.7f
// 计算遮罩层的大小
val overlayRect = Rect(
child.left,
child.top,
child.right,
child.bottom
)
// 绘制灰色遮罩层
c.drawRect(overlayRect, grayOverlayPaint)
} else {
// child.alpha = 1f
}
}
}
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
// 在此处设置偏移量为0,以防止遮罩层影响项的布局
outRect.setEmpty()
}
}
@@ -1,11 +1,16 @@
package com.lizongying.mytv
import android.content.res.Resources
import android.os.Bundle
import android.os.Handler
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.marginBottom
import androidx.core.view.marginStart
import androidx.core.view.marginTop
import androidx.core.view.setPadding
import androidx.fragment.app.Fragment
import com.bumptech.glide.Glide
import com.lizongying.mytv.databinding.InfoBinding
@@ -16,31 +21,64 @@ class InfoFragment : Fragment() {
private val binding get() = _binding!!
private val handler = Handler()
private val delay: Long = 3000
private val delay: Long = 5000
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = InfoBinding.inflate(inflater, container, false)
val application = requireActivity().applicationContext as MyTvApplication
binding.info.layoutParams.width = application.px2Px(binding.info.layoutParams.width)
binding.info.layoutParams.height = application.px2Px(binding.info.layoutParams.height)
val layoutParams = binding.info.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.bottomMargin = application.px2Px(binding.info.marginBottom)
binding.info.layoutParams = layoutParams
binding.logo.layoutParams.width = application.px2Px(binding.logo.layoutParams.width)
binding.logo.setPadding(application.px2Px(binding.logo.paddingTop))
binding.main.layoutParams.width = application.px2Px(binding.main.layoutParams.width)
binding.main.setPadding(application.px2Px(binding.main.paddingTop))
val layoutParamsMain = binding.main.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsMain.marginStart = application.px2Px(binding.main.marginStart)
binding.main.layoutParams = layoutParamsMain
val layoutParamsDesc = binding.desc.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsDesc.topMargin = application.px2Px(binding.desc.marginTop)
binding.desc.layoutParams = layoutParamsDesc
binding.title.textSize = application.px2PxFont(binding.title.textSize)
binding.desc.textSize = application.px2PxFont(binding.desc.textSize)
binding.container.layoutParams.width = application.shouldWidthPx()
binding.container.layoutParams.height = application.shouldHeightPx()
_binding!!.root.visibility = View.GONE
(activity as MainActivity).fragmentReady()
(activity as MainActivity).fragmentReady(TAG)
return binding.root
}
fun show(tvViewModel: TVViewModel) {
binding.textView.text = tvViewModel.title.value
if (_binding == null) {
return
}
binding.title.text = tvViewModel.getTV().title
Glide.with(this)
.load(tvViewModel.logo.value)
.into(binding.infoLogo)
.load(tvViewModel.getTV().logo)
.into(binding.logo)
Log.i(TAG, "${tvViewModel.title.value} ${tvViewModel.epg.value}")
Log.i(TAG, "${tvViewModel.getTV().title} ${tvViewModel.epg.value}")
val epg = tvViewModel.epg.value?.filter { it.beginTime < Utils.getDateTimestamp() }
if (!epg.isNullOrEmpty()) {
binding.infoDesc.text = epg.last().title
binding.desc.text = epg.last().title
} else {
binding.infoDesc.text = ""
binding.desc.text = ""
}
handler.removeCallbacks(removeRunnable)
@@ -0,0 +1,29 @@
package com.lizongying.mytv
import android.content.Context
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.RecyclerView
class ItemDecoration(context: Context) : RecyclerView.ItemDecoration() {
private var application: MyTvApplication
init {
application = context.applicationContext as MyTvApplication
}
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
val space = application.dp2Px(5)
outRect.top = space
outRect.bottom = space
outRect.left = space
outRect.right = space
}
}
@@ -0,0 +1,37 @@
package com.lizongying.mytv
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.lizongying.mytv.databinding.LoadingBinding
class LoadingFragment : Fragment() {
private var _binding: LoadingBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = LoadingBinding.inflate(inflater, container, false)
val application = requireActivity().applicationContext as MyTvApplication
binding.bar.layoutParams.width = application.px2Px(binding.bar.layoutParams.width)
binding.bar.layoutParams.height = application.px2Px(binding.bar.layoutParams.height)
(activity as MainActivity).fragmentReady(TAG)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
companion object {
private const val TAG = "LoadingFragment"
}
}
@@ -1,9 +1,5 @@
package com.lizongying.mytv
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.Signature
import android.content.pm.SigningInfo
import android.os.Build
import android.os.Bundle
import android.os.Handler
@@ -12,27 +8,35 @@ import android.util.Log
import android.view.GestureDetector
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View.SYSTEM_UI_FLAG_FULLSCREEN
import android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
import android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
import android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
import android.view.WindowManager
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.lifecycleScope
import com.lizongying.mytv.models.TVViewModel
import com.lizongying.mytv.requests.Request
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import java.security.MessageDigest
class MainActivity : FragmentActivity(), Request.RequestListener {
private var ready = 0
private var playerFragment = PlayerFragment()
private var mainFragment = MainFragment()
private var infoFragment = InfoFragment()
private var channelFragment = ChannelFragment()
private lateinit var settingFragment: SettingFragment
private val playerFragment = PlayerFragment()
private val errorFragment = ErrorFragment()
private val loadingFragment = LoadingFragment()
private val mainFragment = MainFragment()
private val infoFragment = InfoFragment()
private val channelFragment = ChannelFragment()
private var timeFragment = TimeFragment()
private val settingFragment = SettingFragment()
private var doubleBackToExitPressedOnce = false
@@ -42,42 +46,82 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
private val delayHideMain: Long = 10000
private val delayHideSetting: Long = 10000
init {
Utils.setRequestListener(this)
}
private fun syncTime() {
lifecycleScope.launch(Dispatchers.IO) {
val utilsJob = async(start = CoroutineStart.LAZY) { Utils.init() }
utilsJob.start()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
Log.i(TAG, "onCreate")
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Request.onCreate()
Request.setRequestListener(this)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val lp = window.attributes
lp.layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
window.setAttributes(lp)
}
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
window.decorView.systemUiVisibility = SYSTEM_UI_FLAG_HIDE_NAVIGATION
window.decorView.systemUiVisibility =
SYSTEM_UI_FLAG_FULLSCREEN or
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or SYSTEM_UI_FLAG_HIDE_NAVIGATION or
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
// window.statusBarColor = Color.TRANSPARENT
// window.navigationBarColor = Color.TRANSPARENT
// }
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
val transaction = supportFragmentManager.beginTransaction()
.add(R.id.main_browse_fragment, playerFragment)
.add(R.id.main_browse_fragment, errorFragment)
// .add(R.id.main_browse_fragment, loadingFragment)
.add(R.id.main_browse_fragment, timeFragment)
.add(R.id.main_browse_fragment, infoFragment)
.add(R.id.main_browse_fragment, channelFragment)
.add(R.id.main_browse_fragment, mainFragment)
.hide(mainFragment)
.commit()
.hide(errorFragment)
if (!SP.time) {
transaction.hide(timeFragment)
} else {
transaction.show(timeFragment)
}
transaction.commitNow()
}
gestureDetector = GestureDetector(this, GestureListener())
val packageInfo = getPackageInfo()
val versionName = packageInfo.versionName
val versionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
packageInfo.longVersionCode
} else {
packageInfo.versionCode.toLong()
}
settingFragment = SettingFragment(
versionName,
versionCode,
SP.channelReversal,
SP.channelNum,
SP.bootStartup
)
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// val connectivityManager =
// getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
// connectivityManager.registerDefaultNetworkCallback(object :
// ConnectivityManager.NetworkCallback() {
// override fun onAvailable(network: Network) {
// super.onAvailable(network)
// Log.i(TAG, "net ${Build.VERSION.SDK_INT}")
// if (this@MainActivity.isNetworkConnected) {
// Log.i(TAG, "net isNetworkConnected")
// ready++
// }
// }
// })
// } else {
// Log.i(TAG, "net ${Build.VERSION.SDK_INT}")
// ready++
// }
}
fun showInfoFragment(tvViewModel: TVViewModel) {
@@ -87,6 +131,52 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
}
}
fun showErrorFragment(msg: String) {
errorFragment.show(msg)
if (errorFragment.isVisible) {
return
}
supportFragmentManager.beginTransaction()
.show(errorFragment)
.commit()
}
fun hideErrorFragment() {
errorFragment.show("")
if (!errorFragment.isVisible) {
return
}
supportFragmentManager.beginTransaction()
.hide(errorFragment)
.commit()
}
fun showLoadingFragment() {
showFragment(loadingFragment)
}
fun hideLoadingFragment() {
hideFragment(loadingFragment)
}
fun showPlayerFragment() {
if (playerFragment.isVisible) {
return
}
supportFragmentManager.beginTransaction()
.show(playerFragment)
.commit()
}
fun hidePlayerFragment() {
if (!playerFragment.isVisible) {
return
}
supportFragmentManager.beginTransaction()
.hide(playerFragment)
.commit()
}
private fun showChannel(channel: String) {
if (!mainFragment.isHidden) {
return
@@ -103,7 +193,6 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
fun play(tvViewModel: TVViewModel) {
playerFragment.play(tvViewModel)
mainFragment.view?.requestFocus()
}
fun play(itemPosition: Int) {
@@ -118,14 +207,6 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
mainFragment.next()
}
private fun prevSource() {
// mainFragment.prevSource()
}
private fun nextSource() {
// mainFragment.nextSource()
}
fun switchMainFragment() {
val transaction = supportFragmentManager.beginTransaction()
@@ -145,11 +226,15 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
handler.postDelayed(hideMain, delayHideMain)
}
fun settingActive() {
fun settingDelayHide() {
handler.removeCallbacks(hideSetting)
handler.postDelayed(hideSetting, delayHideSetting)
}
fun settingNeverHide() {
handler.removeCallbacks(hideSetting)
}
private val hideMain = Runnable {
if (!mainFragment.isHidden) {
supportFragmentManager.beginTransaction().hide(mainFragment).commit()
@@ -168,14 +253,42 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
}
}
fun fragmentReady() {
fun fragmentReady(tag: String) {
ready++
Log.i(TAG, "ready $ready")
if (ready == 5) {
Log.i(TAG, "ready $tag $ready ")
if (ready == 7) {
mainFragment.fragmentReady()
}
}
private fun showTime() {
if (SP.time) {
showFragment(timeFragment)
} else {
hideFragment(timeFragment)
}
}
private fun showFragment(fragment: Fragment) {
if (!fragment.isHidden) {
return
}
supportFragmentManager.beginTransaction()
.show(fragment)
.commitNow()
}
private fun hideFragment(fragment: Fragment) {
if (fragment.isHidden) {
return
}
supportFragmentManager.beginTransaction()
.hide(fragment)
.commitNow()
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
if (event != null) {
gestureDetector.onTouchEvent(event)
@@ -191,6 +304,11 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
return true
}
override fun onDoubleTap(e: MotionEvent): Boolean {
showSetting()
return true
}
override fun onFling(
e1: MotionEvent?,
e2: MotionEvent,
@@ -229,22 +347,26 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
return
}
Log.i(TAG, "settingFragment ${settingFragment.isVisible}")
if (!settingFragment.isVisible) {
settingFragment.show(supportFragmentManager, "setting")
settingActive()
} else {
handler.removeCallbacks(hideSetting)
settingFragment.dismiss()
if (settingFragment.isVisible) {
return
}
settingFragment.show(supportFragmentManager, TAG)
settingDelayHide()
}
private val hideSetting = Runnable {
if (settingFragment.isVisible) {
settingFragment.dismiss()
showTime()
mainFragment.changeMenu()
}
}
private fun hideSettingFragment() {
handler.postDelayed(hideSetting, 0)
}
private fun channelUp() {
if (mainFragment.isHidden) {
if (SP.channelReversal) {
@@ -284,6 +406,11 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
return
}
if (settingFragment.isVisible) {
hideSettingFragment()
return
}
if (doubleBackToExitPressedOnce) {
super.onBackPressed()
return
@@ -297,6 +424,11 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
}, 2000)
}
private fun active() {
if (settingFragment.isVisible) {
settingDelayHide()
}
}
fun onKey(keyCode: Int): Boolean {
Log.i(TAG, "keyCode $keyCode")
@@ -387,6 +519,7 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
}
KeyEvent.KEYCODE_ENTER -> {
active()
switchMainFragment()
}
@@ -395,6 +528,7 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
}
KeyEvent.KEYCODE_DPAD_UP -> {
active()
channelUp()
}
@@ -403,6 +537,7 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
}
KeyEvent.KEYCODE_DPAD_DOWN -> {
active()
channelDown()
}
@@ -411,30 +546,19 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
}
KeyEvent.KEYCODE_DPAD_LEFT -> {
channelUp()
// if (mainFragment.isHidden) {
// prevSource()
// } else {
//// if (mainFragment.tvListViewModel.getTVViewModelCurrent()
//// ?.getItemPosition() == 0
//// ) {
////// mainFragment.toLastPosition()
//// hideMainFragment()
//// }
// }
active()
if (mainFragment.isHidden && !settingFragment.isVisible) {
switchMainFragment()
return true
}
}
KeyEvent.KEYCODE_DPAD_RIGHT -> {
channelDown()
// if (mainFragment.isHidden) {
// nextSource()
// } else {
//// if (mainFragment.tvListViewModel.getTVViewModelCurrent()
//// ?.getItemPosition() == mainFragment.tvListViewModel.maxNum[mainFragment.selectedPosition] - 1
//// ) {
//// mainFragment.toFirstPosition()
//// }
// }
active()
if (mainFragment.isHidden && !settingFragment.isVisible) {
showSetting()
return true
}
}
}
return false
@@ -448,65 +572,23 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
return super.onKeyDown(keyCode, event)
}
private fun getPackageInfo(): PackageInfo {
val flag = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
PackageManager.GET_SIGNATURES
} else {
PackageManager.GET_SIGNING_CERTIFICATES
}
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
packageManager.getPackageInfo(packageName, flag)
} else {
packageManager.getPackageInfo(
packageName,
PackageManager.PackageInfoFlags.of(PackageManager.GET_SIGNING_CERTIFICATES.toLong())
)
}
}
private fun getAppSignature(): String {
val packageInfo = getPackageInfo()
var sign: Signature? = null
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
val signatures: Array<out Signature>? = packageInfo.signatures
if (signatures != null) {
sign = signatures[0]
}
} else {
val signingInfo: SigningInfo? = packageInfo.signingInfo
if (signingInfo != null) {
sign = signingInfo.apkContentsSigners[0]
}
}
if (sign == null) {
return ""
}
return hashSignature(sign)
}
private fun hashSignature(signature: Signature): String {
return try {
val md = MessageDigest.getInstance("MD5")
md.update(signature.toByteArray())
val digest = md.digest()
digest.let { it -> it.joinToString("") { "%02x".format(it) } }
} catch (e: Exception) {
Log.e(TAG, "Error hashing signature", e)
""
}
}
private fun getAppSignature() = this.appSignature
override fun onStart() {
Log.i(TAG, "onStart")
Log.i(TAG, "onStart MainActivity")
syncTime()
super.onStart()
}
override fun onResume() {
Log.i(TAG, "onResume")
super.onResume()
}
override fun onResumeFragments() {
super.onResumeFragments()
mainFragment.changeMenu()
if (!mainFragment.isHidden) {
handler.postDelayed(hideMain, delayHideMain)
}
@@ -523,8 +605,8 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
Request.onDestroy()
}
override fun onRequestFinished() {
fragmentReady()
override fun onRequestFinished(message: String?) {
fragmentReady("request")
}
private companion object {
@@ -7,16 +7,22 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.view.marginBottom
import androidx.core.view.marginStart
import androidx.core.view.marginTop
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.lizongying.mytv.Utils.dpToPx
import com.lizongying.mytv.api.YSP
import com.lizongying.mytv.databinding.MenuBinding
import com.lizongying.mytv.databinding.RowBinding
import com.lizongying.mytv.databinding.ShowBinding
import com.lizongying.mytv.models.ProgramType
import com.lizongying.mytv.models.TVList
import com.lizongying.mytv.models.TVListViewModel
import com.lizongying.mytv.models.TVViewModel
import com.lizongying.mytv.requests.Request
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -27,21 +33,39 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
private var rowList: MutableList<View> = mutableListOf()
private var _binding: ShowBinding? = null
private var _binding: MenuBinding? = null
private val binding get() = _binding!!
var tvListViewModel = TVListViewModel()
private var lastVideoUrl = ""
private lateinit var application: MyTvApplication
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = ShowBinding.inflate(inflater, container, false)
_binding = MenuBinding.inflate(inflater, container, false)
application = requireActivity().applicationContext as MyTvApplication
binding.menu.layoutParams.width = application.shouldWidthPx()
binding.menu.layoutParams.height = application.shouldHeightPx()
binding.container.setOnClickListener {
hideSelf()
}
return binding.root
}
private fun hideSelf() {
requireActivity().supportFragmentManager.beginTransaction()
.hide(this)
.commit()
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
@@ -64,44 +88,60 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
tvViewModel.setItemPosition(idx2)
tvListViewModelCurrent.addTVViewModel(tvViewModel)
tvListViewModel.addTVViewModel(tvViewModel)
updateEPG(tvViewModel)
}
tvListViewModel.maxNum.add(v.size)
val adapter =
CardAdapter(
itemBinding.rowItems,
itemBinding.items,
this,
tvListViewModelCurrent,
)
rowList.add(itemBinding.rowItems)
rowList.add(itemBinding.items)
adapter.setItemListener(this)
itemBinding.rowHeader.text = k
itemBinding.rowItems.tag = idx.toInt()
itemBinding.rowItems.adapter = adapter
itemBinding.rowItems.layoutManager =
GridLayoutManager(context, 6)
itemBinding.rowItems.layoutParams.height =
dpToPx(92 * ((tvListViewModelCurrent.size() + 6 - 1) / 6))
itemBinding.header.text = k
itemBinding.items.tag = idx.toInt()
itemBinding.items.adapter = adapter
itemBinding.rowItems.addOnScrollListener(object : RecyclerView.OnScrollListener() {
itemBinding.items.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
(activity as MainActivity).mainActive()
}
})
val itemDecoration = context?.let { GrayOverlayItemDecoration(it) }
val itemDecoration = context?.let { ItemDecoration(it) }
if (itemDecoration != null) {
itemBinding.rowItems.addItemDecoration(itemDecoration)
itemBinding.items.addItemDecoration(itemDecoration)
}
if (SP.grid) {
itemBinding.items.layoutManager =
GridLayoutManager(context, 6)
itemBinding.items.layoutParams.height =
application.dp2Px(110 * ((tvListViewModelCurrent.size() + 6 - 1) / 6) + 5)
} else {
itemBinding.items.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
}
val layoutParams = itemBinding.row.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.topMargin = dpToPx(11F)
layoutParams.topMargin = application.dp2Px(11)
itemBinding.row.layoutParams = layoutParams
itemBinding.row.setOnClickListener {
hideSelf()
}
val layoutParamsHeader =
itemBinding.header.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsHeader.topMargin = application.px2Px(itemBinding.header.marginTop)
layoutParamsHeader.bottomMargin = application.px2Px(itemBinding.header.marginBottom)
layoutParamsHeader.marginStart = application.px2Px(itemBinding.header.marginStart)
itemBinding.header.layoutParams = layoutParamsHeader
itemBinding.header.textSize = application.px2PxFont(itemBinding.header.textSize)
content.addView(itemBinding.row)
idx++
@@ -115,28 +155,35 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
tvListViewModel.tvListViewModel.value?.forEach { tvViewModel ->
tvViewModel.errInfo.observe(viewLifecycleOwner) { _ ->
if (tvViewModel.errInfo.value != null
&& tvViewModel.id.value == itemPosition
&& tvViewModel.getTV().id == itemPosition
) {
Toast.makeText(context, tvViewModel.errInfo.value, Toast.LENGTH_SHORT)
.show()
if (tvViewModel.errInfo.value == "") {
(activity as? MainActivity)?.showPlayerFragment()
(activity as? MainActivity)?.hideErrorFragment()
(activity as? MainActivity)?.hideLoadingFragment()
} else {
(activity as? MainActivity)?.hidePlayerFragment()
(activity as? MainActivity)?.hideLoadingFragment()
(activity as? MainActivity)?.showErrorFragment(tvViewModel.errInfo.value.toString())
}
}
}
tvViewModel.ready.observe(viewLifecycleOwner) { _ ->
// not first time && channel not change
if (tvViewModel.ready.value != null
&& tvViewModel.id.value == itemPosition
&& tvViewModel.getTV().id == itemPosition
&& check(tvViewModel)
) {
Log.i(TAG, "ready ${tvViewModel.title.value}")
Log.i(TAG, "ready ${tvViewModel.getTV().title}")
(activity as? MainActivity)?.play(tvViewModel)
}
}
tvViewModel.change.observe(viewLifecycleOwner) { _ ->
if (tvViewModel.change.value != null) {
val title = tvViewModel.title.value
val title = tvViewModel.getTV().title
Log.i(TAG, "switch $title")
if (tvViewModel.pid.value != "") {
if (tvViewModel.getTV().pid != "") {
Log.i(TAG, "request $title")
lifecycleScope.launch(Dispatchers.IO) {
tvViewModel.let { Request.fetchData(it) }
@@ -158,12 +205,28 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
}
}
}
(activity as MainActivity).fragmentReady()
(activity as MainActivity).fragmentReady(TAG)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
fun changeMenu() {
if (SP.grid) {
for (i in rowList) {
if (i is RecyclerView) {
i.layoutManager = GridLayoutManager(context, 6)
i.layoutParams.height =
application.dp2Px(110 * (((i.adapter as CardAdapter).getItemCount() + 6 - 1) / 6) + 5)
}
}
} else {
for (i in rowList) {
if (i is RecyclerView) {
i.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
i.layoutParams.height = application.dp2Px(110 + 5)
}
}
}
}
override fun onKey(keyCode: Int): Boolean {
@@ -184,13 +247,14 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
}
override fun onItemHasFocus(tvViewModel: TVViewModel) {
tvListViewModel.setItemPositionCurrent(tvViewModel.id.value!!)
val row = tvViewModel.getRowPosition()
for (i in rowList) {
if (i.tag as Int != row) {
((i as RecyclerView).adapter as CardAdapter).clear()
((i as RecyclerView).adapter as CardAdapter).focusable = false
(i.adapter as CardAdapter).clear()
} else {
((i as RecyclerView).adapter as CardAdapter).focusable = true
}
}
@@ -198,39 +262,47 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
}
override fun onItemClicked(tvViewModel: TVViewModel) {
Log.i(TAG, "onItemClicked")
if (this.isHidden) {
(activity as? MainActivity)?.switchMainFragment()
return
}
if (itemPosition != tvViewModel.id.value!!) {
itemPosition = tvViewModel.id.value!!
if (itemPosition != tvViewModel.getTV().id) {
itemPosition = tvViewModel.getTV().id
tvListViewModel.setItemPosition(itemPosition)
tvListViewModel.getTVViewModel(itemPosition)?.changed()
tvListViewModel.getTVViewModel(itemPosition)?.changed("menu")
Log.i(TAG, "onItemClicked ${tvViewModel.getTV().id}")
}
(activity as? MainActivity)?.switchMainFragment()
}
fun setPosition() {
val tvViewModel = tvListViewModel.getTVViewModel(itemPosition)
rowList[tvViewModel!!.getRowPosition()].post {
((rowList[tvViewModel.getRowPosition()] as RecyclerView).layoutManager as GridLayoutManager).findViewByPosition(
tvViewModel.getItemPosition()
)?.requestFocus()
}
val tvViewModel = tvListViewModel.getTVViewModel(itemPosition) ?: return
val rowPosition = tvViewModel.getRowPosition()
val itemPosition = tvViewModel.getItemPosition()
setPosition(rowPosition, itemPosition)
}
fun setPosition(rowPosition: Int, itemPosition: Int) {
rowList[rowPosition].post {
((rowList[rowPosition] as RecyclerView).layoutManager as GridLayoutManager).findViewByPosition(
itemPosition
)?.requestFocus()
when (val layoutManager = (rowList[rowPosition] as RecyclerView).layoutManager) {
is GridLayoutManager -> {
layoutManager.findViewByPosition(
itemPosition
)?.requestFocus()
}
is LinearLayoutManager -> {
layoutManager.findViewByPosition(
itemPosition
)?.requestFocus()
}
}
}
}
fun check(tvViewModel: TVViewModel): Boolean {
val title = tvViewModel.title.value
val title = tvViewModel.getTV().title
val videoUrl = tvViewModel.videoIndex.value?.let { tvViewModel.videoUrl.value?.get(it) }
if (videoUrl == null || videoUrl == "") {
Log.e(TAG, "$title videoUrl is empty")
@@ -246,8 +318,11 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
}
fun fragmentReady() {
// request.fetchPage()
tvListViewModel.getTVViewModel(itemPosition)?.changed()
tvListViewModel.getTVViewModel(itemPosition)?.changed("init")
tvListViewModel.tvListViewModel.value?.forEach { tvViewModel ->
updateEPG(tvViewModel)
}
}
fun play(itemPosition: Int) {
@@ -255,7 +330,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
if (itemPosition > -1 && itemPosition < tvListViewModel.size()) {
this.itemPosition = itemPosition
tvListViewModel.setItemPosition(itemPosition)
tvListViewModel.getTVViewModel(itemPosition)?.changed()
tvListViewModel.getTVViewModel(itemPosition)?.changed("num")
} else {
Toast.makeText(context, "频道不存在", Toast.LENGTH_SHORT).show()
}
@@ -269,7 +344,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
itemPosition = tvListViewModel.size() - 1
}
tvListViewModel.setItemPosition(itemPosition)
tvListViewModel.getTVViewModel(itemPosition)?.changed()
tvListViewModel.getTVViewModel(itemPosition)?.changed("prev")
}
}
@@ -280,23 +355,32 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
itemPosition = 0
}
tvListViewModel.setItemPosition(itemPosition)
tvListViewModel.getTVViewModel(itemPosition)?.changed()
tvListViewModel.getTVViewModel(itemPosition)?.changed("next")
}
}
private fun updateEPG(tvViewModel: TVViewModel) {
if (tvViewModel.getTV().channel == "港澳台") {
Request.fetchFEPG(tvViewModel)
} else {
Request.fetchYEPG(tvViewModel)
when (tvViewModel.getTV().programType) {
ProgramType.Y_PROTO -> {
Request.fetchYProtoEPG(tvViewModel)
}
ProgramType.Y_JCE -> {
Request.fetchYJceEPG(tvViewModel)
}
ProgramType.F -> {
Request.fetchFEPG(tvViewModel)
}
}
}
fun shouldHasFocus(tvModel: TVViewModel):Boolean {
fun shouldHasFocus(tvModel: TVViewModel): Boolean {
return tvModel == tvListViewModel.getTVViewModel(itemPosition)
}
override fun onHiddenChanged(hidden: Boolean) {
Log.i(TAG, "onHiddenChanged $hidden")
super.onHiddenChanged(hidden)
if (!hidden) {
val tvModel = tvListViewModel.getTVViewModel(itemPosition)
@@ -305,15 +389,17 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
Log.i(TAG, "toPosition $rowPosition $itemPosition")
for (i in rowList) {
if (i.tag as Int == rowPosition) {
((i as RecyclerView).adapter as CardAdapter).toPosition(itemPosition!!)
((i as RecyclerView).adapter as CardAdapter).updateEPG()
(i.adapter as CardAdapter).focusable = true
(i.adapter as CardAdapter).toPosition(itemPosition!!)
break
}
}
} else {
view?.post {
// for (i in rowList) {
// ((i as RecyclerView).adapter as CardAdapter).visiable = false
// }
for (i in rowList) {
((i as RecyclerView).adapter as CardAdapter).focusable = false
}
}
}
}
@@ -323,13 +409,6 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
super.onResume()
}
override fun onStop() {
Log.i(TAG, "onStop")
super.onStop()
SP.itemPosition = itemPosition
Log.i(TAG, "$POSITION $itemPosition saved")
}
override fun onDestroy() {
Log.i(TAG, "onDestroy")
super.onDestroy()
@@ -0,0 +1,117 @@
package com.lizongying.mytv
import android.app.Application
import android.content.Context
import android.content.res.Resources
import android.util.DisplayMetrics
import android.view.WindowManager
import androidx.multidex.MultiDex
class MyTvApplication : Application() {
private lateinit var displayMetrics: DisplayMetrics
private lateinit var realDisplayMetrics: DisplayMetrics
private lateinit var windowManager: WindowManager
private var width = 0
private var height = 0
private var shouldWidth = 0
private var shouldHeight = 0
private var deviation = 0
private var ratio = 1.0
private var density = 2.0f
private var scale = 1.0f
override fun onCreate() {
super.onCreate()
displayMetrics = DisplayMetrics()
realDisplayMetrics = DisplayMetrics()
windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
windowManager.defaultDisplay.getMetrics(displayMetrics)
windowManager.defaultDisplay.getRealMetrics(realDisplayMetrics)
if (realDisplayMetrics.heightPixels > realDisplayMetrics.widthPixels) {
width = realDisplayMetrics.heightPixels
height = realDisplayMetrics.widthPixels
} else {
width = realDisplayMetrics.widthPixels
height = realDisplayMetrics.heightPixels
}
density = displayMetrics.density
ratio = if ((width.toDouble() / height) < (16.0 / 9)) {
width * 2 / 1920.0 / density
} else {
height * 2 / 1080.0 / density
}
if ((width.toDouble() / height) < (16.0 / 9.0)) {
ratio = width * 2 / 1920.0 / density
shouldWidth = width
shouldHeight = (width * 9.0 / 16.0).toInt()
} else {
ratio = height * 2 / 1080.0 / density
shouldHeight = height
shouldWidth = (height * 16.0 / 9.0).toInt()
}
deviation = width - Resources.getSystem().displayMetrics.widthPixels
scale = Resources.getSystem().displayMetrics.scaledDensity
}
fun getDisplayMetrics(): DisplayMetrics {
return displayMetrics
}
fun getRealDisplayMetrics(): DisplayMetrics {
return realDisplayMetrics
}
fun shouldWidthPx(): Int {
return shouldWidth
}
fun shouldHeightPx(): Int {
return shouldHeight
}
fun getWidth(): Int {
return width
}
fun getHeight(): Int {
return height
}
fun getDeviation(): Int {
return deviation
}
fun getRatio(): Double {
return ratio
}
fun dp2Px(dp: Int): Int {
return (dp * ratio * density + 0.5f).toInt()
}
fun px2Px(px: Int): Int {
return (px * ratio + 0.5f).toInt()
}
fun px2PxFont(px: Float): Float {
return (px * ratio / scale).toFloat()
}
fun sp2Px(sp: Float): Float {
return (sp * ratio * scale).toFloat()
}
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
MultiDex.install(base)
}
}
@@ -0,0 +1,16 @@
package com.lizongying.mytv
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.net.ConnectivityManager
class NetworkChangeReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
val isConnected = context?.isNetworkConnected
if (isConnected == true) {
}
}
}
}
@@ -78,14 +78,22 @@ class PlayerFragment : Fragment(), SurfaceHolder.Callback {
override fun onPlayerError(error: PlaybackException) {
super.onPlayerError(error)
Log.e(TAG, "PlaybackException $error")
tvViewModel?.changed()
val err = "播放错误"
tvViewModel?.setErrInfo(err)
tvViewModel?.changed("retry")
}
override fun onIsPlayingChanged(isPlaying: Boolean) {
super.onIsPlayingChanged(isPlaying)
if (isPlaying) {
tvViewModel?.setErrInfo("")
}
}
})
}
})
(activity as MainActivity).fragmentReady()
(activity as MainActivity).fragmentReady(TAG)
return _binding!!.root
}
@@ -146,7 +154,7 @@ class PlayerFragment : Fragment(), SurfaceHolder.Callback {
}
companion object {
private const val TAG = "PlaybackVideoFragment"
private const val TAG = "PlayerFragment"
}
override fun surfaceCreated(holder: SurfaceHolder) {
@@ -1,707 +0,0 @@
package com.lizongying.mytv
import android.os.Handler
import android.os.Looper
import android.util.Base64
import android.util.Log
import com.lizongying.mytv.Utils.getDateFormat
import com.lizongying.mytv.api.ApiClient
import com.lizongying.mytv.api.Auth
import com.lizongying.mytv.api.AuthRequest
import com.lizongying.mytv.api.FAuth
import com.lizongying.mytv.api.FAuthService
import com.lizongying.mytv.api.FEPG
import com.lizongying.mytv.api.Info
import com.lizongying.mytv.api.InfoV2
import com.lizongying.mytv.api.LiveInfo
import com.lizongying.mytv.api.LiveInfoRequest
import com.lizongying.mytv.api.Token
import com.lizongying.mytv.api.YSP
import com.lizongying.mytv.api.YSPApiService
import com.lizongying.mytv.api.YSPBtraceService
import com.lizongying.mytv.api.YSPProtoService
import com.lizongying.mytv.api.YSPTokenService
import com.lizongying.mytv.models.TVViewModel
import com.lizongying.mytv.proto.Ysp.cn.yangshipin.oms.common.proto.pageModel
import com.lizongying.mytv.proto.Ysp.cn.yangshipin.omstv.common.proto.epgProgramModel
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
import kotlin.math.max
object Request {
private const val TAG = "Request"
private var yspTokenService: YSPTokenService = ApiClient().yspTokenService
private var yspApiService: YSPApiService = ApiClient().yspApiService
private var yspBtraceService: YSPBtraceService = ApiClient().yspBtraceService
private var yspProtoService: YSPProtoService = ApiClient().yspProtoService
private var fAuthService: FAuthService = ApiClient().fAuthService
private var token = ""
private var tokenFH = ""
private var needAuth = false
private val handler = Handler(Looper.getMainLooper())
private lateinit var btraceRunnable: BtraceRunnable
private var tokenRunnable: TokenRunnable = TokenRunnable()
private val regex = Regex("""des_key = "([^"]+).+var des_iv = "([^"]+)""")
private val input =
"""{"mver":"1","subver":"1.2","host":"www.yangshipin.cn/#/tv/home?pid=","referer":"","canvas":"YSPANGLE(Apple,ANGLEMetalRenderer:AppleM1Pro,UnspecifiedVersion)"}""".toByteArray()
private var listener: RequestListener? = null
fun onCreate() {
Log.i(TAG, "onCreate")
fetchInfoV2()
}
fun onDestroy() {
Log.i(TAG, "onDestroy")
handler.removeCallbacks(tokenRunnable)
}
var call: Call<LiveInfo>? = null
private var callAuth: Call<Auth>? = null
private fun fetchAuth(tvModel: TVViewModel, cookie: String) {
callAuth?.cancel()
val title = tvModel.title.value
val data = YSP.getAuthData(tvModel)
val request = AuthRequest(data)
callAuth = request.let { yspApiService.getAuth("guid=${YSP.getGuid()}; $cookie", it) }
callAuth?.enqueue(object : Callback<Auth> {
override fun onResponse(call: Call<Auth>, response: Response<Auth>) {
if (response.isSuccessful) {
val liveInfo = response.body()
if (liveInfo?.data?.token != null) {
Log.i(TAG, "token ${liveInfo.data.token}")
YSP.token = liveInfo.data.token
fetchVideo(tvModel, cookie)
} else {
Log.e(TAG, "$title token error")
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
tvModel.retryTimes++
if (tvModel.getTV().needToken) {
if (tvModel.tokenRetryTimes == tvModel.tokenRetryMaxTimes) {
if (!tvModel.getTV().mustToken) {
fetchAuth(tvModel, cookie)
}
} else {
token = ""
fetchAuth(tvModel)
}
} else {
fetchAuth(tvModel, cookie)
}
}
}
} else {
Log.e(TAG, "$title auth status error")
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
tvModel.retryTimes++
if (tvModel.getTV().needToken) {
if (tvModel.tokenRetryTimes == tvModel.tokenRetryMaxTimes) {
if (!tvModel.getTV().mustToken) {
fetchAuth(tvModel, cookie)
}
} else {
token = ""
fetchAuth(tvModel)
}
} else {
fetchAuth(tvModel, cookie)
}
}
}
}
override fun onFailure(call: Call<Auth>, t: Throwable) {
Log.e(TAG, "$title auth request error $t")
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
tvModel.retryTimes++
if (tvModel.getTV().needToken) {
if (tvModel.tokenRetryTimes == tvModel.tokenRetryMaxTimes) {
if (!tvModel.getTV().mustToken) {
fetchAuth(tvModel, cookie)
}
} else {
token = ""
fetchAuth(tvModel)
}
} else {
fetchAuth(tvModel, cookie)
}
}
}
})
}
fun fetchVideo(tvModel: TVViewModel, cookie: String) {
Log.i(TAG, "fetchVideo with cookie")
call?.cancel()
if (::btraceRunnable.isInitialized) {
handler.removeCallbacks(btraceRunnable)
}
val title = tvModel.title.value
tvModel.seq = 0
val data = YSP.switch(tvModel)
val request = LiveInfoRequest(data)
call = request.let {
yspApiService.getLiveInfo(
"guid=${YSP.getGuid()}; $cookie",
YSP.token,
it
)
}
call?.enqueue(object : Callback<LiveInfo> {
override fun onResponse(call: Call<LiveInfo>, response: Response<LiveInfo>) {
if (response.isSuccessful) {
val liveInfo = response.body()
if (liveInfo?.data?.playurl != null) {
val chanll = liveInfo.data.chanll
val decodedBytes = Base64.decode(
chanll.substring(9, chanll.length - 3),
Base64.DEFAULT
)
val decodedString = String(decodedBytes)
val matchResult = regex.find(decodedString)
if (matchResult != null) {
val (key, iv) = matchResult.destructured
val keyBytes = Base64.decode(key, Base64.DEFAULT)
val ivBytes = Base64.decode(iv, Base64.DEFAULT)
val url = liveInfo.data.playurl + "&revoi=" + encryptTripleDES(
keyBytes + byteArrayOf(0, 0, 0, 0, 0, 0, 0, 0),
ivBytes
).uppercase() + liveInfo.data.extended_param
Log.d(TAG, "$title url $url")
tvModel.addVideoUrl(url)
tvModel.allReady()
tvModel.retryTimes = 0
btraceRunnable = BtraceRunnable(tvModel)
handler.post(btraceRunnable)
} else {
Log.e(TAG, "$title key error")
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
tvModel.retryTimes++
if (tvModel.getTV().needToken) {
if (tvModel.tokenRetryTimes == tvModel.tokenRetryMaxTimes) {
if (!tvModel.getTV().mustToken) {
fetchVideo(tvModel, cookie)
// fetchAuth(tvModel, cookie)
}
} else {
token = ""
fetchVideo(tvModel)
// fetchAuth(tvModel)
}
} else {
fetchVideo(tvModel, cookie)
// fetchAuth(tvModel, cookie)
}
}
}
} else {
if (liveInfo?.data?.errinfo != null && liveInfo.data.errinfo == "应版权方要求,暂停提供直播信号,请点击观看其他精彩节目") {
Log.e(TAG, "$title error ${liveInfo.data.errinfo}")
tvModel.setErrInfo(liveInfo.data.errinfo)
} else {
Log.e(TAG, "$title url error $request $liveInfo")
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
tvModel.retryTimes++
if (tvModel.getTV().needToken) {
if (tvModel.tokenRetryTimes == tvModel.tokenRetryMaxTimes) {
if (!tvModel.getTV().mustToken) {
fetchVideo(tvModel, cookie)
// fetchAuth(tvModel, cookie)
}
} else {
token = ""
fetchVideo(tvModel)
// fetchAuth(tvModel)
}
} else {
fetchVideo(tvModel, cookie)
// fetchAuth(tvModel, cookie)
}
}
}
}
} else {
Log.e(TAG, "$title status error")
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
tvModel.retryTimes++
if (tvModel.getTV().needToken) {
if (tvModel.tokenRetryTimes == tvModel.tokenRetryMaxTimes) {
if (!tvModel.getTV().mustToken) {
fetchVideo(tvModel, cookie)
// fetchAuth(tvModel, cookie)
}
} else {
token = ""
fetchVideo(tvModel)
// fetchAuth(tvModel)
}
} else {
fetchVideo(tvModel, cookie)
// fetchAuth(tvModel, cookie)
}
}
}
}
override fun onFailure(call: Call<LiveInfo>, t: Throwable) {
Log.e(TAG, "$title fetchVideo request error $t")
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
tvModel.retryTimes++
if (tvModel.getTV().needToken) {
if (tvModel.tokenRetryTimes == tvModel.tokenRetryMaxTimes) {
if (!tvModel.getTV().mustToken) {
fetchVideo(tvModel, cookie)
}
} else {
token = ""
fetchVideo(tvModel)
}
} else {
fetchVideo(tvModel, cookie)
}
}
}
})
}
fun fetchAuth(tvModel: TVViewModel) {
if (token == "") {
yspTokenService.getInfo("")
.enqueue(object : Callback<Info> {
override fun onResponse(call: Call<Info>, response: Response<Info>) {
if (response.isSuccessful) {
token = response.body()?.data?.token!!
Log.i(TAG, "info success $token")
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109;yspopenid=vu0-8lgGV2LW9QjDeuBFsX8yMnzs37Q3_HZF6XyVDpGR_I; vusession=$token"
fetchAuth(tvModel, cookie)
} else {
Log.e(TAG, "info status error")
if (tvModel.tokenRetryTimes < tvModel.tokenRetryMaxTimes) {
tvModel.tokenRetryTimes++
fetchAuth(tvModel)
} else {
if (!tvModel.getTV().mustToken) {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109"
fetchAuth(tvModel, cookie)
}
}
}
}
override fun onFailure(call: Call<Info>, t: Throwable) {
Log.e(TAG, "info request error $t")
if (tvModel.tokenRetryTimes < tvModel.tokenRetryMaxTimes) {
tvModel.tokenRetryTimes++
fetchVideo(tvModel)
} else {
if (!tvModel.getTV().mustToken) {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109"
fetchAuth(tvModel, cookie)
}
}
}
})
} else {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109;yspopenid=vu0-8lgGV2LW9QjDeuBFsX8yMnzs37Q3_HZF6XyVDpGR_I; vusession=$token"
fetchAuth(tvModel, cookie)
}
}
fun fetchVideo(tvModel: TVViewModel) {
Log.d(TAG, "fetchVideo")
if (token == "") {
yspTokenService.getInfo("")
.enqueue(object : Callback<Info> {
override fun onResponse(call: Call<Info>, response: Response<Info>) {
if (response.isSuccessful && response.body()?.data?.token != null) {
token = response.body()?.data?.token!!
Log.i(TAG, "info success $token")
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109; yspopenid=vu0-8lgGV2LW9QjDeuBFsX8yMnzs37Q3_HZF6XyVDpGR_I; vusession=$token"
fetchVideo(tvModel, cookie)
} else {
Log.e(TAG, "info status error")
if (tvModel.tokenRetryTimes < tvModel.tokenRetryMaxTimes) {
tvModel.tokenRetryTimes++
fetchVideo(tvModel)
} else {
if (!tvModel.getTV().mustToken) {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109"
fetchVideo(tvModel, cookie)
}
}
}
}
override fun onFailure(call: Call<Info>, t: Throwable) {
Log.e(TAG, "info request error $t")
if (tvModel.tokenRetryTimes < tvModel.tokenRetryMaxTimes) {
tvModel.tokenRetryTimes++
fetchVideo(tvModel)
} else {
if (!tvModel.getTV().mustToken) {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109"
fetchVideo(tvModel, cookie)
}
}
}
})
} else {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109; yspopenid=vu0-8lgGV2LW9QjDeuBFsX8yMnzs37Q3_HZF6XyVDpGR_I; vusession=$token"
fetchVideo(tvModel, cookie)
}
}
private var fAuth: Call<FAuth>? = null
fun fetchFAuth(tvModel: TVViewModel) {
call?.cancel()
callAuth?.cancel()
fAuth?.cancel()
val title = tvModel.title.value
var qa = "HD"
if (tokenFH != "") {
qa = "FHD"
}
fAuth = fAuthService.getAuth(tokenFH, tvModel.getTV().pid, qa)
fAuth?.enqueue(object : Callback<FAuth> {
override fun onResponse(call: Call<FAuth>, response: Response<FAuth>) {
if (response.isSuccessful && response.body()?.data?.live_url != null) {
val url = response.body()?.data?.live_url!!
// Log.d(TAG, "$title url $url")
tvModel.addVideoUrl(url)
tvModel.allReady()
tvModel.tokenRetryTimes = 0
} else {
Log.e(TAG, "auth status error ${response.code()}")
if (tvModel.tokenRetryTimes < tvModel.tokenRetryMaxTimes) {
tvModel.tokenRetryTimes++
fetchFAuth(tvModel)
}
}
}
override fun onFailure(call: Call<FAuth>, t: Throwable) {
Log.e(TAG, "auth request error $t")
if (tvModel.tokenRetryTimes < tvModel.tokenRetryMaxTimes) {
tvModel.tokenRetryTimes++
fetchFAuth(tvModel)
}
}
})
}
fun fetchData(tvModel: TVViewModel) {
Log.i(TAG, "fetchData")
if (tvModel.getTV().channel == "港澳台") {
fetchFAuth(tvModel)
return
}
if (tvModel.getTV().needToken) {
if (needAuth) {
fetchAuth(tvModel)
} else {
fetchVideo(tvModel)
}
} else {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205"
if (needAuth) {
fetchAuth(tvModel, cookie)
} else {
fetchVideo(tvModel, cookie)
}
}
}
class TokenRunnable : Runnable {
override fun run() {
fetchToken()
}
}
private fun fetchInfoV2() {
yspTokenService.getInfoV2()
.enqueue(object : Callback<InfoV2> {
override fun onResponse(call: Call<InfoV2>, response: Response<InfoV2>) {
if (response.isSuccessful) {
val t = response.body()?.t
val f = response.body()?.f
val e = response.body()?.e
val c = response.body()?.c
if (!t.isNullOrEmpty()) {
token = t
Log.i(TAG, "token success $token")
if (e != null) {
handler.postDelayed(
tokenRunnable,
max(30 * 60 * 1000, (e - 1500) * 1000).toLong()
)
} else {
Log.e(TAG, "e empty")
handler.postDelayed(
tokenRunnable,
30 * 60 * 1000
)
}
} else {
Log.e(TAG, "token empty")
handler.postDelayed(
tokenRunnable,
30 * 60 * 1000
)
}
if (!f.isNullOrEmpty()) {
tokenFH = f
Log.i(TAG, "tokenFH success $tokenFH")
}
if (c != null) {
Utils.setBetween(c * 1000L)
Log.i(TAG, "current time $c")
}
} else {
Log.e(TAG, "token status error")
handler.postDelayed(
tokenRunnable,
30 * 60 * 1000
)
}
listener?.onRequestFinished()
}
override fun onFailure(call: Call<InfoV2>, t: Throwable) {
Log.e(TAG, "token request error $t")
handler.postDelayed(
tokenRunnable,
30 * 60 * 1000
)
listener?.onRequestFinished()
}
})
}
fun fetchToken() {
yspTokenService.getToken(token)
.enqueue(object : Callback<Token> {
override fun onResponse(call: Call<Token>, response: Response<Token>) {
if (response.isSuccessful) {
val t = response.body()?.t
val e = response.body()?.e
if (!t.isNullOrEmpty()) {
token = t
Log.e(TAG, "token success $token")
if (e != null) {
handler.postDelayed(
tokenRunnable,
max(30 * 60 * 1000, (e - 1500) * 1000).toLong()
)
} else {
Log.e(TAG, "e empty")
handler.postDelayed(
tokenRunnable,
30 * 60 * 1000
)
}
} else {
Log.e(TAG, "token empty")
handler.postDelayed(
tokenRunnable,
30 * 60 * 1000
)
}
} else {
Log.e(TAG, "token status error")
handler.postDelayed(
tokenRunnable,
30 * 60 * 1000
)
}
}
override fun onFailure(call: Call<Token>, t: Throwable) {
Log.e(TAG, "token request error $t")
handler.postDelayed(
tokenRunnable,
30 * 60 * 1000
)
}
})
}
class BtraceRunnable(private val tvModel: TVViewModel) : Runnable {
override fun run() {
fetchBtrace(tvModel)
handler.postDelayed(this, 60000)
}
}
fun fetchBtrace(tvModel: TVViewModel) {
val title = tvModel.title.value
val guid = YSP.getGuid()
val pid = tvModel.pid.value!!
val sid = tvModel.sid.value!!
yspBtraceService.kvcollect(
c_timestamp = YSP.generateGuid(),
guid = guid,
c_guid = guid,
prog = sid,
viewid = sid,
fpid = pid,
livepid = pid,
sUrl = "https://www.yangshipin.cn/#/tv/home?pid=$pid",
playno = YSP.getRand(),
ftime = getDateFormat("yyyy-MM-dd HH:mm:ss"),
seq = tvModel.seq.toString(),
)
.enqueue(object : Callback<Void> {
override fun onResponse(call: Call<Void>, response: Response<Void>) {
if (response.isSuccessful) {
// Log.d(TAG, "$title kvcollect success")
} else {
Log.e(TAG, "$title kvcollect status error")
}
}
override fun onFailure(call: Call<Void>, t: Throwable) {
Log.e(TAG, "$title kvcollect request error")
}
})
tvModel.seq++
}
fun fetchPage() {
yspProtoService.getPage().enqueue(object : Callback<pageModel.Response> {
override fun onResponse(
call: Call<pageModel.Response>,
response: Response<pageModel.Response>
) {
if (response.isSuccessful) {
val body = response.body()
if (body?.data?.feedModuleListCount == 1) {
for (item in body.data?.feedModuleListList!![0]?.dataTvChannelListList!!) {
Log.d(
TAG,
"${item.channelName},${item.pid},${item.streamId}"
)
for ((_, v) in TVList.list) {
for (v2 in v) {
if (v2.title == item.channelName || v2.alias == item.channelName) {
v2.pid = item.pid
v2.sid = item.streamId
}
}
}
}
}
}
}
override fun onFailure(call: Call<pageModel.Response>, t: Throwable) {
Log.e(TAG, "Page request failed", t)
}
})
}
fun fetchYEPG(tvViewModel: TVViewModel) {
val title = tvViewModel.title.value
yspProtoService.getProgram(tvViewModel.programId.value!!, getDateFormat("yyyyMMdd"))
.enqueue(object : Callback<epgProgramModel.Response> {
override fun onResponse(
call: Call<epgProgramModel.Response>,
response: Response<epgProgramModel.Response>
) {
if (response.isSuccessful) {
val program = response.body()
if (program != null) {
tvViewModel.addYEPG(program.dataListList)
Log.d(TAG, "$title program ${program.dataListList.size}")
}
} else {
Log.w(TAG, "$title program error")
}
}
override fun onFailure(call: Call<epgProgramModel.Response>, t: Throwable) {
Log.e(TAG, "$title program request failed $t")
}
})
}
fun fetchFEPG(tvViewModel: TVViewModel) {
val title = tvViewModel.title.value
fAuthService.getEPG(tvViewModel.pid.value!!, getDateFormat("yyyyMMdd"))
.enqueue(object : Callback<List<FEPG>> {
override fun onResponse(
call: Call<List<FEPG>>,
response: Response<List<FEPG>>
) {
if (response.isSuccessful) {
val program = response.body()
if (program != null) {
tvViewModel.addFEPG(program)
Log.d(TAG, "$title program ${program.size}")
}
} else {
Log.w(TAG, "$title program error")
}
}
override fun onFailure(call: Call<List<FEPG>>, t: Throwable) {
Log.e(TAG, "$title program request failed $t")
}
})
}
private fun encryptTripleDES(key: ByteArray, iv: ByteArray): String {
return try {
val keySpec = SecretKeySpec(key, "DESede")
val ivSpec = IvParameterSpec(iv)
val cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec)
return cipher.doFinal(input).let { it -> it.joinToString("") { "%02x".format(it) } }
} catch (e: Exception) {
e.printStackTrace()
""
}
}
interface RequestListener {
fun onRequestFinished()
}
fun setRequestListener(listener: RequestListener) {
this.listener = listener
}
}
+18 -1
View File
@@ -6,14 +6,23 @@ import android.content.SharedPreferences
object SP {
// Name of the sp file TODO Should use a meaningful name and do migrations
private const val SP_FILE_NAME = "MainActivity"
// If Change channel with up and down in reversed order or not
private const val KEY_CHANNEL_REVERSAL = "channel_reversal"
// If use channel num to select channel or not
private const val KEY_CHANNEL_NUM = "channel_num"
private const val KEY_TIME = "time"
// If start app on device boot or not
private const val KEY_BOOT_STARTUP = "boot_startup"
private const val KEY_GRID = "grid"
// Position in list of the selected channel item
private const val KEY_POSITION = "position"
// guid
private const val KEY_GUID = "guid"
@@ -34,15 +43,23 @@ object SP {
get() = sp.getBoolean(KEY_CHANNEL_NUM, true)
set(value) = sp.edit().putBoolean(KEY_CHANNEL_NUM, value).apply()
var time: Boolean
get() = sp.getBoolean(KEY_TIME, true)
set(value) = sp.edit().putBoolean(KEY_TIME, value).apply()
var bootStartup: Boolean
get() = sp.getBoolean(KEY_BOOT_STARTUP, false)
set(value) = sp.edit().putBoolean(KEY_BOOT_STARTUP, value).apply()
var grid: Boolean
get() = sp.getBoolean(KEY_GRID, false)
set(value) = sp.edit().putBoolean(KEY_GRID, value).apply()
var itemPosition: Int
get() = sp.getInt(KEY_POSITION, 0)
set(value) = sp.edit().putInt(KEY_POSITION, value).apply()
var guid: String
get() = sp.getString(KEY_GUID, "") ?: ""
get() = sp.getString(KEY_GUID, "") ?: ""
set(value) = sp.edit().putString(KEY_GUID, value).apply()
}
@@ -1,27 +1,42 @@
package com.lizongying.mytv
import android.Manifest
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.marginEnd
import androidx.core.view.marginTop
import androidx.fragment.app.DialogFragment
import com.lizongying.mytv.databinding.DialogBinding
import com.lizongying.mytv.databinding.SettingBinding
class SettingFragment(
private val versionName: String,
private val versionCode: Long,
private val channelReversal: Boolean,
private val channelNum: Boolean,
private val bootStartup: Boolean,
) :
DialogFragment() {
class SettingFragment : DialogFragment() {
private var _binding: DialogBinding? = null
private var _binding: SettingBinding? = null
private val binding get() = _binding!!
private lateinit var updateManager: UpdateManager
override fun onStart() {
super.onStart()
dialog?.window?.apply {
addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
attributes.layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
setAttributes(attributes)
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
@@ -32,45 +47,180 @@ class SettingFragment(
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = DialogBinding.inflate(inflater, container, false)
_binding?.version?.text =
"当前版本: $versionName\n获取最新: https://github.com/lizongying/my-tv/releases/"
val context = requireContext() // It‘s safe to get context here.
_binding = SettingBinding.inflate(inflater, container, false)
binding.versionName.text = "当前版本: v${context.appVersionName}"
binding.version.text = "https://github.com/lizongying/my-tv"
val switchChannelReversal = _binding?.switchChannelReversal
switchChannelReversal?.isChecked = channelReversal
switchChannelReversal?.setOnCheckedChangeListener { _, isChecked ->
SP.channelReversal = isChecked
(activity as MainActivity).settingActive()
binding.switchChannelReversal.run {
isChecked = SP.channelReversal
setOnCheckedChangeListener { _, isChecked ->
SP.channelReversal = isChecked
(activity as MainActivity).settingDelayHide()
}
}
val switchChannelNum = _binding?.switchChannelNum
switchChannelNum?.isChecked = channelNum
switchChannelNum?.setOnCheckedChangeListener { _, isChecked ->
SP.channelNum = isChecked
(activity as MainActivity).settingActive()
binding.switchChannelNum.run {
isChecked = SP.channelNum
setOnCheckedChangeListener { _, isChecked ->
SP.channelNum = isChecked
(activity as MainActivity).settingDelayHide()
}
}
val switchBootStartup = _binding?.switchBootStartup
switchBootStartup?.isChecked = bootStartup
switchBootStartup?.setOnCheckedChangeListener { _, isChecked ->
SP.bootStartup = isChecked
(activity as MainActivity).settingActive()
binding.switchTime.run {
isChecked = SP.time
setOnCheckedChangeListener { _, isChecked ->
SP.time = isChecked
(activity as MainActivity).settingDelayHide()
}
}
updateManager = UpdateManager(context, this, versionCode)
_binding?.checkVersion?.setOnClickListener(OnClickListenerCheckVersion(updateManager))
binding.switchBootStartup.run {
isChecked = SP.bootStartup
setOnCheckedChangeListener { _, isChecked ->
SP.bootStartup = isChecked
(activity as MainActivity).settingDelayHide()
}
}
binding.switchGrid.run {
isChecked = SP.grid
setOnCheckedChangeListener { _, isChecked ->
SP.grid = isChecked
(activity as MainActivity).settingDelayHide()
}
}
binding.checkVersion.setOnClickListener {
(activity as MainActivity).settingDelayHide()
requestInstallPermissions()
}
val application = requireActivity().applicationContext as MyTvApplication
binding.content.layoutParams.width =
application.px2Px(binding.content.layoutParams.width)
binding.content.setPadding(
application.px2Px(binding.content.paddingLeft),
application.px2Px(binding.content.paddingTop),
application.px2Px(binding.content.paddingRight),
application.px2Px(binding.content.paddingBottom)
)
binding.name.textSize = application.px2PxFont(binding.name.textSize)
binding.version.textSize = application.px2PxFont(binding.version.textSize)
val layoutParamsVersion = binding.version.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsVersion.topMargin = application.px2Px(binding.version.marginTop)
binding.version.layoutParams = layoutParamsVersion
binding.checkVersion.textSize = application.px2PxFont(binding.checkVersion.textSize)
val layoutParamsCheckVersion =
binding.checkVersion.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsCheckVersion.marginEnd = application.px2Px(binding.checkVersion.marginEnd)
binding.checkVersion.layoutParams = layoutParamsCheckVersion
binding.versionName.textSize = application.px2PxFont(binding.versionName.textSize)
binding.exit.textSize = application.px2PxFont(binding.exit.textSize)
binding.switchChannelReversal.textSize =
application.px2PxFont(binding.switchChannelReversal.textSize)
val layoutParamsChannelReversal =
binding.switchChannelReversal.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsChannelReversal.topMargin =
application.px2Px(binding.switchChannelReversal.marginTop)
binding.switchChannelReversal.layoutParams = layoutParamsChannelReversal
binding.switchChannelNum.textSize = application.px2PxFont(binding.switchChannelNum.textSize)
val layoutParamsChannelNum =
binding.switchChannelNum.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsChannelNum.topMargin = application.px2Px(binding.switchChannelNum.marginTop)
binding.switchChannelNum.layoutParams = layoutParamsChannelNum
binding.switchTime.textSize = application.px2PxFont(binding.switchTime.textSize)
val layoutParamsTime = binding.switchTime.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsTime.topMargin = application.px2Px(binding.switchTime.marginTop)
binding.switchTime.layoutParams = layoutParamsTime
binding.switchBootStartup.textSize =
application.px2PxFont(binding.switchBootStartup.textSize)
val layoutParamsBootStartup =
binding.switchBootStartup.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsBootStartup.topMargin = application.px2Px(binding.switchBootStartup.marginTop)
binding.switchBootStartup.layoutParams = layoutParamsBootStartup
binding.switchGrid.textSize = application.px2PxFont(binding.switchGrid.textSize)
val layoutParamsGrid = binding.switchGrid.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsGrid.topMargin = application.px2Px(binding.switchGrid.marginTop)
binding.switchGrid.layoutParams = layoutParamsGrid
binding.appreciate.layoutParams.width =
application.px2Px(binding.appreciate.layoutParams.width)
binding.exit.setOnClickListener {
requireActivity().finishAffinity()
}
return binding.root
}
fun setVersionName(versionName: String) {
binding.versionName.text = versionName
private fun requestInstallPermissions() {
val context = requireContext()
val permissionsList: MutableList<String> = ArrayList()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !context.packageManager.canRequestPackageInstalls()) {
permissionsList.add(Manifest.permission.REQUEST_INSTALL_PACKAGES)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
ContextCompat.checkSelfPermission(
context,
Manifest.permission.READ_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED
) {
permissionsList.add(Manifest.permission.READ_EXTERNAL_STORAGE)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
ContextCompat.checkSelfPermission(
context,
Manifest.permission.WRITE_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED
) {
permissionsList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
if (permissionsList.isNotEmpty()) {
ActivityCompat.requestPermissions(
requireActivity(),
permissionsList.toTypedArray<String>(),
PERMISSIONS_REQUEST_CODE
)
} else {
UpdateManager(context, context.appVersionCode).checkAndUpdate()
}
}
internal class OnClickListenerCheckVersion(private val updateManager: UpdateManager) :
View.OnClickListener {
override fun onClick(view: View?) {
updateManager.checkAndUpdate()
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == PERMISSIONS_REQUEST_CODE) {
var allPermissionsGranted = true
for (result in grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
allPermissionsGranted = false
break
}
}
if (allPermissionsGranted) {
val context = requireContext()
UpdateManager(context, context.appVersionCode).checkAndUpdate()
} else {
Toast.makeText(context, "权限授权失败", Toast.LENGTH_LONG).show()
}
}
}
@@ -79,13 +229,9 @@ class SettingFragment(
_binding = null
}
override fun onDestroy() {
super.onDestroy()
// updateManager.destroy()
}
companion object {
const val TAG = "SettingFragment"
const val PERMISSIONS_REQUEST_CODE = 1
}
}
@@ -0,0 +1,83 @@
package com.lizongying.mytv
import android.os.Bundle
import android.os.Handler
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.marginEnd
import androidx.core.view.marginTop
import androidx.fragment.app.Fragment
import com.lizongying.mytv.Utils.getDateFormat
import com.lizongying.mytv.databinding.TimeBinding
class TimeFragment : Fragment() {
private var _binding: TimeBinding? = null
private val binding get() = _binding!!
private val handler = Handler()
private val delay: Long = 1000
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = TimeBinding.inflate(inflater, container, false)
val application = requireActivity().applicationContext as MyTvApplication
binding.time.layoutParams.width = application.px2Px(binding.time.layoutParams.width)
binding.time.layoutParams.height = application.px2Px(binding.time.layoutParams.height)
val layoutParams = binding.time.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.topMargin = application.px2Px(binding.time.marginTop)
layoutParams.marginEnd = application.px2Px(binding.time.marginEnd)
binding.time.layoutParams = layoutParams
binding.content.textSize = application.px2PxFont(binding.content.textSize)
binding.channel.textSize = application.px2PxFont(binding.channel.textSize)
binding.main.layoutParams.width = application.shouldWidthPx()
binding.main.layoutParams.height = application.shouldHeightPx()
if (SP.time) {
handler.removeCallbacks(showRunnable)
handler.postDelayed(showRunnable, 0)
} else {
handler.removeCallbacks(showRunnable)
}
(activity as MainActivity).fragmentReady(TAG)
return binding.root
}
override fun onHiddenChanged(hidden: Boolean) {
super.onHiddenChanged(hidden)
if (!hidden) {
handler.removeCallbacks(showRunnable)
handler.postDelayed(showRunnable, 0)
} else {
handler.removeCallbacks(showRunnable)
}
}
private val showRunnable: Runnable = Runnable {
run {
if (_binding == null) {
return@Runnable
}
binding.content.text = getDateFormat("HH:mm")
handler.postDelayed(showRunnable, delay)
}
}
override fun onDestroyView() {
handler.removeCallbacks(showRunnable)
super.onDestroyView()
_binding = null
}
companion object {
private const val TAG = "TimeFragment"
}
}
@@ -13,9 +13,10 @@ import android.os.Environment
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.widget.Toast
import com.lizongying.mytv.api.Release
import com.lizongying.mytv.requests.MyRequest
import androidx.fragment.app.FragmentActivity
import com.lizongying.mytv.api.ApiClient
import com.lizongying.mytv.requests.ReleaseRequest
import com.lizongying.mytv.requests.ReleaseResponse
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -23,81 +24,95 @@ import java.io.File
class UpdateManager(
private var context: Context?,
private var settingFragment: SettingFragment,
private var context: Context,
private var versionCode: Long
) :
ConfirmationDialogFragment.ConfirmationDialogListener {
ConfirmationFragment.ConfirmationListener {
private var myRequest = MyRequest()
private var release: Release? = null
private var releaseRequest = ReleaseRequest()
private var release: ReleaseResponse? = null
private var downloadReceiver: DownloadReceiver? = null
fun checkAndUpdate() {
CoroutineScope(Dispatchers.Main).launch {
var text = "版本获取失败"
var update = false
try {
release = myRequest.getRelease()
updateUI(release)
Log.i(TAG, "versionCode $versionCode ${release?.data?.versionCode}")
if (release != null) {
if (release?.data?.versionCode!! >= versionCode) {
val dialog = ConfirmationDialogFragment(this@UpdateManager)
dialog.show(settingFragment.fragmentManager, "ConfirmationDialogFragment")
release = releaseRequest.getRelease()
Log.i(TAG, "versionCode $versionCode ${release?.version_code}")
if (release?.version_code != null) {
if (release?.version_code!! > versionCode) {
text = "最新版本:${release?.version_name}"
update = true
} else {
Toast.makeText(context, "不需要更新", Toast.LENGTH_LONG)
.show()
text = "已是最新版本,不需要更新"
}
}
} catch (e: Exception) {
Log.e(TAG, "Error occurred: ${e.message}", e)
}
updateUI(text, update)
}
}
private fun updateUI(release: Release?) {
if (release?.data?.versionName.isNullOrEmpty()) {
settingFragment.setVersionName("版本获取失败")
} else {
settingFragment.setVersionName("最新版本:${release?.data?.versionName!!}")
}
private fun updateUI(text: String, update: Boolean) {
val dialog = ConfirmationFragment(this@UpdateManager, text, update)
dialog.show((context as FragmentActivity).supportFragmentManager, TAG)
}
private fun startDownload(release: Release) {
val apkFileName = "my-tv-${release.data.versionName}.apk"
private fun startDownload(release: ReleaseResponse) {
val apkName = "my-tv"
val apkFileName = "$apkName-${release.version_name}.apk"
Log.i(TAG, "apkFileName $apkFileName")
val downloadManager =
context!!.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val request = Request(Uri.parse(release.data.downloadUrl))
Log.i(TAG, "url ${Uri.parse(release.data.downloadUrl)}")
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, apkFileName)
request.setTitle("New Version Download")
context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val request =
Request(Uri.parse("${ApiClient.DOWNLOAD_HOST}${release.version_name}/$apkName-${release.version_name}.apk"))
Log.i(
TAG,
"url ${Uri.parse("${ApiClient.DOWNLOAD_HOST}${release.version_name}/$apkName-${release.version_name}.apk")}"
)
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)?.mkdirs()
Log.i(TAG, "save dir ${Environment.DIRECTORY_DOWNLOADS}")
request.setDestinationInExternalFilesDir(
context,
Environment.DIRECTORY_DOWNLOADS,
apkFileName
)
request.setTitle("${context.resources.getString(R.string.app_name)} ${release.version_name}")
request.setNotificationVisibility(Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setAllowedOverRoaming(false)
request.setMimeType("application/vnd.android.package-archive")
// 获取下载任务的引用
val downloadReference = downloadManager.enqueue(request)
downloadReceiver = DownloadReceiver(context!!, apkFileName, downloadReference)
downloadReceiver = DownloadReceiver(context, apkFileName, downloadReference)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context!!.registerReceiver(
context.registerReceiver(
downloadReceiver,
IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE),
Context.RECEIVER_NOT_EXPORTED,
)
} else {
context!!.registerReceiver(
context.registerReceiver(
downloadReceiver,
IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
)
}
getDownloadProgress(context!!, downloadReference) { progress ->
getDownloadProgress(context, downloadReference) { progress ->
println("Download progress: $progress%")
}
}
private fun getDownloadProgress(context: Context, downloadId: Long, progressListener: (Int) -> Unit) {
private fun getDownloadProgress(
context: Context,
downloadId: Long,
progressListener: (Int) -> Unit
) {
val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val handler = Handler(Looper.getMainLooper())
val intervalMillis: Long = 1000
@@ -143,27 +158,73 @@ class UpdateManager(
override fun onReceive(context: Context, intent: Intent) {
val reference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
Log.i(TAG, "reference $reference")
val progress = intent.getIntExtra("progress", 0)
Log.i(TAG, "progress $progress")
// 检查是否是我们发起的下载
if (reference == downloadReference) {
// 下载完成,触发安装
installNewVersion()
val downloadManager =
context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val query = DownloadManager.Query().setFilterById(downloadReference)
val cursor = downloadManager.query(query)
if (cursor != null && cursor.moveToFirst()) {
val statusIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)
if (statusIndex < 0) {
Log.i(TAG, "Download failure")
return
}
val status = cursor.getInt(statusIndex)
val progressIndex =
cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)
if (progressIndex < 0) {
Log.i(TAG, "Download failure")
return
}
val progress = cursor.getInt(progressIndex)
val totalSizeIndex =
cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)
val totalSize = cursor.getInt(totalSizeIndex)
cursor.close()
when (status) {
DownloadManager.STATUS_SUCCESSFUL -> {
installNewVersion()
}
DownloadManager.STATUS_FAILED -> {
// Handle download failure
Log.i(TAG, "Download failure")
}
else -> {
// Update UI with download progress
val percentage = progress * 100 / totalSize
Log.i(TAG, "Download progress: $percentage%")
}
}
}
}
}
private fun installNewVersion() {
val installIntent = Intent(Intent.ACTION_VIEW)
val apkUri = Uri.fromFile(
File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
apkFileName
)
val apkFile = File(
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),
apkFileName
)
installIntent.setDataAndType(apkUri, "application/vnd.android.package-archive")
installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(installIntent)
Log.i(TAG, "apkFile $apkFile")
if (apkFile.exists()) {
val apkUri = Uri.parse("file://$apkFile")
Log.i(TAG, "apkUri $apkUri")
val installIntent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(apkUri, "application/vnd.android.package-archive")
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_NEW_TASK)
}
context.startActivity(installIntent)
} else {
Log.e(TAG, "APK file does not exist!")
}
}
}
@@ -179,10 +240,9 @@ class UpdateManager(
override fun onCancel() {
}
fun destroy() {
if (downloadReceiver != null) {
context!!.unregisterReceiver(downloadReceiver)
context.unregisterReceiver(downloadReceiver)
Log.i(TAG, "destroy downloadReceiver")
}
}
+45 -6
View File
@@ -5,8 +5,11 @@ import android.os.Build
import android.util.TypedValue
import com.google.gson.Gson
import com.lizongying.mytv.api.TimeResponse
import com.lizongying.mytv.requests.Request
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.Interceptor
import okhttp3.Response
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Date
@@ -15,6 +18,8 @@ import java.util.Locale
object Utils {
private var between: Long = 0
private var listener: Request.RequestListener? = null
fun getDateFormat(format: String): String {
return SimpleDateFormat(
format,
@@ -31,13 +36,32 @@ 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
withContext(Dispatchers.Main) {
listener?.onRequestFinished(null)
}
}
class RetryInterceptor(private val maxRetry: Int) : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
var response = chain.proceed(request)
var tryCount = 0
while (!response.isSuccessful && tryCount < maxRetry) {
tryCount++
response = chain.proceed(request)
}
return response
}
}
/**
@@ -47,8 +71,8 @@ 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()
.addInterceptor(RetryInterceptor(3))
.build()
val request = okhttp3.Request.Builder()
.url("https://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp")
.build()
@@ -59,7 +83,6 @@ object Utils {
Gson().fromJson(string, TimeResponse::class.java).data.t.toLong()
}
} catch (e: IOException) {
// Handle network errors
throw IOException("Error during network request", e)
}
}
@@ -72,10 +95,26 @@ object Utils {
}
fun dpToPx(dp: Int): Int {
// val density = Resources.getSystem().displayMetrics.density
// return (dp * density + 0.5f).toInt()
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), Resources.getSystem().displayMetrics
).toInt()
}
fun pxToDp(px: Float): Int {
val scale = Resources.getSystem().displayMetrics.density
return (px / scale).toInt()
}
fun pxToDp(px: Int): Int {
val scale = Resources.getSystem().displayMetrics.density
return (px / scale).toInt()
}
fun isTmallDevice() = Build.MANUFACTURER.equals("Tmall", ignoreCase = true)
fun setRequestListener(listener: Request.RequestListener) {
this.listener = listener
}
}
@@ -3,12 +3,16 @@ package com.lizongying.mytv.api
import android.os.Build
import android.util.Log
import com.lizongying.mytv.jce.JceConverterFactory
import com.lizongying.mytv.requests.ReleaseService
import okhttp3.ConnectionSpec
import okhttp3.OkHttpClient
import okhttp3.TlsVersion
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.protobuf.ProtoConverterFactory
import java.net.InetSocketAddress
import java.net.Proxy
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager
@@ -17,9 +21,11 @@ import javax.net.ssl.X509TrustManager
class ApiClient {
private val yspUrl = "https://player-api.yangshipin.cn/"
private val myUrl = "https://lyrics.run/"
private val devUrl = "http://10.0.2.2:8081/"
private val protoUrl = "https://capi.yangshipin.cn/"
private val traceUrl = "https://btrace.yangshipin.cn/"
private val trace2Url = "https://aatc-api.yangshipin.cn/"
private val trace3Url = "https://dtrace.ysp.cctv.cn/"
private val jceUrl = "https://jacc.ysp.cctv.cn/"
private val fUrl = "https://m.fengshows.com/"
private var okHttpClient = getUnsafeOkHttpClient()
@@ -42,7 +48,7 @@ class ApiClient {
val releaseService: ReleaseService by lazy {
Retrofit.Builder()
.baseUrl(myUrl)
.baseUrl(HOST)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build().create(ReleaseService::class.java)
@@ -64,6 +70,30 @@ class ApiClient {
.build().create(YSPBtraceService::class.java)
}
val yspBtraceService2: YSPBtraceService by lazy {
Retrofit.Builder()
.baseUrl(trace2Url)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build().create(YSPBtraceService::class.java)
}
val yspBtraceService3: YSPBtraceService by lazy {
Retrofit.Builder()
.baseUrl(trace3Url)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build().create(YSPBtraceService::class.java)
}
val yspJceService: YSPJceService by lazy {
Retrofit.Builder()
.baseUrl(jceUrl)
.client(okHttpClient)
.addConverterFactory(JceConverterFactory.create())
.build().create(YSPJceService::class.java)
}
val fAuthService: FAuthService by lazy {
Retrofit.Builder()
.baseUrl(fUrl)
@@ -127,9 +157,12 @@ class ApiClient {
val sslContext = SSLContext.getInstance("SSL")
sslContext.init(null, trustAllCerts, java.security.SecureRandom())
val proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress("10.0.2.2", 8888))
val builder = OkHttpClient.Builder()
.sslSocketFactory(sslContext.socketFactory, trustAllCerts[0] as X509TrustManager)
.hostnameVerifier { _, _ -> true }
// .proxy(proxy)
.dns(DnsCache())
return enableTls12OnPreLollipop(builder).build()
@@ -138,4 +171,9 @@ class ApiClient {
throw RuntimeException(e)
}
}
companion object {
const val HOST = "https://gitee.com/lizongying/my-tv/raw/"
const val DOWNLOAD_HOST = "https://gitee.com/lizongying/my-tv/releases/download/"
}
}
@@ -1,4 +1,4 @@
package com.lizongying.mytv
package com.lizongying.mytv.api
import android.content.Context
@@ -16,24 +16,19 @@ data class Token(
)
data class InfoV2(
val o: String?,
val f: String?,
val t: String?,
val e: Int?,
val c: Int?,
)
data class Release(
val code: Int?,
val msg: String?,
val data: Data,
) {
data class Data(
val versionName: String,
val versionCode: Int,
val downloadUrl: String,
val updateTime: Int,
)
}
data class ReleaseV2(
val n: String?,
val u: String?,
val d: String?,
val c: Int?,
)
data class TimeResponse(
val data: Time
@@ -0,0 +1,76 @@
package com.lizongying.mytv.api
data class KvcollectRequest(
val BossId: Int = 2727,
val Pwd: Int = 1424084450,
val cdn: String = "waibao",
val cmd: Int = 263,
val defn: String = "fhd",
val downspeed: Double = 10.0,
val durl: String = "", //
val errcode: String = "",
val fact1: String = "ysp_pc_live_b",
val firstreport: Int = 0,
val fplayerver: String = "100",
val ftime: String = "", //
val geturltime: Int = 0,
val guid: String = "", //
val hc_openid: String = "",
val hh_ua: String = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
val live_type: String = "",
val livepid: String = "", //
val login_type: String = "",
val open_id: String = "",
val openid: String = "",
val platform: String = "5910204",
val playno: String = "", //
val prd: Int = 60000,
val prog: String = "", //
val rand_str: String = "", //
val sRef: String = "",
val sUrl: String = "", //
val sdtfrom: String = "ysp_pc_01",
val seq: Int = 9, //
var signature: String = "",
val url: String = "", //
val viewid: String = "", //
val _dc: Double = 0.0,
)
data class KvcollectRequest2(
val BossId: Int = 2727,
val Pwd: Int = 1424084450,
val cdn: String = "waibao",
val cmd: Int = 263,
val defn: String = "fhd",
val downspeed: String = "10",
val durl: String = "", //
val errcode: String = "",
val fact1: String = "ysp_pc_live_b",
val firstreport: Int = 0,
val fplayerver: String = "100",
val ftime: String = "", //
val geturltime: Int = 0,
val guid: String = "", //
val hc_openid: String = "",
val hh_ua: String = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
val live_type: String = "",
val livepid: String = "", //
val login_type: String = "",
val open_id: String = "",
val openid: String = "",
val platform: String = "5910204",
val playno: String = "", //
val prd: Int = 60000,
val prog: String = "", //
val rand_str: String = "", //
val sRef: String = "",
val sUrl: String = "", //
val sdtfrom: String = "ysp_pc_01",
val seq: Int = 9, //
var signature: String = "",
val url: String = "", //
val viewid: String = "", //
val _dc: Double = 0.0,
)
@@ -1,11 +0,0 @@
package com.lizongying.mytv.api
import retrofit2.Call
import retrofit2.http.GET
interface ReleaseService {
@GET("my-tv/v1/release")
fun getRelease(
): Call<Release>
}
@@ -1,8 +1,6 @@
package com.lizongying.mytv.api
import android.content.Context
import com.lizongying.mytv.Encryptor
import com.lizongying.mytv.MainActivity
import com.lizongying.mytv.SP
import com.lizongying.mytv.Utils.getDateTimestamp
import com.lizongying.mytv.models.TVViewModel
@@ -63,8 +61,8 @@ object YSP {
}
fun switch(tvModel: TVViewModel): String {
livepid = tvModel.pid.value!!
cnlid = tvModel.sid.value!!
livepid = tvModel.getTV().pid
cnlid = tvModel.getTV().sid
defn = "fhd"
randStr = getRand()
@@ -82,7 +80,7 @@ object YSP {
}
fun getAuthData(tvModel: TVViewModel): String {
livepid = tvModel.pid.value!!
livepid = tvModel.getTV().pid
randStr = getRand()
@@ -142,4 +140,9 @@ object YSP {
val hashedData = encryptor.hash2(e) ?: return ""
return hashedData.let { it -> it.joinToString("") { "%02x".format(it) } }
}
fun getAuthSignature(e: String): String {
val hashedData = encryptor.hash2(e.toByteArray()) ?: return ""
return hashedData.let { it -> it.joinToString("") { "%02x".format(it) } }
}
}
@@ -1,11 +1,11 @@
package com.lizongying.mytv.api
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.Field
import retrofit2.http.FormUrlEncoded
import retrofit2.http.Headers
import retrofit2.http.POST
import retrofit2.http.Path
import retrofit2.http.Query
@@ -68,4 +68,58 @@ interface YSPBtraceService {
@Field("c_guid") c_guid: String = "",
@Field("c_vuid") c_vuid: String = "-",
): Call<Void>
@POST("kvcollect")
@Headers(
"content-type: application/json",
"referer: https://www.yangshipin.cn/",
"Cookie: guid=1; versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=123",
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
)
fun kvcollect2(
@Body request: KvcollectRequest,
): Call<Void>
@FormUrlEncoded
@POST("kvcollect")
@Headers(
"content-type: application/x-www-form-urlencoded",
"referer: https://www.yangshipin.cn/",
)
fun kvcollect3(
@Field("BossId") BossId: String = "9141",
@Field("Pwd") Pwd: String = "1137850982",
@Field("prog") prog: String = "", //
@Field("playno") playno: String = "", //
@Field("guid") guid: String = "", //
@Field("hh_ua") hh_ua: String = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
@Field("cdn") cdn: String = "waibao",
@Field("sdtfrom") sdtfrom: String = "ysp_pc_01",
@Field("prd") prd: String = "60000",
@Field("platform") platform: String = "5910204",
@Field("errcode") errcode: String = "-",
@Field("durl") durl: String = "", //
@Field("firstreport") firstreport: String = "-",
@Field("sUrl") sUrl: String = "", //
@Field("sRef") sRef: String = "-",
@Field("fplayerver") fplayerver: String = "100",
@Field("livepid") livepid: String = "",
@Field("viewid") viewid: String = "",
@Field("seq") seq: String = "",
@Field("cmd") cmd: String = "263",
@Field("login_type") login_type: String = "-",
@Field("geturltime") geturltime: String = "-",
@Field("downspeed") downspeed: String = "10",
@Field("hc_openid") hc_openid: String = "-",
@Field("open_id") open_id: String = "-",
@Field("defn") defn: String = "fhd",
@Field("fact1") fact1: String = "ysp_pc_live_b",
@Field("openid") openid: String = "-",
@Field("_dc") _dc: String = "",
@Field("live_type") live_type: String = "-",
@Field("ftime") ftime: String = "",
@Field("url") url: String = "",
@Field("rand_str") rand_str: String = "", //
@Field("signature") signature: String = "",
): Call<Void>
}
@@ -0,0 +1,19 @@
package com.lizongying.mytv.api
import com.tencent.videolite.android.datamodel.cctvjce.TVTimeShiftProgramRequest
import com.tencent.videolite.android.datamodel.cctvjce.TVTimeShiftProgramResponse
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.Headers
import retrofit2.http.POST
interface YSPJceService {
@POST("/")
@Headers(
"content-type: application/octet-stream",
"user-agent: CCTVVideo/2.9.0 (iPad; iOS 17.2; Scale/2.00)",
)
fun getProgram(
@Body body: TVTimeShiftProgramRequest
): Call<TVTimeShiftProgramResponse>
}
@@ -0,0 +1,133 @@
package com.lizongying.mytv.jce;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class CompressUtils {
private static final String TAG = "CompressUtils";
public static byte[] compressGZIP(byte[] bArr) {
GZIPOutputStream gZIPOutputStream;
Throwable th;
if (bArr != null && bArr.length != 0) {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bArr);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
gZIPOutputStream = new GZIPOutputStream(byteArrayOutputStream);
} catch (IOException unused) {
gZIPOutputStream = null;
} catch (Throwable th2) {
gZIPOutputStream = null;
th = th2;
}
try {
byte[] bArr2 = new byte[4096];
while (true) {
int read = byteArrayInputStream.read(bArr2);
if (read <= 0) {
break;
}
gZIPOutputStream.write(bArr2, 0, read);
}
gZIPOutputStream.finish();
byte[] byteArray = byteArrayOutputStream.toByteArray();
try {
byteArrayInputStream.close();
byteArrayOutputStream.close();
gZIPOutputStream.close();
} catch (IOException e2) {
System.out.println(e2);
}
return byteArray;
} catch (IOException unused2) {
try {
byteArrayInputStream.close();
byteArrayOutputStream.close();
if (gZIPOutputStream != null) {
gZIPOutputStream.close();
}
} catch (IOException e3) {
System.out.println(e3);
}
return null;
} catch (Throwable th3) {
th = th3;
try {
byteArrayInputStream.close();
byteArrayOutputStream.close();
if (gZIPOutputStream != null) {
gZIPOutputStream.close();
}
} catch (IOException e4) {
System.out.println(e4);
}
}
}
return null;
}
public static byte[] decompressGZIP(byte[] bArr) {
GZIPInputStream gZIPInputStream;
Throwable th;
if (bArr != null && bArr.length != 0) {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bArr);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
gZIPInputStream = new GZIPInputStream(byteArrayInputStream);
} catch (IOException unused) {
gZIPInputStream = null;
} catch (Throwable th2) {
gZIPInputStream = null;
th = th2;
}
try {
byte[] bArr2 = new byte[4096];
while (true) {
int read = gZIPInputStream.read(bArr2);
if (read <= 0) {
break;
}
byteArrayOutputStream.write(bArr2, 0, read);
}
byteArrayOutputStream.flush();
byte[] byteArray = byteArrayOutputStream.toByteArray();
try {
byteArrayInputStream.close();
byteArrayOutputStream.close();
gZIPInputStream.close();
} catch (IOException e2) {
System.out.println(e2);
}
return byteArray;
} catch (IOException unused2) {
try {
byteArrayInputStream.close();
byteArrayOutputStream.close();
if (gZIPInputStream != null) {
gZIPInputStream.close();
}
} catch (IOException e3) {
System.out.println(e3);
}
return null;
} catch (Throwable th3) {
th = th3;
try {
byteArrayInputStream.close();
byteArrayOutputStream.close();
if (gZIPInputStream != null) {
gZIPInputStream.close();
}
} catch (IOException e4) {
System.out.println(e4);
}
}
}
return null;
}
}
@@ -0,0 +1,45 @@
package com.lizongying.mytv.jce;
import androidx.annotation.NonNull;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
public class JceConverterFactory extends Converter.Factory {
public static JceConverterFactory create() {
return new JceConverterFactory();
}
private JceConverterFactory() {
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(
@NonNull Type type,
@NonNull Annotation[] annotations,
@NonNull Retrofit retrofit) {
if (!(type instanceof Class<?>)) {
return null;
}
return new JceResponseBodyConverter<>();
}
@Override
public Converter<?, RequestBody> requestBodyConverter(
@NonNull Type type,
@NonNull Annotation[] parameterAnnotations,
@NonNull Annotation[] methodAnnotations,
@NonNull Retrofit retrofit) {
if (!(type instanceof Class<?>)) {
return null;
}
return new JceRequestBodyConverter<>();
}
}
@@ -0,0 +1,70 @@
package com.lizongying.mytv.jce;
import androidx.annotation.NonNull;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
import com.tencent.videolite.android.datamodel.cctvjce.BusinessExtent;
import com.tencent.videolite.android.datamodel.cctvjce.BusinessHead;
import com.tencent.videolite.android.datamodel.cctvjce.QUA;
import com.tencent.videolite.android.datamodel.cctvjce.RequestCommand;
import com.tencent.videolite.android.datamodel.cctvjce.RequestHead;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import retrofit2.Converter;
public class JceRequestBodyConverter<T extends JceStruct> implements Converter<T, RequestBody> {
private static final MediaType MEDIA_TYPE = MediaType.get("application/octet-stream");
@Override
public RequestBody convert(@NonNull T value) {
BusinessHead businessHead = new BusinessHead();
RequestHead requestHead = new RequestHead();
requestHead.appId = "1200013";
requestHead.busiExtent = new BusinessExtent(1);
requestHead.cmdId = 24897;
requestHead.contentType = 0;
requestHead.guid = "093e7e5989684fd986c44f07542d8dc8";
requestHead.isSupportDolby = 0;
requestHead.oemPlatform = 0;
QUA qua = new QUA();
qua.appSubVersion = "";
qua.areaMode = 1;
qua.channelId = "50001";
qua.clientKey = "A41CD6B6-6A56-46DC-9AE0-4ECF2E9118DF";
qua.countryCode = 0;
qua.densityDpi = 0;
qua.deviceId = "5EE46760-11B1-5FE7-949A-FF232DAE1823";
qua.deviceModel = "iPad Pro (12.9 inch) 3G";
qua.deviceType = 1;
qua.extent = "";
qua.idfa = "";
qua.imei = "";
qua.langCode = 0;
qua.mac = "";
qua.markerId = 1;
qua.mobileISP = 0;
qua.networkMode = 0;
qua.omgId = "78d6ac7572afb5461e9a590f089f893d2abc0010119007";
qua.platform = 5;
qua.platformVersion = "sysver=ios17.2&device=iPad&modify_time=&lang=zh_CN";
qua.qimei = "1c0fc6ed8a53584ae722b915200014317601";
qua.screenHeight = 2360;
qua.screenWidth = 1640;
qua.serverid = "";
qua.v4ip = "";
qua.versionCode = "23399";
qua.versionName = "2.9.0.23399";
requestHead.qua = qua;
requestHead.requestId = 1;
JceOutputStream jceOutputStream = new JceOutputStream();
jceOutputStream.setServerEncoding("utf-8");
value.writeTo(jceOutputStream);
byte[] bytes = jceOutputStream.toByteArray();
RequestCommand requestCommand = new RequestCommand(requestHead, bytes, businessHead);
bytes = b.b(requestCommand, requestHead.requestId);
return RequestBody.create(MEDIA_TYPE, bytes);
}
}
@@ -0,0 +1,64 @@
package com.lizongying.mytv.jce;
import androidx.annotation.NonNull;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceStruct;
import com.tencent.videolite.android.datamodel.cctvjce.QQVideoJCECmd;
import com.tencent.videolite.android.datamodel.cctvjce.ResponseCommand;
import java.io.IOException;
import okhttp3.ResponseBody;
import retrofit2.Converter;
public class JceResponseBodyConverter<T extends JceStruct> implements Converter<ResponseBody, T> {
JceResponseBodyConverter() {
}
@Override
public T convert(@NonNull ResponseBody value) throws IOException {
return parseFrom(value.bytes());
}
public T parseFrom(byte[] aa) {
byte[] bArr;
int[] iArr = new int[1];
try {
bArr = b.a(aa, iArr);
} catch (Throwable unused) {
bArr = null;
}
ResponseCommand responseCommand = a.g(bArr, ResponseCommand.class);
if (responseCommand == null) {
return null;
}
QQVideoJCECmd convert = QQVideoJCECmd.convert(responseCommand.head.cmdId);
assert convert != null;
JceInputStream jceInputStream = new JceInputStream(responseCommand.body);
jceInputStream.setServerEncoding("UTF-8");
JceStruct instance = null;
try {
instance = (JceStruct) Class.forName("com.tencent.videolite.android.datamodel.cctvjce." + convert + "Response").newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if (instance != null) {
instance.readFrom(jceInputStream);
return (T) instance;
} else {
return null;
}
}
}
@@ -0,0 +1,160 @@
package com.lizongying.mytv.jce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
import java.lang.reflect.Field;
public class a {
/* renamed from: a reason: collision with root package name */
private static final String f33240a = "Net_Protocol";
private a() {
}
private static JceStruct a(JceStruct jceStruct, ClassLoader classLoader) {
Class<?> cls;
if (jceStruct == null) {
return null;
}
String name = jceStruct.getClass().getName();
String str = name.substring(0, name.length() - 7) + "Response";
try {
if (classLoader == null) {
cls = Class.forName(str);
} else {
cls = Class.forName(str, true, classLoader);
}
return (JceStruct) cls.newInstance();
} catch (ClassNotFoundException unused) {
return null;
} catch (IllegalAccessException unused) {
return null;
} catch (InstantiationException unused) {
return null;
}
}
private static JceStruct b(String str, ClassLoader classLoader) {
Class<?> cls;
if (str == null) {
return null;
}
String str2 = str + "Response";
try {
if (classLoader == null) {
cls = Class.forName(str2);
} else {
cls = Class.forName(str2, true, classLoader);
}
return (JceStruct) cls.newInstance();
} catch (ClassNotFoundException unused) {
return null;
} catch (IllegalAccessException unused) {
return null;
} catch (InstantiationException unused) {
return null;
}
}
public static int c(Object obj) {
Field[] declaredFields;
int i2 = 0;
if (obj == null) {
return 0;
}
for (Field field : obj.getClass().getDeclaredFields()) {
if (field != null) {
field.setAccessible(true);
if (!field.getName().equals("errCode")) {
continue;
} else if (!field.getType().getName().equals(Integer.class.getName()) && !field.getType().getName().equals("int")) {
if (field.getType().getName().equals(Long.class.getName()) || field.getType().getName().equals("long")) {
try {
return (int) field.getLong(obj);
} catch (IllegalAccessException e2) {
e2.printStackTrace();
} catch (IllegalArgumentException e3) {
e3.printStackTrace();
}
}
} else {
try {
return field.getInt(obj);
} catch (IllegalAccessException e4) {
e4.printStackTrace();
} catch (IllegalArgumentException e5) {
e5.printStackTrace();
}
}
}
}
return i2;
}
public static byte[] d(JceStruct jceStruct) {
if (jceStruct == null) {
return null;
}
JceOutputStream jceOutputStream = new JceOutputStream();
jceOutputStream.setServerEncoding("utf-8");
jceStruct.writeTo(jceOutputStream);
return jceOutputStream.toByteArray();
}
public static JceStruct e(JceStruct jceStruct, byte[] bArr, ClassLoader classLoader) {
JceStruct a2;
if (jceStruct != null && bArr != null && (a2 = a(jceStruct, classLoader)) != null) {
try {
JceInputStream jceInputStream = new JceInputStream(bArr);
jceInputStream.setServerEncoding("utf-8");
a2.readFrom(jceInputStream);
return a2;
} catch (Exception unused) {
}
}
return null;
}
public static JceStruct f(String str, byte[] bArr, ClassLoader classLoader) {
if (str != null && bArr != null) {
JceStruct b2 = b(str, classLoader);
if (b2 != null) {
try {
JceInputStream jceInputStream = new JceInputStream(bArr);
jceInputStream.setServerEncoding("utf-8");
b2.readFrom(jceInputStream);
return b2;
} catch (Exception e2) {
return null;
}
}
}
return null;
}
public static <T extends JceStruct> T g(byte[] bArr, Class<T> cls) {
T t;
if (bArr != null && bArr.length >= 4) {
try {
t = cls.newInstance();
} catch (IllegalAccessException unused) {
t = null;
} catch (InstantiationException unused) {
t = null;
}
try {
JceInputStream jceInputStream = new JceInputStream(bArr);
jceInputStream.setServerEncoding("utf-8");
if (t != null) {
t.readFrom(jceInputStream);
}
return t;
} catch (Exception unused2) {
}
}
return null;
}
}
@@ -0,0 +1,187 @@
package com.lizongying.mytv.jce;
import com.tencent.videolite.android.datamodel.cctvjce.RequestCommand;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
public class b {
/* renamed from: a reason: collision with root package name */
private static final String f33241a = "Net_UnifiedProtocol";
b() {
}
public static byte[] a(byte[] bArr, int[] iArr) {
boolean z;
if (bArr == null || bArr.length == 0) {
return null;
}
ByteBuffer wrap = ByteBuffer.wrap(bArr);
if (wrap.get() == 19 && wrap.getInt() == bArr.length) {
wrap.getShort();
if ((wrap.getShort() & 65535) != 65281) {
return null;
}
wrap.getShort();
int i2 = wrap.getShort() & 65535;
if (i2 != 0) {
iArr[0] = i2;
return null;
}
wrap.getLong();
int i3 = wrap.getInt();
if ((i3 & 2) <= 0) {
z = false;
} else if ((i3 & 16) <= 0) {
iArr[0] = -867;
return null;
} else {
z = true;
}
wrap.getInt();
wrap.getLong();
wrap.position(wrap.position() + 32);
wrap.get();
wrap.position(wrap.position() + 10);
wrap.get();
wrap.position(wrap.position() + (wrap.getShort() & 65535));
int i4 = 65535 & wrap.getShort();
wrap.position(wrap.position() + i4);
int i5 = 83 + i4 + 2;
int i6 = wrap.getInt();
int i7 = i5 + 4;
if (wrap.get(bArr.length - 1) != 3) {
iArr[0] = -869;
return null;
}
int length = (bArr.length - i7) - 1;
if (length <= 0) {
iArr[0] = -868;
return null;
}
byte[] bArr2 = new byte[length];
System.arraycopy(bArr, i7, bArr2, 0, length);
return c(bArr2, z, i6, iArr);
}
return null;
}
public static byte[] b(RequestCommand requestCommand, long j) {
byte[] d2 = a.d(requestCommand);
if (d2 == null) {
return null;
}
byte[] d3 = d(d2);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(d3.length + 50);
DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);
try {
dataOutputStream.writeByte(19);
dataOutputStream.writeInt(0);
dataOutputStream.writeShort(2);
dataOutputStream.writeShort(65281);
dataOutputStream.writeShort(requestCommand.head.cmdId);
dataOutputStream.writeShort(0);
dataOutputStream.writeLong(j);
dataOutputStream.writeInt(531);
dataOutputStream.writeInt(0);
dataOutputStream.writeLong(0);
e(dataOutputStream, requestCommand.head.guid, 32);
dataOutputStream.writeByte(0);
// VersionCode
dataOutputStream.writeInt(0);
e(dataOutputStream, null, 6);
dataOutputStream.writeByte(0);
dataOutputStream.writeShort(0);
dataOutputStream.writeShort(0);
dataOutputStream.writeInt(d3.length);
byte[] compressGZIP = CompressUtils.compressGZIP(d3);
if (compressGZIP == null) {
return null;
}
dataOutputStream.write(compressGZIP);
dataOutputStream.writeByte(3);
dataOutputStream.close();
byte[] byteArray = byteArrayOutputStream.toByteArray();
ByteBuffer wrap = ByteBuffer.wrap(byteArray);
wrap.putInt(1, byteArray.length);
return wrap.array();
} catch (IOException unused) {
return null;
}
}
private static byte[] c(byte[] bArr, boolean z, int i2, int[] iArr) {
if (bArr == null) {
iArr[0] = -871;
return null;
// } else if (z && ((bArr = CompressUtils.decompressGZIP(bArr)) == null || bArr.length != i2)) {
} else if (z && ((bArr = CompressUtils.decompressGZIP(bArr)) == null)) {
iArr[0] = -871;
return null;
} else {
ByteBuffer wrap = ByteBuffer.wrap(bArr);
int position = wrap.position() + 16;
if (wrap.get() != 38) {
iArr[0] = -869;
return null;
} else if (wrap.get(bArr.length - 1) != 40) {
iArr[0] = -869;
return null;
} else {
int length = (bArr.length - position) - 1;
if (length <= 0) {
iArr[0] = -869;
return null;
}
byte[] bArr2 = new byte[length];
System.arraycopy(bArr, position, bArr2, 0, length);
return bArr2;
}
}
}
private static byte[] d(byte[] bArr) {
int length = bArr.length + 17;
ByteBuffer allocate = ByteBuffer.allocate(length);
allocate.put((byte) 38);
allocate.putInt(length);
allocate.put((byte) 1);
allocate.position(allocate.position() + 10);
allocate.put(bArr);
allocate.put((byte) 40);
return allocate.array();
}
private static void e(OutputStream outputStream, String str, int i2) throws IOException {
byte[] bArr;
int i3;
if (i2 > 0) {
if (str != null) {
bArr = str.getBytes("UTF-8");
i3 = bArr.length;
} else {
bArr = null;
i3 = 0;
}
if (i3 >= i2) {
outputStream.write(bArr, 0, i2);
return;
}
if (i3 > 0) {
outputStream.write(bArr, 0, i3);
}
while (i3 < i2) {
outputStream.write(0);
i3++;
}
}
}
}
@@ -0,0 +1,7 @@
package com.lizongying.mytv.models
enum class ProgramType {
Y_PROTO,
Y_JCE,
F,
}
@@ -1,5 +1,6 @@
package com.lizongying.mytv
package com.lizongying.mytv.models
import com.lizongying.mytv.models.ProgramType
import java.io.Serializable
data class TV(
@@ -7,27 +8,28 @@ data class TV(
var title: String,
var alias: String = "",
var videoUrl: List<String>,
var videoIndex: Int = 0,
var channel: String = "",
var logo: Any = "",
var pid: String = "",
var sid: String = "",
var programId: String = "",
var programType: ProgramType,
var needToken: Boolean = false,
var mustToken: Boolean = false,
) : Serializable {
) : Serializable {
override fun toString(): String {
return "TV{" +
"id=" + id +
", title='" + title + '\'' +
", alias='" + alias + '\'' +
", videoUrl='" + videoUrl + '\'' +
", videoIndex='" + videoIndex + '\'' +
", channel='" + channel + '\'' +
", logo='" + logo + '\'' +
", pid='" + pid + '\'' +
", sid='" + sid + '\'' +
", programId='" + programId + '\'' +
", programType='" + programType + '\'' +
", needToken='" + needToken + '\'' +
", mustToken='" + mustToken + '\'' +
'}'
}
}
@@ -3,6 +3,7 @@ package com.lizongying.mytv.models
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.lizongying.mytv.SP
class TVListViewModel : ViewModel() {
@@ -16,10 +17,6 @@ class TVListViewModel : ViewModel() {
val itemPosition: LiveData<Int>
get() = _itemPosition
private val _itemPositionCurrent = MutableLiveData<Int>()
val itemPositionCurrent: LiveData<Int>
get() = _itemPositionCurrent
fun addTVViewModel(tvViewModel: TVViewModel) {
if (_tvListViewModel.value == null) {
_tvListViewModel.value = mutableListOf(tvViewModel)
@@ -32,23 +29,16 @@ class TVListViewModel : ViewModel() {
return _tvListViewModel.value?.get(id)
}
fun getTVViewModelCurrent(): TVViewModel? {
return _itemPositionCurrent.value?.let { _tvListViewModel.value?.get(it) }
}
fun setItemPosition(position: Int) {
_itemPosition.value = position
_itemPositionCurrent.value = position
}
fun setItemPositionCurrent(position: Int) {
_itemPositionCurrent.value = position
SP.itemPosition = position
}
fun size(): Int {
if (_tvListViewModel.value == null) {
return 0
}
return _tvListViewModel.value!!.size
}
}
@@ -1,18 +1,11 @@
package com.lizongying.mytv.models
import android.net.Uri
import android.util.Log
import androidx.annotation.OptIn
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.media3.common.MediaItem
import androidx.media3.common.util.UnstableApi
import androidx.media3.datasource.DefaultHttpDataSource
import androidx.media3.exoplayer.hls.HlsMediaSource
import com.lizongying.mytv.TV
import com.lizongying.mytv.api.FEPG
import com.lizongying.mytv.proto.Ysp.cn.yangshipin.omstv.common.proto.programModel.Program
import com.tencent.videolite.android.datamodel.cctvjce.TVProgram
import java.text.SimpleDateFormat
import java.util.TimeZone
@@ -22,31 +15,24 @@ class TVViewModel(private var tv: TV) : ViewModel() {
private var itemPosition: Int = 0
var retryTimes = 0
var tokenRetryTimes = 0
var retryMaxTimes = 8
var tokenRetryMaxTimes = 2
var programUpdateTime: Long = 0
var authYSPRetryTimes = 0
var authYSPRetryMaxTimes = 3
var tokenYSPRetryTimes = 0
var tokenYSPRetryMaxTimes = 0
var tokenFHRetryTimes = 0
var tokenFHRetryMaxTimes = 8
var needGetToken = false
private val _errInfo = MutableLiveData<String>()
val errInfo: LiveData<String>
get() = _errInfo
private val _programId = MutableLiveData<String>()
val programId: LiveData<String>
get() = _programId
private var _epg = MutableLiveData<MutableList<EPG>>()
val epg: LiveData<MutableList<EPG>>
get() = _epg
private val _id = MutableLiveData<Int>()
val id: LiveData<Int>
get() = _id
private val _title = MutableLiveData<String>()
val title: LiveData<String>
get() = _title
private val _videoUrl = MutableLiveData<List<String>>()
val videoUrl: LiveData<List<String>>
get() = _videoUrl
@@ -55,20 +41,8 @@ class TVViewModel(private var tv: TV) : ViewModel() {
val videoIndex: LiveData<Int>
get() = _videoIndex
private val _logo = MutableLiveData<Any>()
val logo: LiveData<Any>
get() = _logo
private val _pid = MutableLiveData<String>()
val pid: LiveData<String>
get() = _pid
private val _sid = MutableLiveData<String>()
val sid: LiveData<String>
get() = _sid
private val _change = MutableLiveData<Boolean>()
val change: LiveData<Boolean>
private val _change = MutableLiveData<String>()
val change: LiveData<String>
get() = _change
private val _ready = MutableLiveData<Boolean>()
@@ -82,46 +56,30 @@ class TVViewModel(private var tv: TV) : ViewModel() {
if (_videoUrl.value!!.last().contains("cctv.cn")) {
tv.videoUrl = tv.videoUrl.subList(0, tv.videoUrl.lastIndex) + listOf(url)
} else {
tv.videoUrl = tv.videoUrl + listOf(url)
tv.videoUrl += listOf(url)
}
} else {
tv.videoUrl = tv.videoUrl + listOf(url)
tv.videoUrl += listOf(url)
}
tv.videoIndex = tv.videoUrl.lastIndex
_videoUrl.value = tv.videoUrl
_videoIndex.value = tv.videoIndex
_videoIndex.value = tv.videoUrl.lastIndex
}
fun firstSource() {
if (_videoUrl.value!!.isNotEmpty()) {
setVideoIndex(0)
allReady()
} else {
Log.e(TAG, "no first")
}
}
fun changed() {
_change.value = true
fun changed(from: String) {
retryTimes = 0
authYSPRetryTimes = 0
tokenYSPRetryTimes = 0
tokenFHRetryTimes = 0
_change.value = from
}
fun allReady() {
_ready.value = true
}
fun setVideoIndex(videoIndex: Int) {
_videoIndex.value = videoIndex
}
init {
_id.value = tv.id
_title.value = tv.title
_videoUrl.value = tv.videoUrl
_videoIndex.value = tv.videoIndex
_logo.value = tv.logo
_programId.value = tv.programId
_pid.value = tv.pid
_sid.value = tv.sid
_videoIndex.value = tv.videoUrl.lastIndex
}
fun getRowPosition(): Int {
@@ -144,14 +102,14 @@ class TVViewModel(private var tv: TV) : ViewModel() {
_errInfo.value = info
}
fun update(t: TV) {
tv = t
}
fun getTV(): TV {
return tv
}
fun addYJceEPG(p: MutableList<TVProgram>) {
_epg.value = p.map { EPG(it.name, it.start_time_stamp.toInt()) }.toMutableList()
}
fun addYEPG(p: MutableList<Program>) {
_epg.value = p.map { EPG(it.name, it.st.toInt()) }.toMutableList()
}
@@ -170,27 +128,6 @@ class TVViewModel(private var tv: TV) : ViewModel() {
_epg.value = p.map { EPG(it.title, formatFTime(it.event_time)) }.toMutableList()
}
private var mHeaders: Map<String, String>? = mapOf()
fun setHeaders(headers: Map<String, String>) {
mHeaders = headers
}
/**
* (playerView?.player as ExoPlayer).setMediaSource(tvViewModel.buildSource())
*/
@OptIn(UnstableApi::class)
fun buildSource(): HlsMediaSource {
val httpDataSource = DefaultHttpDataSource.Factory()
mHeaders?.let { httpDataSource.setDefaultRequestProperties(it) }
return HlsMediaSource.Factory(httpDataSource).createMediaSource(
MediaItem.fromUri(
Uri.parse(getVideoUrlCurrent())
)
)
}
fun getVideoUrlCurrent(): String {
return _videoUrl.value!![_videoIndex.value!!]
}
@@ -1,7 +1,7 @@
package com.lizongying.mytv.requests
import com.lizongying.mytv.api.ApiClient
import com.lizongying.mytv.api.Release
import com.lizongying.mytv.api.ReleaseV2
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import retrofit2.Call
@@ -10,20 +10,23 @@ import retrofit2.Response
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
class MyRequest {
class ReleaseRequest {
private var releaseService = ApiClient().releaseService
suspend fun getRelease(): Release? {
suspend fun getRelease(): ReleaseResponse? {
return withContext(Dispatchers.IO) {
fetchRelease()
}
}
private suspend fun fetchRelease(): Release? {
private suspend fun fetchRelease(): ReleaseResponse? {
return suspendCoroutine { continuation ->
releaseService.getRelease()
.enqueue(object : Callback<Release> {
override fun onResponse(call: Call<Release>, response: Response<Release>) {
.enqueue(object : Callback<ReleaseResponse> {
override fun onResponse(
call: Call<ReleaseResponse>,
response: Response<ReleaseResponse>
) {
if (response.isSuccessful) {
continuation.resume(response.body())
} else {
@@ -31,7 +34,7 @@ class MyRequest {
}
}
override fun onFailure(call: Call<Release>, t: Throwable) {
override fun onFailure(call: Call<ReleaseResponse>, t: Throwable) {
continuation.resume(null)
}
})
@@ -39,6 +42,6 @@ class MyRequest {
}
companion object {
private const val TAG = "MyRequest"
private const val TAG = "ReleaseRequest"
}
}
@@ -0,0 +1,7 @@
package com.lizongying.mytv.requests
data class ReleaseResponse(
val version_code: Int?,
val version_name: String?,
)
@@ -0,0 +1,10 @@
package com.lizongying.mytv.requests
import retrofit2.Call
import retrofit2.http.GET
interface ReleaseService {
@GET("JELLY_BEAN_MR1/version.json")
fun getRelease(
): Call<ReleaseResponse>
}
@@ -0,0 +1,920 @@
package com.lizongying.mytv.requests
import android.os.Handler
import android.os.Looper
import android.util.Base64
import android.util.Log
import com.lizongying.mytv.Utils
import com.lizongying.mytv.Utils.getDateFormat
import com.lizongying.mytv.api.ApiClient
import com.lizongying.mytv.api.Auth
import com.lizongying.mytv.api.AuthRequest
import com.lizongying.mytv.api.FAuth
import com.lizongying.mytv.api.FAuthService
import com.lizongying.mytv.api.FEPG
import com.lizongying.mytv.api.Info
import com.lizongying.mytv.api.InfoV2
import com.lizongying.mytv.api.KvcollectRequest
import com.lizongying.mytv.api.KvcollectRequest2
import com.lizongying.mytv.api.LiveInfo
import com.lizongying.mytv.api.LiveInfoRequest
import com.lizongying.mytv.api.YSP
import com.lizongying.mytv.api.YSPApiService
import com.lizongying.mytv.api.YSPBtraceService
import com.lizongying.mytv.api.YSPJceService
import com.lizongying.mytv.api.YSPProtoService
import com.lizongying.mytv.api.YSPTokenService
import com.lizongying.mytv.models.TVList
import com.lizongying.mytv.models.TVViewModel
import com.lizongying.mytv.proto.Ysp.cn.yangshipin.oms.common.proto.pageModel
import com.lizongying.mytv.proto.Ysp.cn.yangshipin.omstv.common.proto.epgProgramModel
import com.tencent.videolite.android.datamodel.cctvjce.TVTimeShiftProgramRequest
import com.tencent.videolite.android.datamodel.cctvjce.TVTimeShiftProgramResponse
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
import kotlin.random.Random
object Request {
private const val TAG = "Request"
private var yspTokenService: YSPTokenService = ApiClient().yspTokenService
private var yspApiService: YSPApiService = ApiClient().yspApiService
private var yspBtraceService: YSPBtraceService = ApiClient().yspBtraceService
private var yspBtraceService2: YSPBtraceService = ApiClient().yspBtraceService2
private var yspBtraceService3: YSPBtraceService = ApiClient().yspBtraceService3
private var yspProtoService: YSPProtoService = ApiClient().yspProtoService
private var yspJceService: YSPJceService = ApiClient().yspJceService
private var fAuthService: FAuthService = ApiClient().fAuthService
private var openid = ""
private var token = ""
private var tokenFH = ""
private var needAuth = true
private var needToken = false
private val handler = Handler(Looper.getMainLooper())
private lateinit var btraceRunnable: BtraceRunnable
private val regex = Regex("""des_key = "([^"]+).+var des_iv = "([^"]+)""")
private val input =
"""{"mver":"1","subver":"1.2","host":"www.yangshipin.cn/#/tv/home?pid=","referer":"","canvas":"YSPANGLE(Apple,ANGLEMetalRenderer:AppleM1Pro,UnspecifiedVersion)"}""".toByteArray()
private var listener: RequestListener? = null
private var initRetryTimes = 0
private var initRetryMaxTimes = 0
fun onDestroy() {
Log.i(TAG, "onDestroy")
}
private var call: Call<LiveInfo>? = null
private var callAuth: Call<Auth>? = null
private var callInfo: Call<Info>? = null
private var callFAuth: Call<FAuth>? = null
private var callPage: Call<pageModel.Response>? = null
private var callBtracePage: Call<Void>? = null
private fun cancelCall() {
call?.cancel()
callAuth?.cancel()
callInfo?.cancel()
callFAuth?.cancel()
callPage?.cancel()
}
private fun fetchAuth(tvModel: TVViewModel, cookie: String) {
cancelCall()
val title = tvModel.getTV().title
val data = YSP.getAuthData(tvModel)
val request = AuthRequest(data)
callAuth = request.let { yspApiService.getAuth("guid=${YSP.getGuid()}; $cookie", it) }
callAuth?.enqueue(object : Callback<Auth> {
override fun onResponse(call: Call<Auth>, response: Response<Auth>) {
if (response.isSuccessful) {
val liveInfo = response.body()
if (liveInfo?.data?.token != null) {
Log.i(TAG, "token ${liveInfo.data.token}")
YSP.token = liveInfo.data.token
fetchVideo(tvModel, cookie)
} else {
Log.e(TAG, "$title token error")
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
tvModel.retryTimes++
if (tvModel.getTV().needToken) {
if (needToken && tvModel.tokenYSPRetryTimes < tvModel.tokenYSPRetryMaxTimes) {
tvModel.tokenYSPRetryTimes++
tvModel.needGetToken = true
fetchAuth(tvModel)
} else {
if (!tvModel.getTV().mustToken) {
fetchAuth(tvModel, cookie)
} else {
val err = "错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
} else {
fetchAuth(tvModel, cookie)
}
} else {
val err = "认证结果错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
} else {
Log.e(TAG, "$title auth status error")
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
tvModel.retryTimes++
if (tvModel.getTV().needToken) {
if (needToken && tvModel.tokenYSPRetryTimes < tvModel.tokenYSPRetryMaxTimes) {
tvModel.tokenYSPRetryTimes++
tvModel.needGetToken = true
fetchAuth(tvModel)
} else {
if (!tvModel.getTV().mustToken) {
fetchAuth(tvModel, cookie)
} else {
val err = "错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
} else {
fetchAuth(tvModel, cookie)
}
} else {
val err = "认证状态错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
}
override fun onFailure(call: Call<Auth>, t: Throwable) {
Log.e(TAG, "$title auth request error $t")
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
tvModel.retryTimes++
if (tvModel.getTV().needToken) {
if (needToken && tvModel.tokenYSPRetryTimes < tvModel.tokenYSPRetryMaxTimes) {
tvModel.tokenYSPRetryTimes++
tvModel.needGetToken = true
fetchAuth(tvModel)
} else {
if (!tvModel.getTV().mustToken) {
fetchAuth(tvModel, cookie)
} else {
val err = "错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
} else {
fetchAuth(tvModel, cookie)
}
} else {
val err = "认证请求错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
})
}
private fun fetchVideo(tvModel: TVViewModel, cookie: String) {
cancelCall()
if (Request::btraceRunnable.isInitialized) {
handler.removeCallbacks(btraceRunnable)
}
val title = tvModel.getTV().title
tvModel.seq = 0
val data = YSP.switch(tvModel)
val request = LiveInfoRequest(data)
call = request.let {
yspApiService.getLiveInfo(
"guid=${YSP.getGuid()}; $cookie",
YSP.token,
it
)
}
call?.enqueue(object : Callback<LiveInfo> {
override fun onResponse(call: Call<LiveInfo>, response: Response<LiveInfo>) {
if (response.isSuccessful) {
val liveInfo = response.body()
if (liveInfo?.data?.playurl != null) {
val chanll = liveInfo.data.chanll
val decodedBytes = Base64.decode(
chanll.substring(9, chanll.length - 3),
Base64.DEFAULT
)
val decodedString = String(decodedBytes)
val matchResult = regex.find(decodedString)
if (matchResult != null) {
val (key, iv) = matchResult.destructured
val keyBytes = Base64.decode(key, Base64.DEFAULT)
val ivBytes = Base64.decode(iv, Base64.DEFAULT)
val url = liveInfo.data.playurl + "&revoi=" + encryptTripleDES(
keyBytes + byteArrayOf(0, 0, 0, 0, 0, 0, 0, 0),
ivBytes
).uppercase() + liveInfo.data.extended_param
Log.d(TAG, "$title url $url")
tvModel.addVideoUrl(url)
tvModel.allReady()
tvModel.retryTimes = 0
btraceRunnable = BtraceRunnable(tvModel)
handler.post(btraceRunnable)
} else {
Log.e(TAG, "$title key error")
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
tvModel.retryTimes++
if (tvModel.getTV().needToken) {
if (needToken && tvModel.tokenYSPRetryTimes < tvModel.tokenYSPRetryMaxTimes) {
tvModel.tokenYSPRetryTimes++
tvModel.needGetToken = true
if (needAuth) {
fetchAuth(tvModel)
} else {
fetchVideo(tvModel)
}
} else {
if (!tvModel.getTV().mustToken) {
if (needAuth) {
fetchAuth(tvModel, cookie)
} else {
fetchVideo(tvModel, cookie)
}
} else {
val err = "错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
} else {
if (needAuth) {
fetchAuth(tvModel, cookie)
} else {
fetchVideo(tvModel, cookie)
}
}
} else {
val err = "结果错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
} else {
if (liveInfo?.data?.errinfo != null && liveInfo.data.errinfo == "应版权方要求,暂停提供直播信号,请点击观看其他精彩节目") {
val err = "版权错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
} else {
Log.e(TAG, "$title url error $request $liveInfo")
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
tvModel.retryTimes++
if (tvModel.getTV().needToken) {
if (needToken && tvModel.tokenYSPRetryTimes < tvModel.tokenYSPRetryMaxTimes) {
tvModel.tokenYSPRetryTimes++
tvModel.needGetToken = true
if (needAuth) {
fetchAuth(tvModel)
} else {
fetchVideo(tvModel)
}
} else {
if (!tvModel.getTV().mustToken) {
if (needAuth) {
fetchAuth(tvModel, cookie)
} else {
fetchVideo(tvModel, cookie)
}
} else {
val err = "错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
} else {
if (needAuth) {
fetchAuth(tvModel, cookie)
} else {
fetchVideo(tvModel, cookie)
}
}
} else {
val err = "其他错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
}
} else {
Log.e(TAG, "$title status error $data")
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
tvModel.retryTimes++
if (tvModel.getTV().needToken) {
if (needToken && tvModel.tokenYSPRetryTimes < tvModel.tokenYSPRetryMaxTimes) {
tvModel.tokenYSPRetryTimes++
tvModel.needGetToken = true
if (needAuth) {
fetchAuth(tvModel, cookie)
} else {
fetchVideo(tvModel, cookie)
}
} else {
if (!tvModel.getTV().mustToken) {
if (needAuth) {
fetchAuth(tvModel, cookie)
} else {
fetchVideo(tvModel, cookie)
}
} else {
val err = "错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
} else {
if (needAuth) {
fetchAuth(tvModel, cookie)
} else {
fetchVideo(tvModel, cookie)
}
}
} else {
val err = "状态错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
}
override fun onFailure(call: Call<LiveInfo>, t: Throwable) {
Log.e(TAG, "$title fetchVideo request error $t")
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
tvModel.retryTimes++
if (tvModel.getTV().needToken) {
if (needToken && tvModel.tokenYSPRetryTimes < tvModel.tokenYSPRetryMaxTimes) {
tvModel.tokenYSPRetryTimes++
tvModel.needGetToken = true
fetchVideo(tvModel)
} else {
if (!tvModel.getTV().mustToken) {
fetchVideo(tvModel, cookie)
} else {
// TODO
}
}
} else {
fetchVideo(tvModel, cookie)
}
} else {
val err = "请求错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
})
}
private fun fetchAuth(tvModel: TVViewModel) {
cancelCall()
if (tvModel.needGetToken) {
callInfo = yspTokenService.getInfo("")
callInfo?.enqueue(object : Callback<Info> {
override fun onResponse(call: Call<Info>, response: Response<Info>) {
if (response.isSuccessful && response.body()?.data?.token != null) {
token = response.body()?.data?.token!!
Log.i(TAG, "info success $token")
tvModel.needGetToken = false
tvModel.tokenYSPRetryTimes = 0
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109;yspopenid=$openid; vusession=$token"
fetchAuth(tvModel, cookie)
} else if (response.code() == 304) {
tvModel.needGetToken = false
tvModel.tokenYSPRetryTimes = 0
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109; yspopenid=$openid; vusession=$token"
fetchVideo(tvModel, cookie)
} else {
Log.e(TAG, "info status error")
if (tvModel.tokenYSPRetryTimes < tvModel.tokenYSPRetryMaxTimes) {
tvModel.tokenYSPRetryTimes++
fetchAuth(tvModel)
} else {
if (!tvModel.getTV().mustToken) {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109"
fetchAuth(tvModel, cookie)
} else {
// TODO
}
}
}
}
override fun onFailure(call: Call<Info>, t: Throwable) {
Log.e(TAG, "info request error $t")
if (tvModel.tokenYSPRetryTimes < tvModel.tokenYSPRetryMaxTimes) {
tvModel.tokenYSPRetryTimes++
fetchVideo(tvModel)
} else {
if (!tvModel.getTV().mustToken) {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109"
fetchAuth(tvModel, cookie)
} else {
// TODO
}
}
}
})
} else {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109;yspopenid=$openid; vusession=$token"
fetchAuth(tvModel, cookie)
}
}
private fun fetchVideo(tvModel: TVViewModel) {
cancelCall()
Log.d(TAG, "fetchVideo")
if (tvModel.needGetToken) {
callInfo = yspTokenService.getInfo("")
callInfo?.enqueue(object : Callback<Info> {
override fun onResponse(call: Call<Info>, response: Response<Info>) {
if (response.isSuccessful && response.body()?.data?.token != null) {
token = response.body()?.data?.token!!
Log.i(TAG, "info success $token")
tvModel.needGetToken = false
tvModel.tokenYSPRetryTimes = 0
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109; yspopenid=$openid; vusession=$token"
fetchVideo(tvModel, cookie)
} else if (response.code() == 304) {
tvModel.needGetToken = false
tvModel.tokenYSPRetryTimes = 0
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109; yspopenid=$openid; vusession=$token"
fetchVideo(tvModel, cookie)
} else {
Log.e(TAG, "info status error")
if (tvModel.tokenYSPRetryTimes < tvModel.tokenYSPRetryMaxTimes) {
tvModel.tokenYSPRetryTimes++
fetchVideo(tvModel)
} else {
if (!tvModel.getTV().mustToken) {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109"
fetchVideo(tvModel, cookie)
} else {
// TODO
}
}
}
}
override fun onFailure(call: Call<Info>, t: Throwable) {
Log.e(TAG, "info request error $t")
if (tvModel.tokenYSPRetryTimes < tvModel.tokenYSPRetryMaxTimes) {
tvModel.tokenYSPRetryTimes++
fetchVideo(tvModel)
} else {
if (!tvModel.getTV().mustToken) {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109"
fetchVideo(tvModel, cookie)
} else {
// TODO
}
}
}
})
} else {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109; yspopenid=$openid; vusession=$token"
fetchVideo(tvModel, cookie)
}
}
private fun fetchFAuth(tvModel: TVViewModel) {
cancelCall()
val title = tvModel.getTV().title
var qa = "HD"
if (tokenFH != "") {
qa = "FHD"
}
callFAuth = fAuthService.getAuth(tokenFH, tvModel.getTV().pid, qa)
callFAuth?.enqueue(object : Callback<FAuth> {
override fun onResponse(call: Call<FAuth>, response: Response<FAuth>) {
if (response.isSuccessful && response.body()?.data?.live_url != null) {
val url = response.body()?.data?.live_url!!
// Log.d(TAG, "$title url $url")
tvModel.addVideoUrl(url)
tvModel.allReady()
tvModel.tokenFHRetryTimes = 0
} else {
Log.e(TAG, "auth status error ${response.code()}")
if (tvModel.tokenFHRetryTimes < tvModel.tokenFHRetryMaxTimes) {
tvModel.tokenFHRetryTimes++
fetchFAuth(tvModel)
} else {
val err = "状态错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
}
override fun onFailure(call: Call<FAuth>, t: Throwable) {
Log.e(TAG, "auth request error $t")
if (tvModel.tokenFHRetryTimes < tvModel.tokenFHRetryMaxTimes) {
tvModel.tokenFHRetryTimes++
fetchFAuth(tvModel)
} else {
val err = "请求错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
})
}
fun fetchData(tvModel: TVViewModel) {
if (tvModel.getTV().channel == "港澳台") {
fetchFAuth(tvModel)
return
}
if (needToken && tvModel.getTV().needToken) {
if (token == "") {
tvModel.needGetToken = true
}
if (needAuth) {
fetchAuth(tvModel)
} else {
fetchVideo(tvModel)
}
} else {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; updateProtocol=1; deviceModel=120"
if (needAuth) {
fetchAuth(tvModel, cookie)
} else {
fetchVideo(tvModel, cookie)
}
}
}
private fun fetchInfoV2() {
yspTokenService.getInfoV2()
.enqueue(object : Callback<InfoV2> {
override fun onResponse(call: Call<InfoV2>, response: Response<InfoV2>) {
if (response.isSuccessful) {
val o = response.body()?.o
val t = response.body()?.t
val f = response.body()?.f
val e = response.body()?.e
val c = response.body()?.c
if (!o.isNullOrEmpty()) {
openid = o
}
if (!t.isNullOrEmpty()) {
token = t
Log.i(TAG, "token success $token")
}
if (!f.isNullOrEmpty()) {
tokenFH = f
Log.i(TAG, "tokenFH success $tokenFH")
}
if (c != null) {
Utils.setBetween(c * 1000L)
Log.i(TAG, "current time $c")
}
listener?.onRequestFinished(null)
} else {
Log.e(TAG, "token status error")
if (initRetryTimes < initRetryMaxTimes) {
initRetryTimes++
fetchInfoV2()
} else {
listener?.onRequestFinished("状态错误")
}
}
}
override fun onFailure(call: Call<InfoV2>, t: Throwable) {
Log.e(TAG, "token request error $t")
if (initRetryTimes < initRetryMaxTimes) {
initRetryTimes++
fetchInfoV2()
} else {
listener?.onRequestFinished("网络错误")
}
}
})
}
class BtraceRunnable(private val tvModel: TVViewModel) : Runnable {
override fun run() {
fetchBtrace3(tvModel)
}
}
fun fetchBtrace(tvModel: TVViewModel) {
callBtracePage?.cancel()
val title = tvModel.getTV().title
val guid = YSP.getGuid()
val pid = tvModel.getTV().pid
val sid = tvModel.getTV().sid
callBtracePage = yspBtraceService.kvcollect(
c_timestamp = YSP.generateGuid(),
guid = guid,
c_guid = guid,
prog = sid,
viewid = sid,
fpid = pid,
livepid = pid,
sUrl = "https://www.yangshipin.cn/#/tv/home?pid=$pid",
playno = YSP.getRand(),
ftime = getDateFormat("yyyy-MM-dd HH:mm:ss"),
seq = tvModel.seq.toString(),
)
callBtracePage?.enqueue(object : Callback<Void> {
override fun onResponse(call: Call<Void>, response: Response<Void>) {
if (response.isSuccessful) {
Log.d(TAG, "$title kvcollect success")
} else {
Log.e(TAG, "$title kvcollect status error")
}
handler.postDelayed(btraceRunnable, 60 * 1000)
}
override fun onFailure(call: Call<Void>, t: Throwable) {
Log.e(TAG, "$title kvcollect request error")
handler.postDelayed(btraceRunnable, 60 * 1000)
}
})
tvModel.seq++
}
fun fetchBtrace2(tvModel: TVViewModel) {
callBtracePage?.cancel()
val title = tvModel.getTV().title
val guid = YSP.getGuid()
val pid = tvModel.getTV().pid
val sid = tvModel.getTV().sid
val randomNumber = Random.nextDouble()
val url = tvModel.getTV().videoUrl.first()
val r = KvcollectRequest(
guid = guid,
prog = sid,
viewid = sid,
livepid = pid,
sUrl = "https://www.yangshipin.cn/#/tv/home?pid=$pid",
playno = YSP.getRand(),
rand_str = YSP.getRand(),
ftime = getDateFormat("yyyy-MM-dd HH:mm:ss"),
seq = tvModel.seq,
durl = url,
url = url,
_dc = randomNumber,
)
val e =
"BossId=${r.BossId}&Pwd=${r.Pwd}&_dc=${r._dc}&cdn=${r.cdn}&cmd=${r.cmd}&defn=${r.defn}&downspeed=${r.downspeed}&durl=${r.durl}&errcode=${r.errcode}&fact1=${r.fact1}&firstreport=${r.firstreport}&fplayerver=${r.fplayerver}&ftime=${r.ftime}&geturltime=6&guid=${r.guid}&hc_openid=${r.hc_openid}&hh_ua=${r.hh_ua}&live_type=${r.live_type}&livepid=${r.livepid}&login_type=${r.login_type}&open_id=&openid=${r.openid}&platform=${r.platform}&playno=${r.playno}&prd=${r.prd}&prog=${r.prog}&rand_str=${r.rand_str}&sRef=${r.sRef}&sUrl=${r.sUrl}&sdtfrom=${r.sdtfrom}&seq=${r.seq}&url=${r.url}&viewid=${r.viewid}"
r.signature = YSP.getAuthSignature(e)
callBtracePage = yspBtraceService2.kvcollect2(r)
callBtracePage?.enqueue(object : Callback<Void> {
override fun onResponse(call: Call<Void>, response: Response<Void>) {
if (response.isSuccessful) {
Log.d(TAG, "$title kvcollect success")
} else {
Log.e(TAG, "$title kvcollect status error")
}
handler.postDelayed(btraceRunnable, 60 * 1000)
}
override fun onFailure(call: Call<Void>, t: Throwable) {
Log.e(TAG, "$title kvcollect request error")
handler.postDelayed(btraceRunnable, 60 * 1000)
}
})
tvModel.seq++
}
fun fetchBtrace3(tvModel: TVViewModel) {
callBtracePage?.cancel()
val title = tvModel.getTV().title
val guid = YSP.getGuid()
val pid = tvModel.getTV().pid
val sid = tvModel.getTV().sid
val randomNumber = Random.nextDouble()
val url = tvModel.getTV().videoUrl.first()
val r = KvcollectRequest2(
guid = guid,
prog = sid,
viewid = sid,
livepid = pid,
sUrl = "https://www.yangshipin.cn/#/tv/home?pid=$pid",
playno = YSP.getRand(),
rand_str = YSP.getRand(),
ftime = getDateFormat("yyyy-MM-dd HH:mm:ss"),
seq = tvModel.seq,
durl = url,
url = url,
_dc = randomNumber,
)
val e =
"BossId=${r.BossId}&Pwd=${r.Pwd}&_dc=${r._dc}&cdn=${r.cdn}&cmd=${r.cmd}&defn=${r.defn}&downspeed=${r.downspeed}&durl=${r.durl}&errcode=${r.errcode}&fact1=${r.fact1}&firstreport=${r.firstreport}&fplayerver=${r.fplayerver}&ftime=${r.ftime}&geturltime=${r.geturltime}&guid=${r.guid}&hc_openid=${r.hc_openid}&hh_ua=${r.hh_ua}&live_type=${r.live_type}&livepid=${r.livepid}&login_type=${r.login_type}&open_id=${r.open_id}&openid=${r.openid}&platform=${r.platform}&playno=${r.playno}&prd=${r.prd}&prog=${r.prog}&rand_str=${r.rand_str}&sRef=${r.sRef}&sUrl=${r.sUrl}&sdtfrom=${r.sdtfrom}&seq=${r.seq}&url=${r.url}&viewid=${r.viewid}"
r.signature = YSP.getAuthSignature(e)
callBtracePage = yspBtraceService3.kvcollect3(
guid = r.guid,
prog = r.prog,
viewid = r.viewid,
livepid = r.livepid,
sUrl = r.sUrl,
playno = r.playno,
rand_str = r.rand_str,
ftime = r.ftime,
seq = "${r.seq}",
durl = r.durl,
url = r.url,
_dc = "${r._dc}",
signature = r.signature
)
callBtracePage?.enqueue(object : Callback<Void> {
override fun onResponse(call: Call<Void>, response: Response<Void>) {
if (response.isSuccessful) {
Log.d(TAG, "$title kvcollect success")
} else {
Log.e(TAG, "$title kvcollect status error")
}
handler.postDelayed(btraceRunnable, 60 * 1000)
}
override fun onFailure(call: Call<Void>, t: Throwable) {
Log.e(TAG, "$title kvcollect request error")
handler.postDelayed(btraceRunnable, 60 * 1000)
}
})
tvModel.seq++
}
fun fetchPage() {
callPage = yspProtoService.getPage()
callPage?.enqueue(object : Callback<pageModel.Response> {
override fun onResponse(
call: Call<pageModel.Response>,
response: Response<pageModel.Response>
) {
if (response.isSuccessful) {
val body = response.body()
if (body?.data?.feedModuleListCount == 1) {
for (item in body.data?.feedModuleListList!![0]?.dataTvChannelListList!!) {
Log.d(
TAG,
"${item.channelName},${item.pid},${item.streamId}"
)
for ((_, v) in TVList.list) {
for (v2 in v) {
if (v2.title == item.channelName || v2.alias == item.channelName) {
v2.pid = item.pid
v2.sid = item.streamId
}
}
}
}
}
}
}
override fun onFailure(call: Call<pageModel.Response>, t: Throwable) {
Log.e(TAG, "Page request failed", t)
}
})
}
fun fetchYJceEPG(tvViewModel: TVViewModel) {
val title = tvViewModel.getTV().title
yspJceService.getProgram(TVTimeShiftProgramRequest(tvViewModel.getTV().pid))
.enqueue(object : Callback<TVTimeShiftProgramResponse> {
override fun onResponse(
call: Call<TVTimeShiftProgramResponse>,
response: Response<TVTimeShiftProgramResponse>
) {
if (response.isSuccessful) {
val program = response.body()
if (program != null) {
tvViewModel.addYJceEPG(program.programs)
Log.d(TAG, "$title program ${program.programs.size}")
}
} else {
Log.w(TAG, "$title program error")
}
}
override fun onFailure(call: Call<TVTimeShiftProgramResponse>, t: Throwable) {
Log.e(TAG, "$title program request failed $t")
}
})
}
fun fetchYProtoEPG(tvViewModel: TVViewModel) {
val title = tvViewModel.getTV().title
yspProtoService.getProgram(tvViewModel.getTV().pid, getDateFormat("yyyyMMdd"))
.enqueue(object : Callback<epgProgramModel.Response> {
override fun onResponse(
call: Call<epgProgramModel.Response>,
response: Response<epgProgramModel.Response>
) {
if (response.isSuccessful) {
val program = response.body()
if (program != null) {
tvViewModel.addYEPG(program.dataListList)
Log.d(TAG, "$title program ${program.dataListList.size}")
}
} else {
Log.w(TAG, "$title program error")
}
}
override fun onFailure(call: Call<epgProgramModel.Response>, t: Throwable) {
Log.e(TAG, "$title program request failed $t")
}
})
}
fun fetchFEPG(tvViewModel: TVViewModel) {
val title = tvViewModel.getTV().title
fAuthService.getEPG(tvViewModel.getTV().pid, getDateFormat("yyyyMMdd"))
.enqueue(object : Callback<List<FEPG>> {
override fun onResponse(
call: Call<List<FEPG>>,
response: Response<List<FEPG>>
) {
if (response.isSuccessful) {
val program = response.body()
if (program != null) {
tvViewModel.addFEPG(program)
Log.d(TAG, "$title program ${program.size}")
}
} else {
Log.w(TAG, "$title program error")
}
}
override fun onFailure(call: Call<List<FEPG>>, t: Throwable) {
Log.e(TAG, "$title program request failed $t")
}
})
}
private fun encryptTripleDES(key: ByteArray, iv: ByteArray): String {
return try {
val keySpec = SecretKeySpec(key, "DESede")
val ivSpec = IvParameterSpec(iv)
val cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec)
return cipher.doFinal(input).let { it -> it.joinToString("") { "%02x".format(it) } }
} catch (e: Exception) {
e.printStackTrace()
""
}
}
interface RequestListener {
fun onRequestFinished(message: String?)
}
fun setRequestListener(listener: RequestListener) {
Request.listener = listener
}
}
@@ -0,0 +1,72 @@
package com.qq.taf.jce;
import java.nio.ByteBuffer;
public class HexUtil {
private static final char[] digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
public static final byte[] emptybytes = new byte[0];
public static String byte2HexStr(byte b2) {
char[] cArr = digits;
return new String(new char[]{cArr[((byte) (b2 >>> 4)) & 15], cArr[b2 & 15]});
}
public static String bytes2HexStr(ByteBuffer byteBuffer) {
ByteBuffer duplicate = byteBuffer.duplicate();
duplicate.flip();
byte[] bArr = new byte[duplicate.limit()];
duplicate.get(bArr);
return bytes2HexStr(bArr);
}
public static byte char2Byte(char c2) {
int i2;
if (c2 < '0' || c2 > '9') {
char c3 = 'a';
if (c2 < 'a' || c2 > 'f') {
c3 = 'A';
if (c2 < 'A' || c2 > 'F') {
return (byte) 0;
}
}
i2 = (c2 - c3) + 10;
} else {
i2 = c2 - '0';
}
return (byte) i2;
}
public static byte hexStr2Byte(String str) {
if (str == null || str.length() != 1) {
return (byte) 0;
}
return char2Byte(str.charAt(0));
}
public static byte[] hexStr2Bytes(String str) {
if (str != null && !str.equals("")) {
int length = str.length() / 2;
byte[] bArr = new byte[length];
for (int i2 = 0; i2 < length; i2++) {
int i3 = i2 * 2;
bArr[i2] = (byte) ((char2Byte(str.charAt(i3)) * 16) + char2Byte(str.charAt(i3 + 1)));
}
return bArr;
}
return emptybytes;
}
public static String bytes2HexStr(byte[] bArr) {
if (bArr == null || bArr.length == 0) {
return null;
}
char[] cArr = new char[bArr.length * 2];
for (int i2 = 0; i2 < bArr.length; i2++) {
byte b2 = bArr[i2];
int i3 = i2 * 2;
char[] cArr2 = digits;
cArr[i3 + 1] = cArr2[b2 & 15];
cArr[i3 + 0] = cArr2[((byte) (b2 >>> 4)) & 15];
}
return new String(cArr);
}
}
@@ -0,0 +1,7 @@
package com.qq.taf.jce;
public class JceDecodeException extends RuntimeException {
public JceDecodeException(String str) {
super(str);
}
}
@@ -0,0 +1,7 @@
package com.qq.taf.jce;
public class JceEncodeException extends RuntimeException {
public JceEncodeException(String str) {
super(str);
}
}
@@ -0,0 +1,896 @@
package com.qq.taf.jce;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public final class JceInputStream {
private ByteBuffer bs;
protected String sServerEncoding = "GBK";
public static class HeadData {
public int tag;
public byte type;
public void clear() {
this.type = (byte) 0;
this.tag = 0;
}
}
public JceInputStream() {
}
private int peakHead(HeadData headData) {
return readHead(headData, this.bs.duplicate());
}
private <T> T[] readArrayImpl(T t, int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return null;
}
HeadData headData = new HeadData();
readHead(headData);
if (headData.type == 9) {
int read = read(0, 0, true);
if (read >= 0) {
T[] tArr = (T[]) ((Object[]) Array.newInstance(t.getClass(), read));
for (int i3 = 0; i3 < read; i3++) {
tArr[i3] = (T) read( t, 0, true);
}
return tArr;
}
throw new JceDecodeException("size invalid: " + read);
}
throw new JceDecodeException("type mismatch.");
}
public static int readHead(HeadData headData, ByteBuffer byteBuffer) {
byte b2 = byteBuffer.get();
headData.type = (byte) (b2 & 15);
int i2 = (b2 & 240) >> 4;
headData.tag = i2;
if (i2 == 15) {
headData.tag = byteBuffer.get() & 255;
return 2;
}
return 1;
}
private void skip(int i2) {
ByteBuffer byteBuffer = this.bs;
byteBuffer.position(byteBuffer.position() + i2);
}
private void skipField() {
HeadData headData = new HeadData();
readHead(headData);
skipField(headData.type);
}
public JceStruct directRead(JceStruct jceStruct, int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return null;
}
try {
JceStruct newInit = jceStruct.newInit();
HeadData headData = new HeadData();
readHead(headData);
if (headData.type == 10) {
newInit.readFrom(this);
skipToStructEnd();
return newInit;
}
throw new JceDecodeException("type mismatch.");
} catch (Exception e2) {
throw new JceDecodeException(e2.getMessage());
}
}
public ByteBuffer getBs() {
return this.bs;
}
public boolean read(boolean z, int i2, boolean z2) {
return read((byte) 0, i2, z2) != 0;
}
public <T> T[] readArray(T[] tArr, int i2, boolean z) {
if (tArr != null && tArr.length != 0) {
return (T[]) readArrayImpl(tArr[0], i2, z);
}
throw new JceDecodeException("unable to get type of key and value.");
}
public String readByteString(String str, int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return str;
}
HeadData headData = new HeadData();
readHead(headData);
byte b2 = headData.type;
if (b2 == 6) {
int i3 = this.bs.get();
if (i3 < 0) {
i3 += 256;
}
byte[] bArr = new byte[i3];
this.bs.get(bArr);
return HexUtil.bytes2HexStr(bArr);
} else if (b2 == 7) {
int i4 = this.bs.getInt();
if (i4 <= 104857600 && i4 >= 0 && i4 <= this.bs.capacity()) {
byte[] bArr2 = new byte[i4];
this.bs.get(bArr2);
return HexUtil.bytes2HexStr(bArr2);
}
throw new JceDecodeException("String too long: " + i4);
} else {
throw new JceDecodeException("type mismatch.");
}
}
public List readList(int i2, boolean z) {
ArrayList arrayList = new ArrayList();
if (skipToTag(i2)) {
HeadData headData = new HeadData();
readHead(headData);
if (headData.type == 9) {
int read = read(0, 0, true);
if (read < 0) {
throw new JceDecodeException("size invalid: " + read);
}
for (int i3 = 0; i3 < read; i3++) {
HeadData headData2 = new HeadData();
readHead(headData2);
switch (headData2.type) {
case 0:
skip(1);
break;
case 1:
skip(2);
break;
case 2:
skip(4);
break;
case 3:
skip(8);
break;
case 4:
skip(4);
break;
case 5:
skip(8);
break;
case 6:
int i4 = this.bs.get();
if (i4 < 0) {
i4 += 256;
}
skip(i4);
break;
case 7:
skip(this.bs.getInt());
break;
case 8:
case 9:
break;
case 10:
try {
JceStruct jceStruct = (JceStruct) Class.forName(JceStruct.class.getName()).getConstructor(new Class[0]).newInstance(new Object[0]);
jceStruct.readFrom(this);
skipToStructEnd();
arrayList.add(jceStruct);
break;
} catch (Exception e2) {
e2.printStackTrace();
throw new JceDecodeException("type mismatch." + e2);
}
case 11:
default:
throw new JceDecodeException("type mismatch.");
case 12:
arrayList.add(Integer.valueOf(0));
break;
}
}
} else {
throw new JceDecodeException("type mismatch.");
}
} else if (z) {
throw new JceDecodeException("require field not exist.");
}
return arrayList;
}
public <K, V> HashMap<K, V> readMap(Map<K, V> map, int i2, boolean z) {
return (HashMap) readMap(new HashMap(), map, i2, z);
}
public String readString(int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return null;
}
HeadData headData = new HeadData();
readHead(headData);
byte b2 = headData.type;
if (b2 == 6) {
int i3 = this.bs.get();
if (i3 < 0) {
i3 += 256;
}
byte[] bArr = new byte[i3];
this.bs.get(bArr);
try {
return new String(bArr, this.sServerEncoding);
} catch (UnsupportedEncodingException unused) {
return new String(bArr);
}
} else if (b2 == 7) {
int i4 = this.bs.getInt();
if (i4 <= 104857600 && i4 >= 0 && i4 <= this.bs.capacity()) {
byte[] bArr2 = new byte[i4];
this.bs.get(bArr2);
try {
return new String(bArr2, this.sServerEncoding);
} catch (UnsupportedEncodingException unused2) {
return new String(bArr2);
}
}
throw new JceDecodeException("String too long: " + i4);
} else {
throw new JceDecodeException("type mismatch.");
}
}
public Map<String, String> readStringMap(int i2, boolean z) {
HashMap hashMap = new HashMap();
if (skipToTag(i2)) {
HeadData headData = new HeadData();
readHead(headData);
if (headData.type == 8) {
int read = read(0, 0, true);
if (read < 0) {
throw new JceDecodeException("size invalid: " + read);
}
for (int i3 = 0; i3 < read; i3++) {
hashMap.put(readString(0, true), readString(1, true));
}
} else {
throw new JceDecodeException("type mismatch.");
}
} else if (z) {
throw new JceDecodeException("require field not exist.");
}
return hashMap;
}
public int setServerEncoding(String str) {
this.sServerEncoding = str;
return 0;
}
public void skipToStructEnd() {
HeadData headData = new HeadData();
do {
readHead(headData);
skipField(headData.type);
} while (headData.type != 11);
}
public boolean skipToTag(int i2) {
try {
HeadData headData = new HeadData();
while (true) {
int peakHead = peakHead(headData);
if (i2 <= headData.tag || headData.type == 11) {
break;
}
skip(peakHead);
skipField(headData.type);
}
if (headData.type == 11) {
return false;
}
return i2 == headData.tag;
} catch (JceDecodeException | BufferUnderflowException unused) {
return false;
}
}
public void warp(byte[] bArr) {
wrap(bArr);
}
public void wrap(byte[] bArr) {
this.bs = ByteBuffer.wrap(bArr);
}
private <K, V> Map<K, V> readMap(Map<K, V> map, Map<K, V> map2, int i2, boolean z) {
if (map2 != null && !map2.isEmpty()) {
Map.Entry<K, V> next = map2.entrySet().iterator().next();
K key = next.getKey();
V value = next.getValue();
if (skipToTag(i2)) {
HeadData headData = new HeadData();
readHead(headData);
if (headData.type == 8) {
int read = read(0, 0, true);
if (read < 0) {
throw new JceDecodeException("size invalid: " + read);
}
for (int i3 = 0; i3 < read; i3++) {
map.put((K)read( key, 0, true), (V)read(value, 1, true));
}
} else {
throw new JceDecodeException("type mismatch.");
}
} else if (z) {
throw new JceDecodeException("require field not exist.");
}
return map;
}
return new HashMap();
}
public byte read(byte b2, int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return b2;
}
HeadData headData = new HeadData();
readHead(headData);
byte b3 = headData.type;
if (b3 != 0) {
if (b3 == 12) {
return (byte) 0;
}
throw new JceDecodeException("type mismatch.");
}
return this.bs.get();
}
public JceInputStream(ByteBuffer byteBuffer) {
this.bs = byteBuffer;
}
private void skipField(byte b2) {
int i2 = 0;
switch (b2) {
case 0:
skip(1);
return;
case 1:
skip(2);
return;
case 2:
skip(4);
return;
case 3:
skip(8);
return;
case 4:
skip(4);
return;
case 5:
skip(8);
return;
case 6:
int i3 = this.bs.get();
if (i3 < 0) {
i3 += 256;
}
skip(i3);
return;
case 7:
skip(this.bs.getInt());
return;
case 8:
int read = read(0, 0, true);
while (i2 < read * 2) {
skipField();
i2++;
}
return;
case 9:
int read2 = read(0, 0, true);
while (i2 < read2) {
skipField();
i2++;
}
return;
case 10:
skipToStructEnd();
return;
case 11:
case 12:
return;
case 13:
HeadData headData = new HeadData();
readHead(headData);
if (headData.type == 0) {
skip(read(0, 0, true));
return;
}
throw new JceDecodeException("skipField with invalid type, type value: " + ((int) b2) + ", " + ((int) headData.type));
default:
throw new JceDecodeException("invalid type.");
}
}
public <T> List<T> readArray(List<T> list, int i2, boolean z) {
if (list != null && !list.isEmpty()) {
Object[] readArrayImpl = readArrayImpl(list.get(0), i2, z);
if (readArrayImpl == null) {
return null;
}
ArrayList arrayList = new ArrayList();
for (Object obj : readArrayImpl) {
arrayList.add(obj);
}
return arrayList;
}
return new ArrayList();
}
public void readHead(HeadData headData) {
readHead(headData, this.bs);
}
public JceInputStream(byte[] bArr) {
this.bs = ByteBuffer.wrap(bArr);
}
public JceInputStream(byte[] bArr, int i2) {
ByteBuffer wrap = ByteBuffer.wrap(bArr);
this.bs = wrap;
wrap.position(i2);
}
public short read(short s, int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return s;
}
HeadData headData = new HeadData();
readHead(headData);
byte b2 = headData.type;
if (b2 != 0) {
if (b2 != 1) {
if (b2 == 12) {
return (short) 0;
}
throw new JceDecodeException("type mismatch.");
}
return this.bs.getShort();
}
return this.bs.get();
}
public int read(int i2, int i3, boolean z) {
if (!skipToTag(i3)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return i2;
}
HeadData headData = new HeadData();
readHead(headData);
byte b2 = headData.type;
if (b2 != 0) {
if (b2 != 1) {
if (b2 != 2) {
if (b2 == 12) {
return 0;
}
throw new JceDecodeException("type mismatch.");
}
return this.bs.getInt();
}
return this.bs.getShort();
}
return this.bs.get();
}
public long read(long j, int i2, boolean z) {
int i3;
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return j;
}
HeadData headData = new HeadData();
readHead(headData);
byte b2 = headData.type;
if (b2 == 0) {
i3 = this.bs.get();
} else if (b2 == 1) {
i3 = this.bs.getShort();
} else if (b2 != 2) {
if (b2 != 3) {
if (b2 == 12) {
return 0L;
}
throw new JceDecodeException("type mismatch.");
}
return this.bs.getLong();
} else {
i3 = this.bs.getInt();
}
return i3;
}
public float read(float f2, int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return f2;
}
HeadData headData = new HeadData();
readHead(headData);
byte b2 = headData.type;
if (b2 != 4) {
if (b2 == 12) {
return 0.0f;
}
throw new JceDecodeException("type mismatch.");
}
return this.bs.getFloat();
}
public double read(double d2, int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return d2;
}
HeadData headData = new HeadData();
readHead(headData);
byte b2 = headData.type;
if (b2 != 4) {
if (b2 != 5) {
if (b2 == 12) {
return 0.0d;
}
throw new JceDecodeException("type mismatch.");
}
return this.bs.getDouble();
}
return this.bs.getFloat();
}
public String read(String str, int i2, boolean z) {
String str2;
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return str;
}
HeadData headData = new HeadData();
readHead(headData);
byte b2 = headData.type;
if (b2 == 6) {
int i3 = this.bs.get();
if (i3 < 0) {
i3 += 256;
}
byte[] bArr = new byte[i3];
this.bs.get(bArr);
try {
str2 = new String(bArr, this.sServerEncoding);
} catch (UnsupportedEncodingException unused) {
str2 = new String(bArr);
}
} else if (b2 == 7) {
int i4 = this.bs.getInt();
if (i4 <= 104857600 && i4 >= 0 && i4 <= this.bs.capacity()) {
byte[] bArr2 = new byte[i4];
this.bs.get(bArr2);
try {
str2 = new String(bArr2, this.sServerEncoding);
} catch (UnsupportedEncodingException unused2) {
str2 = new String(bArr2);
}
} else {
throw new JceDecodeException("String too long: " + i4);
}
} else {
throw new JceDecodeException("type mismatch.");
}
return str2;
}
public String[] read(String[] strArr, int i2, boolean z) {
return (String[]) readArray(strArr, i2, z);
}
public boolean[] read(boolean[] zArr, int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return null;
}
HeadData headData = new HeadData();
readHead(headData);
if (headData.type == 9) {
int read = read(0, 0, true);
if (read >= 0) {
boolean[] zArr2 = new boolean[read];
for (int i3 = 0; i3 < read; i3++) {
zArr2[i3] = read(zArr2[0], 0, true);
}
return zArr2;
}
throw new JceDecodeException("size invalid: " + read);
}
throw new JceDecodeException("type mismatch.");
}
public byte[] read(byte[] bArr, int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return null;
}
HeadData headData = new HeadData();
readHead(headData);
byte b2 = headData.type;
if (b2 == 9) {
int read = read(0, 0, true);
if (read >= 0 && read <= this.bs.capacity()) {
byte[] bArr2 = new byte[read];
for (int i3 = 0; i3 < read; i3++) {
bArr2[i3] = read(bArr2[0], 0, true);
}
return bArr2;
}
throw new JceDecodeException("size invalid: " + read);
} else if (b2 == 13) {
HeadData headData2 = new HeadData();
readHead(headData2);
if (headData2.type == 0) {
int read2 = read(0, 0, true);
if (read2 >= 0 && read2 <= this.bs.capacity()) {
byte[] bArr3 = new byte[read2];
this.bs.get(bArr3);
return bArr3;
}
throw new JceDecodeException("invalid size, tag: " + i2 + ", type: " + ((int) headData.type) + ", " + ((int) headData2.type) + ", size: " + read2);
}
throw new JceDecodeException("type mismatch, tag: " + i2 + ", type: " + ((int) headData.type) + ", " + ((int) headData2.type));
} else {
throw new JceDecodeException("type mismatch.");
}
}
public short[] read(short[] sArr, int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return null;
}
HeadData headData = new HeadData();
readHead(headData);
if (headData.type == 9) {
int read = read(0, 0, true);
if (read >= 0) {
short[] sArr2 = new short[read];
for (int i3 = 0; i3 < read; i3++) {
sArr2[i3] = read(sArr2[0], 0, true);
}
return sArr2;
}
throw new JceDecodeException("size invalid: " + read);
}
throw new JceDecodeException("type mismatch.");
}
public int[] read(int[] iArr, int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return null;
}
HeadData headData = new HeadData();
readHead(headData);
if (headData.type == 9) {
int read = read(0, 0, true);
if (read >= 0) {
int[] iArr2 = new int[read];
for (int i3 = 0; i3 < read; i3++) {
iArr2[i3] = read(iArr2[0], 0, true);
}
return iArr2;
}
throw new JceDecodeException("size invalid: " + read);
}
throw new JceDecodeException("type mismatch.");
}
public long[] read(long[] jArr, int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return null;
}
HeadData headData = new HeadData();
readHead(headData);
if (headData.type == 9) {
int read = read(0, 0, true);
if (read >= 0) {
long[] jArr2 = new long[read];
for (int i3 = 0; i3 < read; i3++) {
jArr2[i3] = read(jArr2[0], 0, true);
}
return jArr2;
}
throw new JceDecodeException("size invalid: " + read);
}
throw new JceDecodeException("type mismatch.");
}
public float[] read(float[] fArr, int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return null;
}
HeadData headData = new HeadData();
readHead(headData);
if (headData.type == 9) {
int read = read(0, 0, true);
if (read >= 0) {
float[] fArr2 = new float[read];
for (int i3 = 0; i3 < read; i3++) {
fArr2[i3] = read(fArr2[0], 0, true);
}
return fArr2;
}
throw new JceDecodeException("size invalid: " + read);
}
throw new JceDecodeException("type mismatch.");
}
public double[] read(double[] dArr, int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return null;
}
HeadData headData = new HeadData();
readHead(headData);
if (headData.type == 9) {
int read = read(0, 0, true);
if (read >= 0) {
double[] dArr2 = new double[read];
for (int i3 = 0; i3 < read; i3++) {
dArr2[i3] = read(dArr2[0], 0, true);
}
return dArr2;
}
throw new JceDecodeException("size invalid: " + read);
}
throw new JceDecodeException("type mismatch.");
}
public JceStruct read(JceStruct jceStruct, int i2, boolean z) {
if (!skipToTag(i2)) {
if (z) {
throw new JceDecodeException("require field not exist.");
}
return null;
}
try {
JceStruct jceStruct2 = (JceStruct) jceStruct.getClass().newInstance();
HeadData headData = new HeadData();
readHead(headData);
if (headData.type == 10) {
jceStruct2.readFrom(this);
skipToStructEnd();
return jceStruct2;
}
throw new JceDecodeException("type mismatch.");
} catch (Exception e2) {
throw new JceDecodeException(e2.getMessage());
}
}
public JceStruct[] read(JceStruct[] jceStructArr, int i2, boolean z) {
return (JceStruct[]) readArray(jceStructArr, i2, z);
}
public <T> Object read(T t, int i2, boolean z) {
if (t instanceof Byte) {
return Byte.valueOf(read((byte) 0, i2, z));
}
if (t instanceof Boolean) {
return Boolean.valueOf(read(false, i2, z));
}
if (t instanceof Short) {
return Short.valueOf(read((short) 0, i2, z));
}
if (t instanceof Integer) {
return Integer.valueOf(read(0, i2, z));
}
if (t instanceof Long) {
return Long.valueOf(read(0L, i2, z));
}
if (t instanceof Float) {
return Float.valueOf(read(0.0f, i2, z));
}
if (t instanceof Double) {
return Double.valueOf(read(0.0d, i2, z));
}
if (t instanceof String) {
return readString(i2, z);
}
if (t instanceof Map) {
return readMap((Map) t, i2, z);
}
if (t instanceof List) {
return readArray((List) t, i2, z);
}
if (t instanceof JceStruct) {
return read((JceStruct) t, i2, z);
}
if (t.getClass().isArray()) {
if (!(t instanceof byte[]) && !(t instanceof Byte[])) {
if (t instanceof boolean[]) {
return read((boolean[]) null, i2, z);
}
if (t instanceof short[]) {
return read((short[]) null, i2, z);
}
if (t instanceof int[]) {
return read((int[]) null, i2, z);
}
if (t instanceof long[]) {
return read((long[]) null, i2, z);
}
if (t instanceof float[]) {
return read((float[]) null, i2, z);
}
if (t instanceof double[]) {
return read((double[]) null, i2, z);
}
return readArray((Object[]) t, i2, z);
}
return read((byte[]) null, i2, z);
}
throw new JceDecodeException("read object error: unsupport type.");
}
}
@@ -0,0 +1,361 @@
package com.qq.taf.jce;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class JceOutputStream {
private ByteBuffer bs;
private OnIllegalArgumentException exceptionHandler;
protected String sServerEncoding;
public JceOutputStream(ByteBuffer byteBuffer) {
this.sServerEncoding = "GBK";
this.bs = byteBuffer;
}
private void writeArray(Object[] objArr, int i2) {
reserve(8);
writeHead((byte) 9, i2);
write(objArr.length, 0);
for (Object obj : objArr) {
write(obj, 0);
}
}
public ByteBuffer getByteBuffer() {
return this.bs;
}
public OnIllegalArgumentException getExceptionHandler() {
return this.exceptionHandler;
}
public void reserve(int i2) {
if (this.bs.remaining() < i2) {
int capacity = (this.bs.capacity() + i2) * 2;
try {
ByteBuffer allocate = ByteBuffer.allocate(capacity);
allocate.put(this.bs.array(), 0, this.bs.position());
this.bs = allocate;
} catch (IllegalArgumentException e2) {
OnIllegalArgumentException onIllegalArgumentException = this.exceptionHandler;
if (onIllegalArgumentException != null) {
onIllegalArgumentException.onException(e2, this.bs, i2, capacity);
}
throw e2;
}
}
}
public void setExceptionHandler(OnIllegalArgumentException onIllegalArgumentException) {
this.exceptionHandler = onIllegalArgumentException;
}
public int setServerEncoding(String str) {
this.sServerEncoding = str;
return 0;
}
public byte[] toByteArray() {
byte[] bArr = new byte[this.bs.position()];
System.arraycopy(this.bs.array(), 0, bArr, 0, this.bs.position());
return bArr;
}
public void write(boolean z, int i2) {
write(z ? (byte) 1 : (byte) 0, i2);
}
public void writeByteString(String str, int i2) {
reserve(str.length() + 10);
byte[] hexStr2Bytes = HexUtil.hexStr2Bytes(str);
if (hexStr2Bytes.length > 255) {
writeHead((byte) 7, i2);
this.bs.putInt(hexStr2Bytes.length);
this.bs.put(hexStr2Bytes);
return;
}
writeHead((byte) 6, i2);
this.bs.put((byte) hexStr2Bytes.length);
this.bs.put(hexStr2Bytes);
}
public void writeHead(byte b2, int i2) {
if (i2 < 15) {
this.bs.put((byte) (b2 | (i2 << 4)));
} else if (i2 < 256) {
this.bs.put((byte) (b2 | 240));
this.bs.put((byte) i2);
} else {
throw new JceEncodeException("tag is too large: " + i2);
}
}
public void writeStringByte(String str, int i2) {
byte[] hexStr2Bytes = HexUtil.hexStr2Bytes(str);
reserve(hexStr2Bytes.length + 10);
if (hexStr2Bytes.length > 255) {
writeHead((byte) 7, i2);
this.bs.putInt(hexStr2Bytes.length);
this.bs.put(hexStr2Bytes);
return;
}
writeHead((byte) 6, i2);
this.bs.put((byte) hexStr2Bytes.length);
this.bs.put(hexStr2Bytes);
}
public void write(byte b2, int i2) {
reserve(3);
if (b2 == 0) {
writeHead((byte) 12, i2);
return;
}
writeHead((byte) 0, i2);
this.bs.put(b2);
}
public JceOutputStream(int i2) {
this.sServerEncoding = "GBK";
this.bs = ByteBuffer.allocate(i2);
}
public void write(short s, int i2) {
reserve(4);
if (s >= -128 && s <= 127) {
write((byte) s, i2);
return;
}
writeHead((byte) 1, i2);
this.bs.putShort(s);
}
public JceOutputStream() {
this(128);
}
public void write(int i2, int i3) {
reserve(6);
if (i2 >= -32768 && i2 <= 32767) {
write((short) i2, i3);
return;
}
writeHead((byte) 2, i3);
this.bs.putInt(i2);
}
public void write(long j, int i2) {
reserve(10);
if (j >= -2147483648L && j <= 2147483647L) {
write((int) j, i2);
return;
}
writeHead((byte) 3, i2);
this.bs.putLong(j);
}
public void write(float f2, int i2) {
reserve(6);
writeHead((byte) 4, i2);
this.bs.putFloat(f2);
}
public void write(double d2, int i2) {
reserve(10);
writeHead((byte) 5, i2);
this.bs.putDouble(d2);
}
public void write(String str, int i2) {
byte[] bytes;
try {
bytes = str.getBytes(this.sServerEncoding);
} catch (UnsupportedEncodingException unused) {
bytes = str.getBytes();
}
reserve(bytes.length + 10);
if (bytes.length > 255) {
writeHead((byte) 7, i2);
this.bs.putInt(bytes.length);
this.bs.put(bytes);
return;
}
writeHead((byte) 6, i2);
this.bs.put((byte) bytes.length);
this.bs.put(bytes);
}
public <K, V> void write(Map<K, V> map, int i2) {
reserve(8);
writeHead((byte) 8, i2);
write(map == null ? 0 : map.size(), 0);
if (map != null) {
for (Map.Entry<K, V> entry : map.entrySet()) {
write(entry.getKey(), 0);
write(entry.getValue(), 1);
}
}
}
public void write(boolean[] zArr, int i2) {
reserve(8);
writeHead((byte) 9, i2);
write(zArr.length, 0);
for (boolean z : zArr) {
write(z, 0);
}
}
public void write(byte[] bArr, int i2) {
reserve(bArr.length + 8);
writeHead((byte) 13, i2);
writeHead((byte) 0, 0);
write(bArr.length, 0);
this.bs.put(bArr);
}
public void write(short[] sArr, int i2) {
reserve(8);
writeHead((byte) 9, i2);
write(sArr.length, 0);
for (short s : sArr) {
write(s, 0);
}
}
public void write(int[] iArr, int i2) {
reserve(8);
writeHead((byte) 9, i2);
write(iArr.length, 0);
for (int i3 : iArr) {
write(i3, 0);
}
}
public void write(long[] jArr, int i2) {
reserve(8);
writeHead((byte) 9, i2);
write(jArr.length, 0);
for (long j : jArr) {
write(j, 0);
}
}
public void write(float[] fArr, int i2) {
reserve(8);
writeHead((byte) 9, i2);
write(fArr.length, 0);
for (float f2 : fArr) {
write(f2, 0);
}
}
public void write(double[] dArr, int i2) {
reserve(8);
writeHead((byte) 9, i2);
write(dArr.length, 0);
for (double d2 : dArr) {
write(d2, 0);
}
}
public <T> void write(T[] tArr, int i2) {
writeArray(tArr, i2);
}
public <T> void write(Collection<T> collection, int i2) {
reserve(8);
writeHead((byte) 9, i2);
write(collection == null ? 0 : collection.size(), 0);
if (collection != null) {
for (T t : collection) {
write(t, 0);
}
}
}
public void write(JceStruct jceStruct, int i2) {
reserve(2);
writeHead((byte) 10, i2);
jceStruct.writeTo(this);
reserve(2);
writeHead((byte) 11, 0);
}
public void write(Byte b2, int i2) {
write(b2.byteValue(), i2);
}
public void write(Boolean bool, int i2) {
write(bool.booleanValue(), i2);
}
public void write(Short sh, int i2) {
write(sh.shortValue(), i2);
}
public void write(Integer num, int i2) {
write(num.intValue(), i2);
}
public void write(Long l, int i2) {
write(l.longValue(), i2);
}
public void write(Float f2, int i2) {
write(f2.floatValue(), i2);
}
public void write(Double d2, int i2) {
write(d2.doubleValue(), i2);
}
public void write(Object obj, int i2) {
if (obj instanceof Byte) {
write(((Byte) obj).byteValue(), i2);
} else if (obj instanceof Boolean) {
write(((Boolean) obj).booleanValue(), i2);
} else if (obj instanceof Short) {
write(((Short) obj).shortValue(), i2);
} else if (obj instanceof Integer) {
write(((Integer) obj).intValue(), i2);
} else if (obj instanceof Long) {
write(((Long) obj).longValue(), i2);
} else if (obj instanceof Float) {
write(((Float) obj).floatValue(), i2);
} else if (obj instanceof Double) {
write(((Double) obj).doubleValue(), i2);
} else if (obj instanceof String) {
write((String) obj, i2);
} else if (obj instanceof Map) {
write((Map) obj, i2);
} else if (obj instanceof List) {
write((Collection) ((List) obj), i2);
} else if (obj instanceof JceStruct) {
write((JceStruct) obj, i2);
} else if (obj instanceof byte[]) {
write((byte[]) obj, i2);
} else if (obj instanceof boolean[]) {
write((boolean[]) obj, i2);
} else if (obj instanceof short[]) {
write((short[]) obj, i2);
} else if (obj instanceof int[]) {
write((int[]) obj, i2);
} else if (obj instanceof long[]) {
write((long[]) obj, i2);
} else if (obj instanceof float[]) {
write((float[]) obj, i2);
} else if (obj instanceof double[]) {
write((double[]) obj, i2);
} else if (obj.getClass().isArray()) {
writeArray((Object[]) obj, i2);
} else if (obj instanceof Collection) {
write((Collection) obj, i2);
} else {
throw new JceEncodeException("write object error: unsupport type. " + obj.getClass());
}
}
}
@@ -0,0 +1,86 @@
package com.qq.taf.jce;
import java.io.Serializable;
public abstract class JceStruct implements Serializable {
public static final byte BYTE = 0;
public static final byte DOUBLE = 5;
public static final byte FLOAT = 4;
public static final byte INT = 2;
public static final int JCE_MAX_STRING_LENGTH = 104857600;
public static final byte LIST = 9;
public static final byte LONG = 3;
public static final byte MAP = 8;
public static final byte SHORT = 1;
public static final byte SIMPLE_LIST = 13;
public static final byte STRING1 = 6;
public static final byte STRING4 = 7;
public static final byte STRUCT_BEGIN = 10;
public static final byte STRUCT_END = 11;
public static final byte ZERO_TAG = 12;
private Object tag;
public static String toDisplaySimpleString(JceStruct jceStruct) {
if (jceStruct == null) {
return null;
}
StringBuilder sb = new StringBuilder();
jceStruct.displaySimple(sb, 0);
return sb.toString();
}
public boolean containField(String str) {
return false;
}
public void display(StringBuilder sb, int i2) {
}
public void displaySimple(StringBuilder sb, int i2) {
}
public Object getFieldByName(String str) {
return null;
}
public Object getTag() {
return this.tag;
}
public JceStruct newInit() {
return null;
}
public abstract void readFrom(JceInputStream jceInputStream);
public void recyle() {
}
public void setFieldByName(String str, Object obj) {
}
public void setTag(Object obj) {
this.tag = obj;
}
public byte[] toByteArray() {
JceOutputStream jceOutputStream = new JceOutputStream();
writeTo(jceOutputStream);
return jceOutputStream.toByteArray();
}
public String toString() {
StringBuilder sb = new StringBuilder();
display(sb, 0);
return sb.toString();
}
public abstract void writeTo(JceOutputStream jceOutputStream);
public byte[] toByteArray(String str) {
JceOutputStream jceOutputStream = new JceOutputStream();
jceOutputStream.setServerEncoding(str);
writeTo(jceOutputStream);
return jceOutputStream.toByteArray();
}
}
@@ -0,0 +1,7 @@
package com.qq.taf.jce;
import java.nio.ByteBuffer;
public interface OnIllegalArgumentException {
void onException(IllegalArgumentException illegalArgumentException, ByteBuffer byteBuffer, int i2, int i3);
}
@@ -0,0 +1,55 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class Action extends JceStruct {
public String reportEventId;
public String reportKey;
public String reportParams;
public String url;
public Action() {
this.url = "";
this.reportEventId = "";
this.reportKey = "";
this.reportParams = "";
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.url = jceInputStream.readString(0, true);
this.reportEventId = jceInputStream.readString(1, false);
this.reportKey = jceInputStream.readString(2, false);
this.reportParams = jceInputStream.readString(3, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write(this.url, 0);
String str = this.reportEventId;
if (str != null) {
jceOutputStream.write(str, 1);
}
String str2 = this.reportKey;
if (str2 != null) {
jceOutputStream.write(str2, 2);
}
String str3 = this.reportParams;
if (str3 != null) {
jceOutputStream.write(str3, 3);
}
}
public Action(String str, String str2, String str3, String str4) {
this.url = "";
this.reportEventId = "";
this.reportKey = "";
this.reportParams = "";
this.url = str;
this.reportEventId = str2;
this.reportKey = str3;
this.reportParams = str4;
}
}
@@ -0,0 +1,36 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class BucketConfig extends JceStruct {
public int bucketId;
public String extra;
public BucketConfig() {
this.bucketId = 0;
this.extra = "";
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.bucketId = jceInputStream.read(this.bucketId, 0, true);
this.extra = jceInputStream.readString(1, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write(this.bucketId, 0);
String str = this.extra;
if (str != null) {
jceOutputStream.write(str, 1);
}
}
public BucketConfig(int i2, String str) {
this.bucketId = 0;
this.extra = "";
this.bucketId = i2;
this.extra = str;
}
}
@@ -0,0 +1,27 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class BusinessExtent extends JceStruct {
public int launchType;
public BusinessExtent() {
this.launchType = 0;
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.launchType = jceInputStream.read(this.launchType, 0, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write(this.launchType, 0);
}
public BusinessExtent(int i2) {
this.launchType = 0;
this.launchType = i2;
}
}
@@ -0,0 +1,42 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class BusinessHead extends JceStruct {
static byte[] cache_head;
public byte[] head;
public int type;
static {
cache_head = new byte[0];
byte[] bArr = {0};
}
public BusinessHead() {
this.type = 0;
this.head = null;
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.type = jceInputStream.read(this.type, 0, true);
this.head = jceInputStream.read(cache_head, 1, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write(this.type, 0);
byte[] bArr = this.head;
if (bArr != null) {
jceOutputStream.write(bArr, 1);
}
}
public BusinessHead(int i2, byte[] bArr) {
this.type = 0;
this.head = null;
this.type = i2;
this.head = bArr;
}
}
@@ -0,0 +1,46 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class Coordinates extends JceStruct {
public double accuracy;
public float latitude;
public float longitude;
public int type;
public Coordinates() {
this.type = 0;
this.latitude = 0.0f;
this.longitude = 0.0f;
this.accuracy = 0.0d;
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.type = jceInputStream.read(this.type, 0, false);
this.latitude = jceInputStream.read(this.latitude, 1, false);
this.longitude = jceInputStream.read(this.longitude, 2, false);
this.accuracy = jceInputStream.read(this.accuracy, 3, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write(this.type, 0);
jceOutputStream.write(this.latitude, 1);
jceOutputStream.write(this.longitude, 2);
jceOutputStream.write(this.accuracy, 3);
}
public Coordinates(int i2, float f2, float f3, double d2) {
this.type = 0;
this.latitude = 0.0f;
this.longitude = 0.0f;
this.accuracy = 0.0d;
this.type = i2;
this.latitude = f2;
this.longitude = f3;
this.accuracy = d2;
}
}
@@ -0,0 +1,33 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class ExtentAccount extends JceStruct {
public String accountId;
public int type;
public ExtentAccount() {
this.type = 0;
this.accountId = "";
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.type = jceInputStream.read(this.type, 0, true);
this.accountId = jceInputStream.readString(1, true);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write(this.type, 0);
jceOutputStream.write(this.accountId, 1);
}
public ExtentAccount(int i2, String str) {
this.type = 0;
this.accountId = "";
this.type = i2;
this.accountId = str;
}
}
@@ -0,0 +1,52 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class ExtentData extends JceStruct {
static BucketConfig cache_bucketInfo = new BucketConfig();
public BucketConfig bucketInfo;
public int checkFlag;
public String extra;
public byte flagByte;
public ExtentData() {
this.checkFlag = 0;
this.flagByte = (byte) 0;
this.extra = "";
this.bucketInfo = null;
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.checkFlag = jceInputStream.read(this.checkFlag, 0, false);
this.flagByte = jceInputStream.read(this.flagByte, 1, false);
this.extra = jceInputStream.readString(2, false);
this.bucketInfo = (BucketConfig) jceInputStream.read((JceStruct) cache_bucketInfo, 3, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write(this.checkFlag, 0);
jceOutputStream.write(this.flagByte, 1);
String str = this.extra;
if (str != null) {
jceOutputStream.write(str, 2);
}
BucketConfig bucketConfig = this.bucketInfo;
if (bucketConfig != null) {
jceOutputStream.write((JceStruct) bucketConfig, 3);
}
}
public ExtentData(int i2, byte b2, String str, BucketConfig bucketConfig) {
this.checkFlag = 0;
this.flagByte = (byte) 0;
this.extra = "";
this.bucketInfo = null;
this.checkFlag = i2;
this.flagByte = b2;
this.extra = str;
this.bucketInfo = bucketConfig;
}
}
@@ -0,0 +1,115 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class LogReport extends JceStruct {
public String callType;
public String channelId;
public String extent;
public String from;
public int isAuto;
public String mid;
public String pageId;
public int pageStep;
public String pid;
public String refPageId;
public String vid;
public LogReport() {
this.pageId = "";
this.refPageId = "";
this.pageStep = 0;
this.callType = "";
this.isAuto = 0;
this.vid = "";
this.pid = "";
this.from = "";
this.channelId = "";
this.mid = "";
this.extent = "";
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.pageId = jceInputStream.readString(0, false);
this.refPageId = jceInputStream.readString(1, false);
this.pageStep = jceInputStream.read(this.pageStep, 2, false);
this.callType = jceInputStream.readString(3, false);
this.isAuto = jceInputStream.read(this.isAuto, 4, false);
this.vid = jceInputStream.readString(5, false);
this.pid = jceInputStream.readString(6, false);
this.from = jceInputStream.readString(7, false);
this.channelId = jceInputStream.readString(8, false);
this.mid = jceInputStream.readString(9, false);
this.extent = jceInputStream.readString(10, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
String str = this.pageId;
if (str != null) {
jceOutputStream.write(str, 0);
}
String str2 = this.refPageId;
if (str2 != null) {
jceOutputStream.write(str2, 1);
}
jceOutputStream.write(this.pageStep, 2);
String str3 = this.callType;
if (str3 != null) {
jceOutputStream.write(str3, 3);
}
jceOutputStream.write(this.isAuto, 4);
String str4 = this.vid;
if (str4 != null) {
jceOutputStream.write(str4, 5);
}
String str5 = this.pid;
if (str5 != null) {
jceOutputStream.write(str5, 6);
}
String str6 = this.from;
if (str6 != null) {
jceOutputStream.write(str6, 7);
}
String str7 = this.channelId;
if (str7 != null) {
jceOutputStream.write(str7, 8);
}
String str8 = this.mid;
if (str8 != null) {
jceOutputStream.write(str8, 9);
}
String str9 = this.extent;
if (str9 != null) {
jceOutputStream.write(str9, 10);
}
}
public LogReport(String str, String str2, int i2, String str3, int i3, String str4, String str5, String str6, String str7, String str8, String str9) {
this.pageId = "";
this.refPageId = "";
this.pageStep = 0;
this.callType = "";
this.isAuto = 0;
this.vid = "";
this.pid = "";
this.from = "";
this.channelId = "";
this.mid = "";
this.extent = "";
this.pageId = str;
this.refPageId = str2;
this.pageStep = i2;
this.callType = str3;
this.isAuto = i3;
this.vid = str4;
this.pid = str5;
this.from = str6;
this.channelId = str7;
this.mid = str8;
this.extent = str9;
}
}
@@ -0,0 +1,61 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class LoginToken extends JceStruct {
static byte[] cache_TokenValue;
public boolean IsMainLogin;
public String TokenAppID;
public byte TokenKeyType;
public String TokenUin;
public byte[] TokenValue;
static {
cache_TokenValue = new byte[0];
byte[] bArr = {0};
}
public LoginToken() {
this.TokenAppID = "";
this.TokenKeyType = (byte) 0;
this.TokenValue = null;
this.TokenUin = "";
this.IsMainLogin = true;
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.TokenAppID = jceInputStream.readString(0, true);
this.TokenKeyType = jceInputStream.read(this.TokenKeyType, 1, true);
this.TokenValue = jceInputStream.read(cache_TokenValue, 2, true);
this.TokenUin = jceInputStream.readString(3, false);
this.IsMainLogin = jceInputStream.read(this.IsMainLogin, 4, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write(this.TokenAppID, 0);
jceOutputStream.write(this.TokenKeyType, 1);
jceOutputStream.write(this.TokenValue, 2);
String str = this.TokenUin;
if (str != null) {
jceOutputStream.write(str, 3);
}
jceOutputStream.write(this.IsMainLogin, 4);
}
public LoginToken(String str, byte b2, byte[] bArr, String str2, boolean z) {
this.TokenAppID = "";
this.TokenKeyType = (byte) 0;
this.TokenValue = null;
this.TokenUin = "";
this.IsMainLogin = true;
this.TokenAppID = str;
this.TokenKeyType = b2;
this.TokenValue = bArr;
this.TokenUin = str2;
this.IsMainLogin = z;
}
}
@@ -0,0 +1,443 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import java.io.Serializable;
public final class QQVideoJCECmd implements Serializable {
static final /* synthetic */ boolean $assertionsDisabled = false;
public static final int _BindCellphone = 24736;
public static final int _CheckBindReadForward = 24869;
public static final int _CheckBindReadReverse = 24870;
public static final int _CheckCode = 24681;
public static final int _GetCode = 24680;
public static final int _NewGetTicket = 60788;
public static final int _NewLogin = 59986;
public static final int _NewLogout = 59988;
public static final int _NewRefreshToken = 59987;
private String __T;
private int __value;
private static QQVideoJCECmd[] __values = new QQVideoJCECmd[195];
public static final int _StGuidGet = 24865;
public static final QQVideoJCECmd StGuidGet = new QQVideoJCECmd(0, _StGuidGet, "StGuidGet");
public static final int _ChannelList = 24593;
public static final QQVideoJCECmd ChannelList = new QQVideoJCECmd(1, _ChannelList, "ChannelList");
public static final int _FeedList = 24608;
public static final QQVideoJCECmd FeedList = new QQVideoJCECmd(2, _FeedList, "FeedList");
public static final int _FeedListiPad = 25316;
public static final QQVideoJCECmd FeedListiPad = new QQVideoJCECmd(3, _FeedListiPad, "FeedListiPad");
public static final int _SearchSmart = 24733;
public static final QQVideoJCECmd SearchSmart = new QQVideoJCECmd(4, _SearchSmart, "SearchSmart");
public static final int _VideoDetails = 24805;
public static final QQVideoJCECmd VideoDetails = new QQVideoJCECmd(5, _VideoDetails, "VideoDetails");
public static final int _DetailVideoList = 24806;
public static final QQVideoJCECmd DetailVideoList = new QQVideoJCECmd(6, _DetailVideoList, "DetailVideoList");
public static final int _DetailCoverList = 24807;
public static final QQVideoJCECmd DetailCoverList = new QQVideoJCECmd(7, _DetailCoverList, "DetailCoverList");
public static final int _SecondaryFeedList = 65231;
public static final QQVideoJCECmd SecondaryFeedList = new QQVideoJCECmd(8, _SecondaryFeedList, "SecondaryFeedList");
public static final int _GetCloudBucketConfig = 24842;
public static final QQVideoJCECmd GetCloudBucketConfig = new QQVideoJCECmd(9, _GetCloudBucketConfig, "GetCloudBucketConfig");
public static final QQVideoJCECmd NewRefreshToken = new QQVideoJCECmd(10, 59987, "NewRefreshToken");
public static final QQVideoJCECmd NewLogin = new QQVideoJCECmd(11, 59986, "NewLogin");
public static final QQVideoJCECmd NewLogout = new QQVideoJCECmd(12, 59988, "NewLogout");
public static final QQVideoJCECmd NewGetTicket = new QQVideoJCECmd(13, 60788, "NewGetTicket");
public static final int _AppUpdate = 24841;
public static final QQVideoJCECmd AppUpdate = new QQVideoJCECmd(14, _AppUpdate, "AppUpdate");
public static final int _WatchRecordListV1 = 24811;
public static final QQVideoJCECmd WatchRecordListV1 = new QQVideoJCECmd(15, _WatchRecordListV1, "WatchRecordListV1");
public static final int _WatchRecordUploadV1 = 24810;
public static final QQVideoJCECmd WatchRecordUploadV1 = new QQVideoJCECmd(16, _WatchRecordUploadV1, "WatchRecordUploadV1");
public static final int _WatchRecordPostersV1 = 24813;
public static final QQVideoJCECmd WatchRecordPostersV1 = new QQVideoJCECmd(17, _WatchRecordPostersV1, "WatchRecordPostersV1");
public static final int _WatchRecordDelV1 = 24812;
public static final QQVideoJCECmd WatchRecordDelV1 = new QQVideoJCECmd(18, _WatchRecordDelV1, "WatchRecordDelV1");
public static final int _TicketTrade = 59572;
public static final QQVideoJCECmd TicketTrade = new QQVideoJCECmd(19, _TicketTrade, "TicketTrade");
public static final int _AiSeeRsaEncrypt = 23875;
public static final QQVideoJCECmd AiSeeRsaEncrypt = new QQVideoJCECmd(20, _AiSeeRsaEncrypt, "AiSeeRsaEncrypt");
public static final int _PriceCloud = 59569;
public static final QQVideoJCECmd PriceCloud = new QQVideoJCECmd(21, _PriceCloud, "PriceCloud");
public static final int _SearchRank = 24732;
public static final QQVideoJCECmd SearchRank = new QQVideoJCECmd(22, _SearchRank, "SearchRank");
public static final int _SearchHotWords = 24797;
public static final QQVideoJCECmd SearchHotWords = new QQVideoJCECmd(23, _SearchHotWords, "SearchHotWords");
public static final int _VideoList = 24902;
public static final QQVideoJCECmd VideoList = new QQVideoJCECmd(24, _VideoList, "VideoList");
public static final int _Search = 24731;
public static final QQVideoJCECmd Search = new QQVideoJCECmd(25, _Search, "Search");
public static final int _CheckDownloadCopyright = 59985;
public static final QQVideoJCECmd CheckDownloadCopyright = new QQVideoJCECmd(26, _CheckDownloadCopyright, "CheckDownloadCopyright");
public static final int _GetCacheList = 24002;
public static final QQVideoJCECmd GetCacheList = new QQVideoJCECmd(27, _GetCacheList, "GetCacheList");
public static final int _AccountPlayPermission = 24194;
public static final QQVideoJCECmd AccountPlayPermission = new QQVideoJCECmd(28, _AccountPlayPermission, "AccountPlayPermission");
public static final int _OneWeekSignUp = 24369;
public static final QQVideoJCECmd OneWeekSignUp = new QQVideoJCECmd(29, _OneWeekSignUp, "OneWeekSignUp");
public static final int _FollowAction = 24824;
public static final QQVideoJCECmd FollowAction = new QQVideoJCECmd(30, _FollowAction, "FollowAction");
public static final int _MyFollow = 24827;
public static final QQVideoJCECmd MyFollow = new QQVideoJCECmd(31, _MyFollow, "MyFollow");
public static final int _MyAllFollow = 24828;
public static final QQVideoJCECmd MyAllFollow = new QQVideoJCECmd(32, _MyAllFollow, "MyAllFollow");
public static final int _OperatePageNav = 24666;
public static final QQVideoJCECmd OperatePageNav = new QQVideoJCECmd(33, _OperatePageNav, "OperatePageNav");
public static final int _OperatePageNavIPad = 25318;
public static final QQVideoJCECmd OperatePageNavIPad = new QQVideoJCECmd(34, _OperatePageNavIPad, "OperatePageNavIPad");
public static final int _OperationPageList = 24648;
public static final QQVideoJCECmd OperationPageList = new QQVideoJCECmd(35, _OperationPageList, "OperationPageList");
public static final int _OperationPageListIPad = 25338;
public static final QQVideoJCECmd OperationPageListIPad = new QQVideoJCECmd(36, _OperationPageListIPad, "OperationPageListIPad");
public static final int _LiveDetail = 24873;
public static final QQVideoJCECmd LiveDetail = new QQVideoJCECmd(37, _LiveDetail, "LiveDetail");
public static final int _LiveDetailIPad = 25356;
public static final QQVideoJCECmd LiveDetailIPad = new QQVideoJCECmd(38, _LiveDetailIPad, "LiveDetailIPad");
public static final int _LivePoll = 24874;
public static final QQVideoJCECmd LivePoll = new QQVideoJCECmd(39, _LivePoll, "LivePoll");
public static final int _LivePollIPad = 25355;
public static final QQVideoJCECmd LivePollIPad = new QQVideoJCECmd(40, _LivePollIPad, "LivePollIPad");
public static final int _LiveMultiCameraInfo = 24875;
public static final QQVideoJCECmd LiveMultiCameraInfo = new QQVideoJCECmd(41, _LiveMultiCameraInfo, "LiveMultiCameraInfo");
public static final int _LiveMultiCameraInfoIPad = 25354;
public static final QQVideoJCECmd LiveMultiCameraInfoIPad = new QQVideoJCECmd(42, _LiveMultiCameraInfoIPad, "LiveMultiCameraInfoIPad");
public static final int _FollowActorPage = 24761;
public static final QQVideoJCECmd FollowActorPage = new QQVideoJCECmd(43, _FollowActorPage, "FollowActorPage");
public static final int _BookAction = 24788;
public static final QQVideoJCECmd BookAction = new QQVideoJCECmd(44, _BookAction, "BookAction");
public static final int _ReportPlayStart = 24702;
public static final QQVideoJCECmd ReportPlayStart = new QQVideoJCECmd(45, _ReportPlayStart, "ReportPlayStart");
public static final int _ReportPlayStop = 24703;
public static final QQVideoJCECmd ReportPlayStop = new QQVideoJCECmd(46, _ReportPlayStop, "ReportPlayStop");
public static final int _AccountUserInfo = 24802;
public static final QQVideoJCECmd AccountUserInfo = new QQVideoJCECmd(47, _AccountUserInfo, "AccountUserInfo");
public static final int _SearchVideoList = 24764;
public static final QQVideoJCECmd SearchVideoList = new QQVideoJCECmd(48, _SearchVideoList, "SearchVideoList");
public static final int _LikeAction = 24803;
public static final QQVideoJCECmd LikeAction = new QQVideoJCECmd(49, _LikeAction, "LikeAction");
public static final QQVideoJCECmd BindCellphone = new QQVideoJCECmd(50, 24736, "BindCellphone");
public static final QQVideoJCECmd CheckBindReadForward = new QQVideoJCECmd(51, 24869, "CheckBindReadForward");
public static final QQVideoJCECmd CheckBindReadReverse = new QQVideoJCECmd(52, 24870, "CheckBindReadReverse");
public static final QQVideoJCECmd CheckCode = new QQVideoJCECmd(53, 24681, "CheckCode");
public static final QQVideoJCECmd GetCode = new QQVideoJCECmd(54, 24680, "GetCode");
public static final int _LikeGlobalSwitch = 24830;
public static final QQVideoJCECmd LikeGlobalSwitch = new QQVideoJCECmd(55, _LikeGlobalSwitch, "LikeGlobalSwitch");
public static final int _CommentGlobalSwitch = 24852;
public static final QQVideoJCECmd CommentGlobalSwitch = new QQVideoJCECmd(56, _CommentGlobalSwitch, "CommentGlobalSwitch");
public static final int _ShareGlobalSwitch = 24851;
public static final QQVideoJCECmd ShareGlobalSwitch = new QQVideoJCECmd(57, _ShareGlobalSwitch, "ShareGlobalSwitch");
public static final int _PublishLiveComment = 24814;
public static final QQVideoJCECmd PublishLiveComment = new QQVideoJCECmd(58, _PublishLiveComment, "PublishLiveComment");
public static final int _PublishVideoComment = 24815;
public static final QQVideoJCECmd PublishVideoComment = new QQVideoJCECmd(59, _PublishVideoComment, "PublishVideoComment");
public static final int _LiveCommentList = 24816;
public static final QQVideoJCECmd LiveCommentList = new QQVideoJCECmd(60, _LiveCommentList, "LiveCommentList");
public static final int _VideoCommentList = 24817;
public static final QQVideoJCECmd VideoCommentList = new QQVideoJCECmd(61, _VideoCommentList, "VideoCommentList");
public static final int _MyCommentList = 24818;
public static final QQVideoJCECmd MyCommentList = new QQVideoJCECmd(62, _MyCommentList, "MyCommentList");
public static final int _CommentDelete = 24821;
public static final QQVideoJCECmd CommentDelete = new QQVideoJCECmd(63, _CommentDelete, "CommentDelete");
public static final int _CommentCount = 24819;
public static final QQVideoJCECmd CommentCount = new QQVideoJCECmd(64, _CommentCount, "CommentCount");
public static final int _FavoriteAction = 24796;
public static final QQVideoJCECmd FavoriteAction = new QQVideoJCECmd(65, _FavoriteAction, "FavoriteAction");
public static final int _FavoriteIDList = 24845;
public static final QQVideoJCECmd FavoriteIDList = new QQVideoJCECmd(66, _FavoriteIDList, "FavoriteIDList");
public static final int _ShareAction = 24853;
public static final QQVideoJCECmd ShareAction = new QQVideoJCECmd(67, _ShareAction, "ShareAction");
public static final int _DynamicInsertFeed = 24883;
public static final QQVideoJCECmd DynamicInsertFeed = new QQVideoJCECmd(68, _DynamicInsertFeed, "DynamicInsertFeed");
public static final int _GetAppStartUpPictureConfig = 24896;
public static final QQVideoJCECmd GetAppStartUpPictureConfig = new QQVideoJCECmd(69, _GetAppStartUpPictureConfig, "GetAppStartUpPictureConfig");
public static final int _TVTimeShiftProgram = 24897;
public static final QQVideoJCECmd TVTimeShiftProgram = new QQVideoJCECmd(70, _TVTimeShiftProgram, "TVTimeShiftProgram");
public static final int _DevReport = 24901;
public static final QQVideoJCECmd DevReport = new QQVideoJCECmd(71, _DevReport, "DevReport");
public static final int _CPRec = 24838;
public static final QQVideoJCECmd CPRec = new QQVideoJCECmd(72, _CPRec, "CPRec");
public static final int _WebGetCode = 24960;
public static final QQVideoJCECmd WebGetCode = new QQVideoJCECmd(73, _WebGetCode, "WebGetCode");
public static final int _HoverBallConfig = 24961;
public static final QQVideoJCECmd HoverBallConfig = new QQVideoJCECmd(74, _HoverBallConfig, "HoverBallConfig");
public static final int _SignInConfig = 24963;
public static final QQVideoJCECmd SignInConfig = new QQVideoJCECmd(75, _SignInConfig, "SignInConfig");
public static final int _GetTmpCredentials = 24854;
public static final QQVideoJCECmd GetTmpCredentials = new QQVideoJCECmd(76, _GetTmpCredentials, "GetTmpCredentials");
public static final int _VideoReplyCommentList = 24965;
public static final QQVideoJCECmd VideoReplyCommentList = new QQVideoJCECmd(77, _VideoReplyCommentList, "VideoReplyCommentList");
public static final int _JumpVideoCommentList = 24966;
public static final QQVideoJCECmd JumpVideoCommentList = new QQVideoJCECmd(78, _JumpVideoCommentList, "JumpVideoCommentList");
public static final int _VideoCommentLike = 24967;
public static final QQVideoJCECmd VideoCommentLike = new QQVideoJCECmd(79, _VideoCommentLike, "VideoCommentLike");
public static final int _PublishVideoReplyComment = 24968;
public static final QQVideoJCECmd PublishVideoReplyComment = new QQVideoJCECmd(80, _PublishVideoReplyComment, "PublishVideoReplyComment");
public static final int _MyReplyCommentList = 24969;
public static final QQVideoJCECmd MyReplyCommentList = new QQVideoJCECmd(81, _MyReplyCommentList, "MyReplyCommentList");
public static final int _ReplyCommentCount = 24970;
public static final QQVideoJCECmd ReplyCommentCount = new QQVideoJCECmd(82, _ReplyCommentCount, "ReplyCommentCount");
public static final int _ModifyUser = 24964;
public static final QQVideoJCECmd ModifyUser = new QQVideoJCECmd(83, _ModifyUser, "ModifyUser");
public static final int _DetailPagePlayBasic = 24976;
public static final QQVideoJCECmd DetailPagePlayBasic = new QQVideoJCECmd(84, _DetailPagePlayBasic, "DetailPagePlayBasic");
public static final int _GetVodUploadSignature = 24979;
public static final QQVideoJCECmd GetVodUploadSignature = new QQVideoJCECmd(85, _GetVodUploadSignature, "GetVodUploadSignature");
public static final int _VodUploadComplete = 25033;
public static final QQVideoJCECmd VodUploadComplete = new QQVideoJCECmd(86, _VodUploadComplete, "VodUploadComplete");
public static final int _GetGShootTopics = 24980;
public static final QQVideoJCECmd GetGShootTopics = new QQVideoJCECmd(87, _GetGShootTopics, "GetGShootTopics");
public static final int _GetActivityEntranceConfigList = 24981;
public static final QQVideoJCECmd GetActivityEntranceConfigList = new QQVideoJCECmd(88, _GetActivityEntranceConfigList, "GetActivityEntranceConfigList");
public static final int _GetHomeTabWelfareEntryAction = 24984;
public static final QQVideoJCECmd GetHomeTabWelfareEntryAction = new QQVideoJCECmd(89, _GetHomeTabWelfareEntryAction, "GetHomeTabWelfareEntryAction");
public static final int _AppStartupConfig = 24990;
public static final QQVideoJCECmd AppStartupConfig = new QQVideoJCECmd(90, _AppStartupConfig, "AppStartupConfig");
public static final int _TVShowList = 24997;
public static final QQVideoJCECmd TVShowList = new QQVideoJCECmd(91, _TVShowList, "TVShowList");
public static final int _TabHoverBallConfig = 25006;
public static final QQVideoJCECmd TabHoverBallConfig = new QQVideoJCECmd(92, _TabHoverBallConfig, "TabHoverBallConfig");
public static final int _CPClassificationList = 25007;
public static final QQVideoJCECmd CPClassificationList = new QQVideoJCECmd(93, _CPClassificationList, "CPClassificationList");
public static final int _FollowActorTabPage = 25008;
public static final QQVideoJCECmd FollowActorTabPage = new QQVideoJCECmd(94, _FollowActorTabPage, "FollowActorTabPage");
public static final int _CPVideoList = 25018;
public static final QQVideoJCECmd CPVideoList = new QQVideoJCECmd(95, _CPVideoList, "CPVideoList");
public static final int _RedDotConfig = 25019;
public static final QQVideoJCECmd RedDotConfig = new QQVideoJCECmd(96, _RedDotConfig, "RedDotConfig");
public static final int _LiveExt = 25025;
public static final QQVideoJCECmd LiveExt = new QQVideoJCECmd(97, _LiveExt, "LiveExt");
public static final int _LiveExtIPad = 25353;
public static final QQVideoJCECmd LiveExtIPad = new QQVideoJCECmd(98, _LiveExtIPad, "LiveExtIPad");
public static final int _TopicList = 25030;
public static final QQVideoJCECmd TopicList = new QQVideoJCECmd(99, _TopicList, "TopicList");
public static final int _UserVideoList = 25031;
public static final QQVideoJCECmd UserVideoList = new QQVideoJCECmd(100, _UserVideoList, "UserVideoList");
public static final int _UcenterCfg = 25049;
public static final QQVideoJCECmd UcenterCfg = new QQVideoJCECmd(101, _UcenterCfg, "UcenterCfg");
public static final int _TaskComplete = 25042;
public static final QQVideoJCECmd TaskComplete = new QQVideoJCECmd(102, _TaskComplete, "TaskComplete");
public static final int _TaskList = 25043;
public static final QQVideoJCECmd TaskList = new QQVideoJCECmd(103, _TaskList, "TaskList");
public static final int _H5SkipConfig = 25047;
public static final QQVideoJCECmd H5SkipConfig = new QQVideoJCECmd(104, _H5SkipConfig, "H5SkipConfig");
public static final int _TaskListWithAuth = 25048;
public static final QQVideoJCECmd TaskListWithAuth = new QQVideoJCECmd(105, _TaskListWithAuth, "TaskListWithAuth");
public static final int _GetCpInfo = 25060;
public static final QQVideoJCECmd GetCpInfo = new QQVideoJCECmd(106, _GetCpInfo, "GetCpInfo");
public static final int _PortraitVideoList = 25065;
public static final QQVideoJCECmd PortraitVideoList = new QQVideoJCECmd(107, _PortraitVideoList, "PortraitVideoList");
public static final int _PortraitVideoListIPad = 25359;
public static final QQVideoJCECmd PortraitVideoListIPad = new QQVideoJCECmd(108, _PortraitVideoListIPad, "PortraitVideoListIPad");
public static final int _HomeRedDotConfig = 25063;
public static final QQVideoJCECmd HomeRedDotConfig = new QQVideoJCECmd(109, _HomeRedDotConfig, "HomeRedDotConfig");
public static final int _EraseHomeRedDot = 25068;
public static final QQVideoJCECmd EraseHomeRedDot = new QQVideoJCECmd(110, _EraseHomeRedDot, "EraseHomeRedDot");
public static final int _LiveHistoryCommentList = 25062;
public static final QQVideoJCECmd LiveHistoryCommentList = new QQVideoJCECmd(111, _LiveHistoryCommentList, "LiveHistoryCommentList");
public static final int _MsgList = 25072;
public static final QQVideoJCECmd MsgList = new QQVideoJCECmd(112, _MsgList, "MsgList");
public static final int _MsgPoll = 25073;
public static final QQVideoJCECmd MsgPoll = new QQVideoJCECmd(113, _MsgPoll, "MsgPoll");
public static final int _LikeList = 25093;
public static final QQVideoJCECmd LikeList = new QQVideoJCECmd(114, _LikeList, "LikeList");
public static final int _InteractiveMsgList = 25098;
public static final QQVideoJCECmd InteractiveMsgList = new QQVideoJCECmd(115, _InteractiveMsgList, "InteractiveMsgList");
public static final int _CommunityFeedList = 25107;
public static final QQVideoJCECmd CommunityFeedList = new QQVideoJCECmd(116, _CommunityFeedList, "CommunityFeedList");
public static final int _CircleAction = 25110;
public static final QQVideoJCECmd CircleAction = new QQVideoJCECmd(117, _CircleAction, "CircleAction");
public static final int _CircleHomePage = 25111;
public static final QQVideoJCECmd CircleHomePage = new QQVideoJCECmd(118, _CircleHomePage, "CircleHomePage");
public static final int _DeletePost = 25115;
public static final QQVideoJCECmd DeletePost = new QQVideoJCECmd(119, _DeletePost, "DeletePost");
public static final int _MyCircleList = 25113;
public static final QQVideoJCECmd MyCircleList = new QQVideoJCECmd(120, _MyCircleList, "MyCircleList");
public static final int _AllMyCircleList = 25116;
public static final QQVideoJCECmd AllMyCircleList = new QQVideoJCECmd(121, _AllMyCircleList, "AllMyCircleList");
public static final int _CommunityPersonHomePage = 25106;
public static final QQVideoJCECmd CommunityPersonHomePage = new QQVideoJCECmd(122, _CommunityPersonHomePage, "CommunityPersonHomePage");
public static final int _CreatePost = 25112;
public static final QQVideoJCECmd CreatePost = new QQVideoJCECmd(123, _CreatePost, "CreatePost");
public static final int _ForwardPost = 25119;
public static final QQVideoJCECmd ForwardPost = new QQVideoJCECmd(124, _ForwardPost, "ForwardPost");
public static final int _ReportPost = 25121;
public static final QQVideoJCECmd ReportPost = new QQVideoJCECmd(125, _ReportPost, "ReportPost");
public static final int _AllCircleList = 25123;
public static final QQVideoJCECmd AllCircleList = new QQVideoJCECmd(126, _AllCircleList, "AllCircleList");
public static final int _ModifyUserInfo = 25127;
public static final QQVideoJCECmd ModifyUserInfo = new QQVideoJCECmd(127, _ModifyUserInfo, "ModifyUserInfo");
public static final int _CommunityFollowingList = 25102;
public static final QQVideoJCECmd CommunityFollowingList = new QQVideoJCECmd(128, _CommunityFollowingList, "CommunityFollowingList");
public static final int _GetPostInfo = 25122;
public static final QQVideoJCECmd GetPostInfo = new QQVideoJCECmd(129, _GetPostInfo, "GetPostInfo");
public static final int _CommunityMuteInfo = 25130;
public static final QQVideoJCECmd CommunityMuteInfo = new QQVideoJCECmd(130, _CommunityMuteInfo, "CommunityMuteInfo");
public static final int _PostDetail = 25143;
public static final QQVideoJCECmd PostDetail = new QQVideoJCECmd(131, _PostDetail, "PostDetail");
public static final int _PostDetailIPad = 25360;
public static final QQVideoJCECmd PostDetailIPad = new QQVideoJCECmd(132, _PostDetailIPad, "PostDetailIPad");
public static final int _MomentCommentList = 25153;
public static final QQVideoJCECmd MomentCommentList = new QQVideoJCECmd(133, _MomentCommentList, "MomentCommentList");
public static final int _AppBottomTabBubble = 25159;
public static final QQVideoJCECmd AppBottomTabBubble = new QQVideoJCECmd(134, _AppBottomTabBubble, "AppBottomTabBubble");
public static final int _PayOrder = 25164;
public static final QQVideoJCECmd PayOrder = new QQVideoJCECmd(135, _PayOrder, "PayOrder");
public static final int _GuidVipRequest = 25200;
public static final QQVideoJCECmd GuidVipRequest = new QQVideoJCECmd(136, _GuidVipRequest, "GuidVipRequest");
public static final int _CircleUserList = 25239;
public static final QQVideoJCECmd CircleUserList = new QQVideoJCECmd(137, _CircleUserList, "CircleUserList");
public static final int _CacheVideoList = 25240;
public static final QQVideoJCECmd CacheVideoList = new QQVideoJCECmd(138, _CacheVideoList, "CacheVideoList");
public static final int _CachedVideoInfo = 25241;
public static final QQVideoJCECmd CachedVideoInfo = new QQVideoJCECmd(139, _CachedVideoInfo, "CachedVideoInfo");
public static final int _PersonalConf = 25265;
public static final QQVideoJCECmd PersonalConf = new QQVideoJCECmd(140, _PersonalConf, "PersonalConf");
public static final int _PersonalConfFix = 25263;
public static final QQVideoJCECmd PersonalConfFix = new QQVideoJCECmd(141, _PersonalConfFix, "PersonalConfFix");
public static final int _PhoneBind = 25267;
public static final QQVideoJCECmd PhoneBind = new QQVideoJCECmd(142, _PhoneBind, "PhoneBind");
public static final int _ScreenLiveList = 25282;
public static final QQVideoJCECmd ScreenLiveList = new QQVideoJCECmd(143, _ScreenLiveList, "ScreenLiveList");
public static final int _ScreenLiveListIPad = 25352;
public static final QQVideoJCECmd ScreenLiveListIPad = new QQVideoJCECmd(144, _ScreenLiveListIPad, "ScreenLiveListIPad");
public static final int _IsScreenHasLiveList = 25285;
public static final QQVideoJCECmd IsScreenHasLiveList = new QQVideoJCECmd(145, _IsScreenHasLiveList, "IsScreenHasLiveList");
public static final int _IsScreenHasLiveListIPad = 25351;
public static final QQVideoJCECmd IsScreenHasLiveListIPad = new QQVideoJCECmd(146, _IsScreenHasLiveListIPad, "IsScreenHasLiveListIPad");
public static final int _MatchFilter = 25311;
public static final QQVideoJCECmd MatchFilter = new QQVideoJCECmd(147, _MatchFilter, "MatchFilter");
public static final int _PidTimeShift = 25312;
public static final QQVideoJCECmd PidTimeShift = new QQVideoJCECmd(148, _PidTimeShift, "PidTimeShift");
public static final int _PidEditTask = 25313;
public static final QQVideoJCECmd PidEditTask = new QQVideoJCECmd(149, _PidEditTask, "PidEditTask");
public static final int _PidQueryTask = 25314;
public static final QQVideoJCECmd PidQueryTask = new QQVideoJCECmd(150, _PidQueryTask, "PidQueryTask");
public static final int _CheckUserVipBind = 25272;
public static final QQVideoJCECmd CheckUserVipBind = new QQVideoJCECmd(151, _CheckUserVipBind, "CheckUserVipBind");
public static final int _UninterestedReport = 25324;
public static final QQVideoJCECmd UninterestedReport = new QQVideoJCECmd(152, _UninterestedReport, "UninterestedReport");
public static final int _UninterestedReportDup = 25317;
public static final QQVideoJCECmd UninterestedReportDup = new QQVideoJCECmd(153, _UninterestedReportDup, "UninterestedReportDup");
public static final int _GameList = 25309;
public static final QQVideoJCECmd GameList = new QQVideoJCECmd(154, _GameList, "GameList");
public static final int _GameNum = 25310;
public static final QQVideoJCECmd GameNum = new QQVideoJCECmd(155, _GameNum, "GameNum");
public static final int _GameCenterTab = 25315;
public static final QQVideoJCECmd GameCenterTab = new QQVideoJCECmd(156, _GameCenterTab, "GameCenterTab");
public static final int _GameMatchTab = 25369;
public static final QQVideoJCECmd GameMatchTab = new QQVideoJCECmd(157, _GameMatchTab, "GameMatchTab");
public static final int _SubscribeGameList = 25319;
public static final QQVideoJCECmd SubscribeGameList = new QQVideoJCECmd(158, _SubscribeGameList, "SubscribeGameList");
public static final int _GameIDsToSubscribe = 25323;
public static final QQVideoJCECmd GameIDsToSubscribe = new QQVideoJCECmd(159, _GameIDsToSubscribe, "GameIDsToSubscribe");
public static final int _BatchSubscribeAPP = 25325;
public static final QQVideoJCECmd BatchSubscribeAPP = new QQVideoJCECmd(160, _BatchSubscribeAPP, "BatchSubscribeAPP");
public static final int _ChannelsWithPrograms = 25328;
public static final QQVideoJCECmd ChannelsWithPrograms = new QQVideoJCECmd(161, _ChannelsWithPrograms, "ChannelsWithPrograms");
public static final int _SubscribedPids = 24809;
public static final QQVideoJCECmd SubscribedPids = new QQVideoJCECmd(162, _SubscribedPids, "SubscribedPids");
public static final int _CheckVideoEpisodes = 25331;
public static final QQVideoJCECmd CheckVideoEpisodes = new QQVideoJCECmd(163, _CheckVideoEpisodes, "CheckVideoEpisodes");
public static final int _ProgramsList = 25333;
public static final QQVideoJCECmd ProgramsList = new QQVideoJCECmd(164, _ProgramsList, "ProgramsList");
public static final int _GetCircleInfo = 25337;
public static final QQVideoJCECmd GetCircleInfo = new QQVideoJCECmd(165, _GetCircleInfo, "GetCircleInfo");
public static final int _FeedsLiveComment = 25332;
public static final QQVideoJCECmd FeedsLiveComment = new QQVideoJCECmd(166, _FeedsLiveComment, "FeedsLiveComment");
public static final int _IPadCPClassificationList = 25349;
public static final QQVideoJCECmd IPadCPClassificationList = new QQVideoJCECmd(167, _IPadCPClassificationList, "IPadCPClassificationList");
public static final int _IPadFollowActorTabPage = 25348;
public static final QQVideoJCECmd IPadFollowActorTabPage = new QQVideoJCECmd(168, _IPadFollowActorTabPage, "IPadFollowActorTabPage");
public static final int _VideoDetailsIPad = 25346;
public static final QQVideoJCECmd VideoDetailsIPad = new QQVideoJCECmd(169, _VideoDetailsIPad, "VideoDetailsIPad");
public static final int _GetTicketSignature = 25306;
public static final QQVideoJCECmd GetTicketSignature = new QQVideoJCECmd(170, _GetTicketSignature, "GetTicketSignature");
public static final int _LoginNotice = 25367;
public static final QQVideoJCECmd LoginNotice = new QQVideoJCECmd(171, _LoginNotice, "LoginNotice");
public static final int _VidEditTask = 25374;
public static final QQVideoJCECmd VidEditTask = new QQVideoJCECmd(172, _VidEditTask, "VidEditTask");
public static final int _TVCircleCardList = 25382;
public static final QQVideoJCECmd TVCircleCardList = new QQVideoJCECmd(173, _TVCircleCardList, "TVCircleCardList");
public static final int _LiveMsgRead = 25404;
public static final QQVideoJCECmd LiveMsgRead = new QQVideoJCECmd(174, _LiveMsgRead, "LiveMsgRead");
public static final int _FifaVideoList = 25413;
public static final QQVideoJCECmd FifaVideoList = new QQVideoJCECmd(175, _FifaVideoList, "FifaVideoList");
public static final int _Topic = 25419;
public static final QQVideoJCECmd Topic = new QQVideoJCECmd(176, _Topic, "Topic");
public static final int _SubscribeConf = 25427;
public static final QQVideoJCECmd SubscribeConf = new QQVideoJCECmd(177, _SubscribeConf, "SubscribeConf");
public static final int _PortraitLiveList = 25454;
public static final QQVideoJCECmd PortraitLiveList = new QQVideoJCECmd(178, _PortraitLiveList, "PortraitLiveList");
public static final int _FoldingScreenHoverCard = 25456;
public static final QQVideoJCECmd FoldingScreenHoverCard = new QQVideoJCECmd(179, _FoldingScreenHoverCard, "FoldingScreenHoverCard");
public static final int _TVTimeShiftProgramAuthority = 25457;
public static final QQVideoJCECmd TVTimeShiftProgramAuthority = new QQVideoJCECmd(180, _TVTimeShiftProgramAuthority, "TVTimeShiftProgramAuthority");
public static final int _SnapshotCreate = 25471;
public static final QQVideoJCECmd SnapshotCreate = new QQVideoJCECmd(181, _SnapshotCreate, "SnapshotCreate");
public static final int _SnapshotDel = 25473;
public static final QQVideoJCECmd SnapshotDel = new QQVideoJCECmd(182, _SnapshotDel, "SnapshotDel");
public static final int _SnapshotActList = 25477;
public static final QQVideoJCECmd SnapshotActList = new QQVideoJCECmd(183, _SnapshotActList, "SnapshotActList");
public static final int _ModulePage = 25481;
public static final QQVideoJCECmd ModulePage = new QQVideoJCECmd(184, _ModulePage, "ModulePage");
public static final int _GetSnapshotDetail = 25479;
public static final QQVideoJCECmd GetSnapshotDetail = new QQVideoJCECmd(185, _GetSnapshotDetail, "GetSnapshotDetail");
public static final int _SnapshotPostInfo = 25482;
public static final QQVideoJCECmd SnapshotPostInfo = new QQVideoJCECmd(186, _SnapshotPostInfo, "SnapshotPostInfo");
public static final int _ActivityHomePage = 25483;
public static final QQVideoJCECmd ActivityHomePage = new QQVideoJCECmd(187, _ActivityHomePage, "ActivityHomePage");
public static final int _GetWSAuthCode = 25464;
public static final QQVideoJCECmd GetWSAuthCode = new QQVideoJCECmd(188, _GetWSAuthCode, "GetWSAuthCode");
public static final int _WsPollingMsg = 25493;
public static final QQVideoJCECmd WsPollingMsg = new QQVideoJCECmd(189, _WsPollingMsg, "WsPollingMsg");
public static final int _MedalStatistics = 25495;
public static final QQVideoJCECmd MedalStatistics = new QQVideoJCECmd(190, _MedalStatistics, "MedalStatistics");
public static final int _MedalChangeSubscription = 25496;
public static final QQVideoJCECmd MedalChangeSubscription = new QQVideoJCECmd(191, _MedalChangeSubscription, "MedalChangeSubscription");
public static final int _MedalDetails = 25498;
public static final QQVideoJCECmd MedalDetails = new QQVideoJCECmd(192, _MedalDetails, "MedalDetails");
public static final int _GetScheme = 25504;
public static final QQVideoJCECmd GetScheme = new QQVideoJCECmd(193, _GetScheme, "GetScheme");
public static final int _SubGameList = 25502;
public static final QQVideoJCECmd SubGameList = new QQVideoJCECmd(194, _SubGameList, "SubGameList");
private QQVideoJCECmd(int i2, int i3, String str) {
this.__T = new String();
this.__T = str;
this.__value = i3;
__values[i2] = this;
}
public static QQVideoJCECmd convert(int i2) {
int i3 = 0;
while (true) {
QQVideoJCECmd[] qQVideoJCECmdArr = __values;
if (i3 >= qQVideoJCECmdArr.length) {
return null;
}
if (qQVideoJCECmdArr[i3].value() == i2) {
return __values[i3];
}
i3++;
}
}
public String toString() {
return this.__T;
}
public int value() {
return this.__value;
}
public static QQVideoJCECmd convert(String str) {
int i2 = 0;
while (true) {
QQVideoJCECmd[] qQVideoJCECmdArr = __values;
if (i2 >= qQVideoJCECmdArr.length) {
return null;
}
if (qQVideoJCECmdArr[i2].toString().equals(str)) {
return __values[i2];
}
i2++;
}
}
}
@@ -0,0 +1,255 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class QUA extends JceStruct {
public String appSubVersion;
public int areaMode;
public String channelId;
public String clientKey;
public Coordinates coordinates;
public int countryCode;
public int densityDpi;
public String deviceId;
public String deviceModel;
public int deviceType;
public String extent;
public ExtentData extentData;
public String idfa;
public String imei;
public String imsi;
public int langCode;
public String mac;
public int markerId;
public int mobileISP;
public int networkMode;
public String omgId;
public int platform;
public String platformVersion;
public String qimei;
public int screenHeight;
public int screenWidth;
public String serverid;
public String v4ip;
public String versionCode;
public String versionName;
static ExtentData cache_extentData = new ExtentData();
static Coordinates cache_coordinates = new Coordinates();
public QUA() {
this.versionName = "";
this.versionCode = "";
this.screenWidth = 0;
this.screenHeight = 0;
this.platform = 0;
this.platformVersion = "";
this.markerId = 0;
this.networkMode = 0;
this.densityDpi = 0;
this.channelId = "";
this.imei = "";
this.imsi = "";
this.idfa = "";
this.omgId = "";
this.extent = "";
this.extentData = null;
this.clientKey = "";
this.mac = "";
this.serverid = "";
this.coordinates = null;
this.deviceId = "";
this.deviceModel = "";
this.deviceType = 0;
this.mobileISP = 0;
this.areaMode = 0;
this.countryCode = 0;
this.langCode = 0;
this.appSubVersion = "";
this.v4ip = "";
this.qimei = "";
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.versionName = jceInputStream.readString(0, true);
this.versionCode = jceInputStream.readString(1, true);
this.screenWidth = jceInputStream.read(this.screenWidth, 2, false);
this.screenHeight = jceInputStream.read(this.screenHeight, 3, false);
this.platform = jceInputStream.read(this.platform, 4, false);
this.platformVersion = jceInputStream.readString(5, false);
this.markerId = jceInputStream.read(this.markerId, 6, false);
this.networkMode = jceInputStream.read(this.networkMode, 7, false);
this.densityDpi = jceInputStream.read(this.densityDpi, 8, false);
this.channelId = jceInputStream.readString(9, false);
this.imei = jceInputStream.readString(10, false);
this.imsi = jceInputStream.readString(11, false);
this.idfa = jceInputStream.readString(12, false);
this.omgId = jceInputStream.readString(13, false);
this.extent = jceInputStream.readString(14, false);
this.extentData = (ExtentData) jceInputStream.read((JceStruct) cache_extentData, 15, false);
this.clientKey = jceInputStream.readString(16, false);
this.mac = jceInputStream.readString(17, false);
this.serverid = jceInputStream.readString(18, false);
this.coordinates = (Coordinates) jceInputStream.read((JceStruct) cache_coordinates, 19, false);
this.deviceId = jceInputStream.readString(20, false);
this.deviceModel = jceInputStream.readString(21, false);
this.deviceType = jceInputStream.read(this.deviceType, 22, false);
this.mobileISP = jceInputStream.read(this.mobileISP, 23, false);
this.areaMode = jceInputStream.read(this.areaMode, 24, false);
this.countryCode = jceInputStream.read(this.countryCode, 25, false);
this.langCode = jceInputStream.read(this.langCode, 26, false);
this.appSubVersion = jceInputStream.readString(27, false);
this.v4ip = jceInputStream.readString(28, false);
this.qimei = jceInputStream.readString(29, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write(this.versionName, 0);
jceOutputStream.write(this.versionCode, 1);
jceOutputStream.write(this.screenWidth, 2);
jceOutputStream.write(this.screenHeight, 3);
jceOutputStream.write(this.platform, 4);
String str = this.platformVersion;
if (str != null) {
jceOutputStream.write(str, 5);
}
jceOutputStream.write(this.markerId, 6);
jceOutputStream.write(this.networkMode, 7);
jceOutputStream.write(this.densityDpi, 8);
String str2 = this.channelId;
if (str2 != null) {
jceOutputStream.write(str2, 9);
}
String str3 = this.imei;
if (str3 != null) {
jceOutputStream.write(str3, 10);
}
String str4 = this.imsi;
if (str4 != null) {
jceOutputStream.write(str4, 11);
}
String str5 = this.idfa;
if (str5 != null) {
jceOutputStream.write(str5, 12);
}
String str6 = this.omgId;
if (str6 != null) {
jceOutputStream.write(str6, 13);
}
String str7 = this.extent;
if (str7 != null) {
jceOutputStream.write(str7, 14);
}
ExtentData extentData = this.extentData;
if (extentData != null) {
jceOutputStream.write((JceStruct) extentData, 15);
}
String str8 = this.clientKey;
if (str8 != null) {
jceOutputStream.write(str8, 16);
}
String str9 = this.mac;
if (str9 != null) {
jceOutputStream.write(str9, 17);
}
String str10 = this.serverid;
if (str10 != null) {
jceOutputStream.write(str10, 18);
}
Coordinates coordinates = this.coordinates;
if (coordinates != null) {
jceOutputStream.write((JceStruct) coordinates, 19);
}
String str11 = this.deviceId;
if (str11 != null) {
jceOutputStream.write(str11, 20);
}
String str12 = this.deviceModel;
if (str12 != null) {
jceOutputStream.write(str12, 21);
}
jceOutputStream.write(this.deviceType, 22);
jceOutputStream.write(this.mobileISP, 23);
jceOutputStream.write(this.areaMode, 24);
jceOutputStream.write(this.countryCode, 25);
jceOutputStream.write(this.langCode, 26);
String str13 = this.appSubVersion;
if (str13 != null) {
jceOutputStream.write(str13, 27);
}
String str14 = this.v4ip;
if (str14 != null) {
jceOutputStream.write(str14, 28);
}
String str15 = this.qimei;
if (str15 != null) {
jceOutputStream.write(str15, 29);
}
}
public QUA(String str, String str2, int i2, int i3, int i4, String str3, int i5, int i6, int i7, String str4, String str5, String str6, String str7, String str8, String str9, ExtentData extentData, String str10, String str11, String str12, Coordinates coordinates, String str13, String str14, int i8, int i9, int i10, int i11, int i12, String str15, String str16, String str17) {
this.versionName = "";
this.versionCode = "";
this.screenWidth = 0;
this.screenHeight = 0;
this.platform = 0;
this.platformVersion = "";
this.markerId = 0;
this.networkMode = 0;
this.densityDpi = 0;
this.channelId = "";
this.imei = "";
this.imsi = "";
this.idfa = "";
this.omgId = "";
this.extent = "";
this.extentData = null;
this.clientKey = "";
this.mac = "";
this.serverid = "";
this.coordinates = null;
this.deviceId = "";
this.deviceModel = "";
this.deviceType = 0;
this.mobileISP = 0;
this.areaMode = 0;
this.countryCode = 0;
this.langCode = 0;
this.appSubVersion = "";
this.v4ip = "";
this.qimei = "";
this.versionName = str;
this.versionCode = str2;
this.screenWidth = i2;
this.screenHeight = i3;
this.platform = i4;
this.platformVersion = str3;
this.markerId = i5;
this.networkMode = i6;
this.densityDpi = i7;
this.channelId = str4;
this.imei = str5;
this.imsi = str6;
this.idfa = str7;
this.omgId = str8;
this.extent = str9;
this.extentData = extentData;
this.clientKey = str10;
this.mac = str11;
this.serverid = str12;
this.coordinates = coordinates;
this.deviceId = str13;
this.deviceModel = str14;
this.deviceType = i8;
this.mobileISP = i9;
this.areaMode = i10;
this.countryCode = i11;
this.langCode = i12;
this.appSubVersion = str15;
this.v4ip = str16;
this.qimei = str17;
}
}
@@ -0,0 +1,54 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class RequestCommand extends JceStruct {
static byte[] cache_body;
public byte[] body;
public BusinessHead businessHead;
public RequestHead head;
static RequestHead cache_head = new RequestHead();
static BusinessHead cache_businessHead = new BusinessHead();
static {
cache_body = new byte[0];
byte[] bArr = {0};
}
public RequestCommand() {
this.head = null;
this.body = null;
this.businessHead = null;
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.head = (RequestHead) jceInputStream.read((JceStruct) cache_head, 0, true);
this.body = jceInputStream.read(cache_body, 1, false);
this.businessHead = (BusinessHead) jceInputStream.read((JceStruct) cache_businessHead, 2, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write((JceStruct) this.head, 0);
byte[] bArr = this.body;
if (bArr != null) {
jceOutputStream.write(bArr, 1);
}
BusinessHead businessHead = this.businessHead;
if (businessHead != null) {
jceOutputStream.write((JceStruct) businessHead, 2);
}
}
public RequestCommand(RequestHead requestHead, byte[] bArr, BusinessHead businessHead) {
this.head = null;
this.body = null;
this.businessHead = null;
this.head = requestHead;
this.body = bArr;
this.businessHead = businessHead;
}
}
@@ -0,0 +1,141 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
import java.util.ArrayList;
import java.util.Collection;
public final class RequestHead extends JceStruct {
static BusinessExtent cache_busiExtent;
static ArrayList<ExtentAccount> cache_extentAccountList;
static LogReport cache_logReport;
static SafeInfo cache_safeInfo;
public String appId;
public BusinessExtent busiExtent;
public int cmdId;
public int contentType;
public ArrayList<ExtentAccount> extentAccountList;
public String guid;
public int isSupportDolby;
public LogReport logReport;
public int oemPlatform;
public QUA qua;
public int requestId;
public SafeInfo safeInfo;
public ArrayList<LoginToken> token;
static QUA cache_qua = new QUA();
static ArrayList<LoginToken> cache_token = new ArrayList<>();
static {
cache_token.add(new LoginToken());
cache_logReport = new LogReport();
cache_extentAccountList = new ArrayList<>();
cache_extentAccountList.add(new ExtentAccount());
cache_safeInfo = new SafeInfo();
cache_busiExtent = new BusinessExtent();
}
public RequestHead() {
this.requestId = 0;
this.cmdId = 0;
this.qua = null;
this.appId = "";
this.guid = "";
this.token = null;
this.logReport = null;
this.extentAccountList = null;
this.oemPlatform = 0;
this.isSupportDolby = 0;
this.contentType = 0;
this.safeInfo = null;
this.busiExtent = null;
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.requestId = jceInputStream.read(this.requestId, 0, true);
this.cmdId = jceInputStream.read(this.cmdId, 1, true);
this.qua = (QUA) jceInputStream.read((JceStruct) cache_qua, 2, false);
this.appId = jceInputStream.readString(3, false);
this.guid = jceInputStream.readString(4, false);
this.token = (ArrayList) jceInputStream.read(cache_token, 5, false);
this.logReport = (LogReport) jceInputStream.read((JceStruct) cache_logReport, 6, false);
this.extentAccountList = (ArrayList) jceInputStream.read( cache_extentAccountList, 7, false);
this.oemPlatform = jceInputStream.read(this.oemPlatform, 8, false);
this.isSupportDolby = jceInputStream.read(this.isSupportDolby, 9, false);
this.contentType = jceInputStream.read(this.contentType, 10, false);
this.safeInfo = (SafeInfo) jceInputStream.read((JceStruct) cache_safeInfo, 11, false);
this.busiExtent = (BusinessExtent) jceInputStream.read((JceStruct) cache_busiExtent, 12, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write(this.requestId, 0);
jceOutputStream.write(this.cmdId, 1);
QUA qua = this.qua;
if (qua != null) {
jceOutputStream.write((JceStruct) qua, 2);
}
String str = this.appId;
if (str != null) {
jceOutputStream.write(str, 3);
}
String str2 = this.guid;
if (str2 != null) {
jceOutputStream.write(str2, 4);
}
ArrayList<LoginToken> arrayList = this.token;
if (arrayList != null) {
jceOutputStream.write((Collection) arrayList, 5);
}
LogReport logReport = this.logReport;
if (logReport != null) {
jceOutputStream.write((JceStruct) logReport, 6);
}
ArrayList<ExtentAccount> arrayList2 = this.extentAccountList;
if (arrayList2 != null) {
jceOutputStream.write((Collection) arrayList2, 7);
}
jceOutputStream.write(this.oemPlatform, 8);
jceOutputStream.write(this.isSupportDolby, 9);
jceOutputStream.write(this.contentType, 10);
SafeInfo safeInfo = this.safeInfo;
if (safeInfo != null) {
jceOutputStream.write((JceStruct) safeInfo, 11);
}
BusinessExtent businessExtent = this.busiExtent;
if (businessExtent != null) {
jceOutputStream.write((JceStruct) businessExtent, 12);
}
}
public RequestHead(int i2, int i3, QUA qua, String str, String str2, ArrayList<LoginToken> arrayList, LogReport logReport, ArrayList<ExtentAccount> arrayList2, int i4, int i5, int i6, SafeInfo safeInfo, BusinessExtent businessExtent) {
this.requestId = 0;
this.cmdId = 0;
this.qua = null;
this.appId = "";
this.guid = "";
this.token = null;
this.logReport = null;
this.extentAccountList = null;
this.oemPlatform = 0;
this.isSupportDolby = 0;
this.contentType = 0;
this.safeInfo = null;
this.busiExtent = null;
this.requestId = i2;
this.cmdId = i3;
this.qua = qua;
this.appId = str;
this.guid = str2;
this.token = arrayList;
this.logReport = logReport;
this.extentAccountList = arrayList2;
this.oemPlatform = i4;
this.isSupportDolby = i5;
this.contentType = i6;
this.safeInfo = safeInfo;
this.busiExtent = businessExtent;
}
}
@@ -0,0 +1,54 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class ResponseCommand extends JceStruct {
static byte[] cache_body;
public byte[] body;
public BusinessHead businessHead;
public ResponseHead head;
static ResponseHead cache_head = new ResponseHead();
static BusinessHead cache_businessHead = new BusinessHead();
static {
cache_body = new byte[0];
byte[] bArr = {0};
}
public ResponseCommand() {
this.head = null;
this.body = null;
this.businessHead = null;
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.head = (ResponseHead) jceInputStream.read((JceStruct) cache_head, 0, true);
this.body = jceInputStream.read(cache_body, 1, false);
this.businessHead = (BusinessHead) jceInputStream.read((JceStruct) cache_businessHead, 2, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write((JceStruct) this.head, 0);
byte[] bArr = this.body;
if (bArr != null) {
jceOutputStream.write(bArr, 1);
}
BusinessHead businessHead = this.businessHead;
if (businessHead != null) {
jceOutputStream.write((JceStruct) businessHead, 2);
}
}
public ResponseCommand(ResponseHead responseHead, byte[] bArr, BusinessHead businessHead) {
this.head = null;
this.body = null;
this.businessHead = null;
this.head = responseHead;
this.body = bArr;
this.businessHead = businessHead;
}
}
@@ -0,0 +1,46 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class ResponseHead extends JceStruct {
public int cmdId;
public int errCode;
public int requestId;
public String sUserid;
public ResponseHead() {
this.requestId = 0;
this.cmdId = 0;
this.errCode = 0;
this.sUserid = "";
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.requestId = jceInputStream.read(this.requestId, 0, true);
this.cmdId = jceInputStream.read(this.cmdId, 1, true);
this.errCode = jceInputStream.read(this.errCode, 2, true);
this.sUserid = jceInputStream.readString(3, true);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write(this.requestId, 0);
jceOutputStream.write(this.cmdId, 1);
jceOutputStream.write(this.errCode, 2);
jceOutputStream.write(this.sUserid, 3);
}
public ResponseHead(int i2, int i3, int i4, String str) {
this.requestId = 0;
this.cmdId = 0;
this.errCode = 0;
this.sUserid = "";
this.requestId = i2;
this.cmdId = i3;
this.errCode = i4;
this.sUserid = str;
}
}
@@ -0,0 +1,52 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class SafeInfo extends JceStruct {
static byte[] cache_SafeResult;
public String SafeKey;
public byte[] SafeResult;
public int type;
static {
cache_SafeResult = new byte[0];
byte[] bArr = {0};
}
public SafeInfo() {
this.type = 0;
this.SafeKey = "";
this.SafeResult = null;
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.type = jceInputStream.read(this.type, 0, false);
this.SafeKey = jceInputStream.readString(1, false);
this.SafeResult = jceInputStream.read(cache_SafeResult, 2, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write(this.type, 0);
String str = this.SafeKey;
if (str != null) {
jceOutputStream.write(str, 1);
}
byte[] bArr = this.SafeResult;
if (bArr != null) {
jceOutputStream.write(bArr, 2);
}
}
public SafeInfo(int i2, String str, byte[] bArr) {
this.type = 0;
this.SafeKey = "";
this.SafeResult = null;
this.type = i2;
this.SafeKey = str;
this.SafeResult = bArr;
}
}
@@ -0,0 +1,85 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class TVProgram extends JceStruct {
public int copyRight;
public int duration;
public String epg_time;
public String id;
public String name;
public int picScreenFlag;
public long start_time_stamp;
public int timeShiftFlag;
public int videoScreenFlag;
public TVProgram() {
this.id = "";
this.start_time_stamp = 0L;
this.epg_time = "";
this.name = "";
this.copyRight = 0;
this.timeShiftFlag = 0;
this.duration = 0;
this.picScreenFlag = 0;
this.videoScreenFlag = 0;
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.id = jceInputStream.readString(0, false);
this.start_time_stamp = jceInputStream.read(this.start_time_stamp, 1, false);
this.epg_time = jceInputStream.readString(2, false);
this.name = jceInputStream.readString(3, false);
this.copyRight = jceInputStream.read(this.copyRight, 4, false);
this.timeShiftFlag = jceInputStream.read(this.timeShiftFlag, 5, false);
this.duration = jceInputStream.read(this.duration, 6, false);
this.picScreenFlag = jceInputStream.read(this.picScreenFlag, 7, false);
this.videoScreenFlag = jceInputStream.read(this.videoScreenFlag, 8, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
String str = this.id;
if (str != null) {
jceOutputStream.write(str, 0);
}
jceOutputStream.write(this.start_time_stamp, 1);
String str2 = this.epg_time;
if (str2 != null) {
jceOutputStream.write(str2, 2);
}
String str3 = this.name;
if (str3 != null) {
jceOutputStream.write(str3, 3);
}
jceOutputStream.write(this.copyRight, 4);
jceOutputStream.write(this.timeShiftFlag, 5);
jceOutputStream.write(this.duration, 6);
jceOutputStream.write(this.picScreenFlag, 7);
jceOutputStream.write(this.videoScreenFlag, 8);
}
public TVProgram(String str, long j, String str2, String str3, int i2, int i3, int i4, int i5, int i6) {
this.id = "";
this.start_time_stamp = 0L;
this.epg_time = "";
this.name = "";
this.copyRight = 0;
this.timeShiftFlag = 0;
this.duration = 0;
this.picScreenFlag = 0;
this.videoScreenFlag = 0;
this.id = str;
this.start_time_stamp = j;
this.epg_time = str2;
this.name = str3;
this.copyRight = i2;
this.timeShiftFlag = i3;
this.duration = i4;
this.picScreenFlag = i5;
this.videoScreenFlag = i6;
}
}
@@ -0,0 +1,26 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class TVTimeShiftProgramRequest extends JceStruct {
public String pid;
public TVTimeShiftProgramRequest() {
this.pid = "";
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.pid = jceInputStream.readString(0, true);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write(this.pid, 0);
}
public TVTimeShiftProgramRequest(String pid) {
this.pid = pid;
}
}
@@ -0,0 +1,58 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
import java.util.ArrayList;
import java.util.Collection;
public final class TVTimeShiftProgramResponse extends JceStruct {
static ArrayList<TVProgram> cache_programs = new ArrayList<>();
public int errcode;
public String errmsg;
public ArrayList<TVProgram> programs;
public int timeShiftFlag;
static {
cache_programs.add(new TVProgram());
}
public TVTimeShiftProgramResponse() {
this.errcode = 0;
this.errmsg = "";
this.programs = null;
this.timeShiftFlag = 0;
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.errcode = jceInputStream.read(this.errcode, 0, true);
this.errmsg = jceInputStream.readString(1, false);
this.programs = (ArrayList) jceInputStream.read(cache_programs, 2, false);
this.timeShiftFlag = jceInputStream.read(this.timeShiftFlag, 3, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write(this.errcode, 0);
String str = this.errmsg;
if (str != null) {
jceOutputStream.write(str, 1);
}
ArrayList<TVProgram> arrayList = this.programs;
if (arrayList != null) {
jceOutputStream.write((Collection) arrayList, 2);
}
jceOutputStream.write(this.timeShiftFlag, 3);
}
public TVTimeShiftProgramResponse(int i2, String str, ArrayList<TVProgram> arrayList, int i3) {
this.errcode = 0;
this.errmsg = "";
this.programs = null;
this.timeShiftFlag = 0;
this.errcode = i2;
this.errmsg = str;
this.programs = arrayList;
this.timeShiftFlag = i3;
}
}
@@ -0,0 +1,45 @@
package com.tencent.videolite.android.datamodel.cctvjce;
import com.qq.taf.jce.JceInputStream;
import com.qq.taf.jce.JceOutputStream;
import com.qq.taf.jce.JceStruct;
public final class TextInnerLayoutInfo extends JceStruct {
public int bottomPending;
public int leftPending;
public int rightPending;
public int topPending;
public TextInnerLayoutInfo() {
this.leftPending = 0;
this.topPending = 0;
this.rightPending = 0;
this.bottomPending = 0;
}
@Override // com.qq.taf.jce.JceStruct
public void readFrom(JceInputStream jceInputStream) {
this.leftPending = jceInputStream.read(this.leftPending, 0, false);
this.topPending = jceInputStream.read(this.topPending, 1, false);
this.rightPending = jceInputStream.read(this.rightPending, 2, false);
this.bottomPending = jceInputStream.read(this.bottomPending, 3, false);
}
@Override // com.qq.taf.jce.JceStruct
public void writeTo(JceOutputStream jceOutputStream) {
jceOutputStream.write(this.leftPending, 0);
jceOutputStream.write(this.topPending, 1);
jceOutputStream.write(this.rightPending, 2);
jceOutputStream.write(this.bottomPending, 3);
}
public TextInnerLayoutInfo(int i2, int i3, int i4, int i5) {
this.leftPending = 0;
this.topPending = 0;
this.rightPending = 0;
this.bottomPending = 0;
this.leftPending = i2;
this.topPending = i3;
this.rightPending = i4;
this.bottomPending = i5;
}
}
@@ -1,4 +0,0 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FF263238" />
<corners android:radius="4dp" /> <!-- Adjust the radius as needed -->
</shape>
@@ -0,0 +1,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/blur" />
<corners
android:bottomLeftRadius="4dp"
android:bottomRightRadius="4dp" />
</shape>
@@ -0,0 +1,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/blur" />
<corners
android:topLeftRadius="4dp"
android:bottomLeftRadius="4dp" />
</shape>
@@ -0,0 +1,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/blur" />
<corners
android:topRightRadius="4dp"
android:bottomRightRadius="4dp" />
</shape>
@@ -0,0 +1,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/focus" />
<corners
android:bottomLeftRadius="4dp"
android:bottomRightRadius="4dp" />
</shape>
@@ -0,0 +1,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners
android:topLeftRadius="4dp"
android:bottomLeftRadius="4dp" />
</shape>
@@ -0,0 +1,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners
android:topRightRadius="4dp"
android:bottomRightRadius="4dp" />
</shape>
@@ -1,4 +1,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners android:radius="4dp" /> <!-- Adjust the radius as needed -->
<corners
android:topLeftRadius="4dp"
android:topRightRadius="4dp" />
</shape>
+23
View File
@@ -0,0 +1,23 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="50"
android:viewportHeight="50"
android:width="62.5dp"
android:height="62.5dp">
<group
android:scaleX="0.1"
android:scaleY="-0.1"
android:translateY="50">
<path
android:pathData="M205 377c-27 -27 -40 -33 -65 -29 -30 4 -70 -19 -70 -40 0 -5 -16 -24 -35 -42 -38 -36 -44 -66 -23 -111 22 -49 51 -55 248 -55l182 0 29 29c46 46 37 106 -20 136 -20 10 -31 25 -35 49 -4 22 -20 46 -42 65 -29 26 -43 31 -85 31 -44 0 -55 -4 -84 -33zm138 2c29 -13 57 -58 57 -93 0 -17 5 -26 15 -26 24 0 65 -46 65 -71 0 -13 -10 -33 -22 -46 -21 -22 -26 -23 -205 -23 -182 0 -184 0 -208 25 -33 32 -32 70 3 105 16 15 36 40 45 54 18 27 54 35 74 15 8 -8 16 -2 29 19 9 17 27 35 38 41 28 13 80 13 109 0z"
android:fillColor="#FFEEEEEE" />
<path
android:pathData="M174 269c-10 -17 13 -36 27 -22 12 12 4 33 -11 33 -5 0 -12 -5 -16 -11z"
android:fillColor="#FFEEEEEE" />
<path
android:pathData="M294 269c-10 -17 13 -36 27 -22 12 12 4 33 -11 33 -5 0 -12 -5 -16 -11z"
android:fillColor="#FFEEEEEE" />
<path
android:pathData="M194 196c-32 -14 -50 -33 -41 -42 3 -3 20 4 38 15 43 26 75 26 118 0 34 -20 49 -20 36 1 -10 16 -69 40 -97 40 -13 -1 -37 -7 -54 -14z"
android:fillColor="#FFEEEEEE" />
</group>
</vector>
+60
View File
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/card"
android:layout_width="150dp"
android:layout_height="100dp"
android:orientation="vertical"
android:layout_gravity="center_vertical"
>
<ImageView
android:id="@+id/icon"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@drawable/rounded_white_top"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:padding="5dp" />
<LinearLayout
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="60dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/icon"
android:background="@drawable/rounded_dark_bottom"
android:orientation="vertical"
android:padding="7dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:gravity="start"
android:text="Title"
android:maxLines="1"
android:ellipsize="end"
android:textColor="#FFEEEEEE"
android:textSize="14sp" />
<TextView
android:id="@+id/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/title"
android:layout_marginTop="8dp"
android:gravity="start"
android:maxLines="1"
android:ellipsize="end"
android:text="Description"
android:textColor="#B3EEEEEE"
android:textSize="12sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
+42 -17
View File
@@ -1,19 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/channel_fragment"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="end|top"
android:layout_marginTop="20dp"
android:layout_marginEnd="50dp">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>
<FrameLayout
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/channel_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="0dp"
android:textColor="#FFEEEEEE"
android:textStyle="bold"
android:textSize="50sp" />
</FrameLayout>
<RelativeLayout
android:id="@+id/channel"
android:layout_width="90dp"
android:layout_height="60dp"
android:layout_gravity="end|top"
android:layout_marginTop="15dp"
android:layout_marginEnd="170dp"
android:gravity="end|bottom" >
<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:textColor="@color/white"
android:textStyle="bold"
android:textSize="40sp"
tools:text="99"
android:layout_alignBaseline="@+id/time"/>
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:textColor="@color/white"
android:textStyle="bold"
android:textSize="32sp"
tools:text="12:34" />
</RelativeLayout>
</FrameLayout>
</LinearLayout>
+30
View File
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/error"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black" >
<LinearLayout
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="@+id/logo"
android:src="@drawable/sad_cloud"
android:layout_width="50dp"
android:layout_height="50dp" />
<TextView
android:id="@+id/msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:textColor="#FFEEEEEE"
android:text="Message"
android:textSize="20sp" />
</LinearLayout>
</FrameLayout>
+55 -48
View File
@@ -1,53 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/info_fragment"
android:layout_width="320dp"
android:layout_height="80dp"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="20dp"
android:background="@drawable/rounded_background">
<ImageView
android:id="@+id/info_logo"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:padding="10dp" />
<LinearLayout
android:layout_width="216dp"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="100dp"
android:background="#FF263238"
android:gravity="start|center_vertical"
android:orientation="vertical"
android:padding="7dp">
>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginTop="0dp"
android:gravity="start"
android:textColor="#FFEEEEEE"
android:textSize="22sp" />
<LinearLayout
android:id="@+id/info"
android:layout_width="400dp"
android:layout_height="80dp"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="20dp"
android:orientation="horizontal">
<TextView
android:id="@+id/info_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginTop="8dp"
android:gravity="start"
android:singleLine="true"
android:textColor="#B3EEEEEE"
android:textSize="16sp" />
</LinearLayout>
<ImageView
android:id="@+id/logo"
android:layout_width="100dp"
android:layout_height="match_parent"
android:background="@drawable/rounded_white_left"
android:padding="10dp" />
<View
android:layout_width="8dp"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:background="@drawable/rounded_background2" />
</FrameLayout>
<LinearLayout
android:id="@+id/main"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_marginStart="0dp"
android:background="@drawable/rounded_dark_right"
android:gravity="start|center_vertical"
android:orientation="vertical"
android:padding="7dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:gravity="start"
android:textColor="#FFEEEEEE"
android:textSize="20sp" />
<TextView
android:id="@+id/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginTop="8dp"
android:gravity="start"
android:singleLine="true"
android:textColor="#B3EEEEEE"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
</LinearLayout>
+21
View File
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/loading"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
>
<LinearLayout
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" >
<ProgressBar
android:id="@+id/bar"
android:layout_width="50dp"
android:layout_height="50dp"
android:indeterminateTint="@color/white"/>
</LinearLayout>
</FrameLayout>
+32
View File
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:clickable="true"
android:focusable="false"
android:gravity="center"
>
<FrameLayout
android:id="@+id/menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ScrollView
android:id="@+id/scroll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<LinearLayout
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
</FrameLayout>
</LinearLayout>
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/player_fragment"
android:id="@+id/player"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
+8 -4
View File
@@ -3,22 +3,26 @@
android:id="@+id/row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:orientation="vertical"
android:background="@android:color/transparent"
android:clickable="true"
android:focusable="false"
>
<TextView
android:id="@+id/row_header"
android:id="@+id/header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginTop="0dp"
android:layout_marginStart="10dp"
android:layout_marginStart="20dp"
android:layout_marginBottom="5dp"
android:gravity="start"
android:textColor="#FFEEEEEE"
android:textSize="22sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/row_items"
android:id="@+id/items"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</androidx.recyclerview.widget.RecyclerView>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dialog"
android:id="@+id/setting"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
@@ -8,15 +8,17 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/content"
android:layout_width="300dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="20dp"
android:paddingLeft="7dp"
android:paddingRight="7dp"
android:background="#FF263238"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:background="@drawable/rounded_dark_left"
>
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
@@ -27,9 +29,10 @@
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="当前版本: $versionName\n获取最新: https://github.com/lizongying/my-tv/releases/"
android:textSize="14sp"
/>
<LinearLayout
android:layout_width="300dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
@@ -37,7 +40,7 @@
android:id="@+id/check_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:textSize="14sp"
android:text="@string/check_version"
/>
<ProgressBar
@@ -48,33 +51,58 @@
<TextView
android:id="@+id/version_name"
android:text=""
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<Button
android:id="@+id/exit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="@string/exit"
/>
<Switch
android:id="@+id/switch_channel_reversal"
android:text="@string/title_channel_reversal"
android:layout_marginTop="10dp"
android:textSize="14sp"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Switch
android:id="@+id/switch_channel_num"
android:text="@string/title_channel_num"
android:layout_marginTop="10dp"
android:textSize="14sp"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Switch
android:id="@+id/switch_time"
android:text="@string/title_time"
android:textSize="14sp"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Switch
android:id="@+id/switch_boot_startup"
android:text="@string/title_boot_startup"
android:layout_marginTop="10dp"
android:textSize="14sp"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Switch
android:id="@+id/switch_grid"
android:text="@string/title_grid"
android:textSize="14sp"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<ImageView
android:id="@+id/appreciate"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:src="@drawable/appreciate"
android:background="@color/white" />
android:background="@drawable/rounded_white_right" />
</LinearLayout>
</FrameLayout>
-17
View File
@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/show_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
</FrameLayout>
+45
View File
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>
<FrameLayout
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:id="@+id/time"
android:layout_width="120dp"
android:layout_height="60dp"
android:layout_gravity="end|top"
android:layout_marginTop="15dp"
android:layout_marginEnd="50dp"
android:gravity="end|bottom" >
<TextView
android:id="@+id/channel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:textColor="@color/white"
android:textStyle="bold"
android:textSize="40sp"
tools:text="99"
android:layout_alignBaseline="@+id/content"/>
<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:textColor="@color/white"
android:textStyle="bold"
android:textSize="32sp"
tools:text="12:34" />
</RelativeLayout>
</FrameLayout>
</LinearLayout>
-954
View File
@@ -1,954 +0,0 @@
[
{
"id": 0,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/d57905b93540bd15f0c48230dbbbff7ee0d645ff539e38866e2d15c8b9f7dfcd.png?imageMogr2/format/webp",
"pid": "600001859",
"sid": "2000210103",
"programId": "600001859",
"needToken": false,
"mustToken": false,
"title": "CCTV1 综合",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226231/index.m3u8"
]
},
{
"id": 1,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/20115388de0207131af17eac86c33049b95d69eaff064e55653a1b941810a006.png?imageMogr2/format/webp",
"pid": "600001800",
"sid": "2000203603",
"programId": "600001800",
"needToken": true,
"mustToken": false,
"title": "CCTV2 财经",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226195/index.m3u8"
]
},
{
"id": 2,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/7b7a65c712450da3deb6ca66fbacf4f9aee00d3f20bd80eafb5ada01ec63eb3a.png?imageMogr2/format/webp",
"pid": "600001801",
"sid": "2000203803",
"programId": "600001801",
"needToken": true,
"mustToken": true,
"title": "CCTV3 综艺",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226397/index.m3u8"
]
},
{
"id": 3,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/f357e58fdbcc076a3d65e1f958c942b2e14f14342c60736ceed98b092d35356a.png?imageMogr2/format/webp",
"pid": "600001814",
"sid": "2000204803",
"programId": "600001814",
"needToken": false,
"mustToken": false,
"title": "CCTV4 中文国际",
"videoUrl": [
"http://39.134.24.161/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226191/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226191/index.m3u8"
]
},
{
"id": 4,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/0a6a7138952675983a3d854df7688557b286d59aa06166edae51506f9204d655.png?imageMogr2/format/webp",
"pid": "600001818",
"sid": "2000205103",
"programId": "600001818",
"needToken": true,
"mustToken": false,
"title": "CCTV5 体育",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226395/index.m3u8"
]
},
{
"id": 5,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/741515efda91f03f455df8a7da4ee11fa9329139c276435cf0a9e2af398d5bf2.png?imageMogr2/format/webp",
"pid": "600001802",
"sid": "2013693901",
"programId": "600001802",
"needToken": true,
"mustToken": true,
"title": "CCTV6 电影",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226393/index.m3u8"
]
},
{
"id": 6,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/b29af94e295ebdf646cefb68122c429b9cd921f498ca20d2d8070252536f9ff9.png?imageMogr2/format/webp",
"pid": "600004092",
"sid": "2000510003",
"programId": "600004092",
"needToken": true,
"mustToken": false,
"title": "CCTV7 国防军事",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226192/index.m3u8"
]
},
{
"id": 7,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/ad51de94426a0ba039e6dd6a8534ea98ecc813a6176bde87b4f18cc34d6d7590.png?imageMogr2/format/webp",
"pid": "600001803",
"sid": "2000203903",
"programId": "600001803",
"needToken": true,
"mustToken": true,
"title": "CCTV8 电视剧",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226391/index.m3u8"
]
},
{
"id": 8,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/2ed1b4deeca179d5db806bb941790f82eb92a1b7299c1c38fe027f95a5caee5e.png?imageMogr2/format/webp",
"pid": "600004078",
"sid": "2000499403",
"programId": "600004078",
"needToken": true,
"mustToken": false,
"title": "CCTV9 记录",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226197/index.m3u8"
]
},
{
"id": 9,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/aa6157ec65188cd41826e5a2f088c3d6d153205f5f6428258d12c59999e221aa.png?imageMogr2/format/webp",
"pid": "600001805",
"sid": "2000203503",
"programId": "600001805",
"needToken": true,
"mustToken": false,
"title": "CCTV10 科教",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226189/index.m3u8"
]
},
{
"id": 10,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/ed12ed7c7a1034dae4350011fe039284c5d5a836506b28c9e32e3c75299625c0.png?imageMogr2/format/webp",
"pid": "600001806",
"sid": "2000204103",
"programId": "600001806",
"needToken": true,
"mustToken": false,
"title": "CCTV11 戏曲",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226240/index.m3u8"
]
},
{
"id": 11,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/484083cffaa40df7e659565e8cb4d1cc740158a185512114167aa21fa0c59240.png?imageMogr2/format/webp",
"pid": "600001807",
"sid": "2000202603",
"programId": "600001807",
"needToken": true,
"mustToken": false,
"title": "CCTV12 社会与法",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226190/index.m3u8"
]
},
{
"id": 12,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/266da7b43c03e2312186b4a999e0f060e8f15b10d2cc2c9aa32171819254cf1a.png?imageMogr2/format/webp",
"pid": "600001811",
"sid": "2000204603",
"programId": "600001811",
"needToken": false,
"mustToken": false,
"title": "CCTV13 新闻",
"videoUrl": [
"https://live-play.cctvnews.cctv.com/cctv/merge_cctv13.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226233/index.m3u8"
]
},
{
"id": 13,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/af6b603896938dc346fbb16abfc63c12cba54b0ec9d18770a15d347d115f12d5.png?imageMogr2/format/webp",
"pid": "600001809",
"sid": "2000204403",
"programId": "600001809",
"needToken": true,
"mustToken": false,
"title": "CCTV14 少儿",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226193/index.m3u8"
]
},
{
"id": 14,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/2ceee92188ef684efe0d8b90839c4f3ad450d179dc64d59beff417059453af47.png?imageMogr2/format/webp",
"pid": "600001815",
"sid": "2000205003",
"programId": "600001815",
"needToken": true,
"mustToken": false,
"title": "CCTV15 音乐",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225785/index.m3u8"
]
},
{
"id": 15,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/53793fa7bacd3a93ff6dc5d2758418985e1f952a316c335d663b572d8bdcd74d.png?imageMogr2/format/webp",
"pid": "600098637",
"sid": "2012375003",
"programId": "600098637",
"needToken": true,
"mustToken": false,
"title": "CCTV16 奥林匹克",
"videoUrl": [
"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"
]
},
{
"id": 16,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/ddef563072f8bad2bea5b9e52674cb7b4ed50efb20c26e61994dfbdf05c1e3c0.png?imageMogr2/format/webp",
"pid": "600001810",
"sid": "2000204203",
"programId": "600001810",
"needToken": true,
"mustToken": false,
"title": "CCTV17 农业农村",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226198/index.m3u8"
]
},
{
"id": 17,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/649ad76a90bfef55b05db9fe52e006487280f619089099d5dc971e387fc6eff0.png?imageMogr2/format/webp",
"pid": "600001817",
"sid": "2000204503",
"programId": "600001817",
"needToken": true,
"mustToken": false,
"title": "CCTV5+ 体育赛事",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226221/index.m3u8"
]
},
{
"id": 18,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/3e9d06fd7244d950df5838750f1c6ac3456e172b51caca2c16d2282125b111e8.png?imageMogr2/format/webp",
"pid": "600002264",
"sid": "2000266303",
"programId": "600002264",
"needToken": true,
"mustToken": false,
"title": "CCTV4K 超高清",
"videoUrl": [
""
]
},
{
"id": 19,
"videoIndex": 0,
"channel": "央视",
"logo": "",
"pid": "600156816",
"sid": "2020603421",
"programId": "",
"needToken": false,
"mustToken": false,
"title": "CCTV8K 超高清",
"videoUrl": [
""
]
},
{
"id": 20,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/4d549e53e6d0f632d5a633d1945280797b153e588f919221a07faa869812cc89.png?imageMogr2/format/webp",
"pid": "600099658",
"sid": "2012513603",
"programId": "600099658",
"needToken": true,
"mustToken": true,
"title": "风云剧场",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226950/index.m3u8"
]
},
{
"id": 21,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/a556bd7d93ce65e18f243a8892b5604f4faa994a4897315914216a710a706208.png?imageMogr2/format/webp",
"pid": "600099655",
"sid": "2012514403",
"programId": "600099655",
"needToken": true,
"mustToken": true,
"title": "第一剧场",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226959/index.m3u8"
]
},
{
"id": 22,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/5661bd04fecdb6e899f801147a22ab5d3a475bf2b62e30aec2c0023190ebc9b1.png?imageMogr2/format/webp",
"pid": "600099620",
"sid": "2012511203",
"programId": "600099620",
"needToken": true,
"mustToken": true,
"title": "怀旧剧场",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226972/index.m3u8"
]
},
{
"id": 23,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/bb3c6c9e145d698137f5bb64a582021a01b51344b929003630eb769ea65832a9.png?imageMogr2/format/webp",
"pid": "600099637",
"sid": "2012513303",
"programId": "600099637",
"needToken": true,
"mustToken": true,
"title": "世界地理",
"videoUrl": [
""
]
},
{
"id": 24,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/bbf1d024c5228b8dd128b0e3cb1717d173fab4ee84c3a4c8a57b1a215362ca3b.png?imageMogr2/format/webp",
"pid": "600099660",
"sid": "2012514103",
"programId": "600099660",
"needToken": true,
"mustToken": true,
"title": "风云音乐",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226953/index.m3u8"
]
},
{
"id": 25,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/4c6b6a6d3839889f34d33db3c2f80233b26b74d3489b393487635f8704e70796.png?imageMogr2/format/webp",
"pid": "600099649",
"sid": "2012513403",
"programId": "600099649",
"needToken": true,
"mustToken": true,
"title": "兵器科技",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226975/index.m3u8"
]
},
{
"id": 26,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/cd1e2bb52b06a991de168733e5ff0f1d85adc8042d40c8f393f723543e5dd08a.png?imageMogr2/format/webp",
"pid": "600099636",
"sid": "2012514203",
"programId": "600099636",
"needToken": true,
"mustToken": true,
"title": "风云足球",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226984/index.m3u8"
]
},
{
"id": 27,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/cdd1b31ede7a5ad049ed53d9a072422f829e72dd062ed2c19e077fdd01699071.png?imageMogr2/format/webp",
"pid": "600099659",
"sid": "2012512503",
"programId": "600099659",
"needToken": true,
"mustToken": true,
"title": "高尔夫网球",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226978/index.m3u8"
]
},
{
"id": 28,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/fa28955ce8b2539d728bf4c6a13a46ff57ad76eae46627f7bcfb1ed8a613d3fc.png?imageMogr2/format/webp",
"pid": "600099650",
"sid": "2012513903",
"programId": "600099650",
"needToken": true,
"mustToken": true,
"title": "女性时尚",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226969/index.m3u8"
]
},
{
"id": 29,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/14ac5ce40482cacd3d4b37435222bfe86af2b452a2f04ecbfc1d13d76edd7c57.png?imageMogr2/format/webp",
"pid": "600099653",
"sid": "2012513803",
"programId": "600099653",
"needToken": true,
"mustToken": true,
"title": "央视文化精品",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226981/index.m3u8"
]
},
{
"id": 30,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/10e14a92478011aa6c3c8562e62127f3b1908e29fcd78e4b2b24b9e6d3ec2fbc.png?imageMogr2/format/webp",
"pid": "600099652",
"sid": "2012513703",
"programId": "600099652",
"needToken": true,
"mustToken": true,
"title": "央视台球",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226956/index.m3u8"
]
},
{
"id": 31,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/244d72c0eb1615ed7d51c2f5db5a67f306aa3f58c05bc2d34de3aa7e956dc8c9.png?imageMogr2/format/webp",
"pid": "600099656",
"sid": "2012514003",
"programId": "600099656",
"needToken": true,
"mustToken": true,
"title": "电视指南",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226987/index.m3u8"
]
},
{
"id": 32,
"videoIndex": 0,
"channel": "央视",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/54a6863656fdfd8f803be193ddf22441c5000a108833889816fd2d8911715ce8.png?imageMogr2/format/webp",
"pid": "600099651",
"sid": "2012513503",
"programId": "600099651",
"needToken": true,
"mustToken": true,
"title": "卫生健康",
"videoUrl": [
""
]
},
{
"id": 33,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/9bd372ca292a82ce3aa08772b07efc4af1f85c21d1f268ea33440c49e9a0a488.png?imageMogr2/format/webp",
"pid": "600002483",
"sid": "2000292403",
"programId": "600002483",
"needToken": true,
"mustToken": false,
"title": "东方卫视",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226217/index.m3u8"
]
},
{
"id": 34,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/4120e89d3079d08aa17d382f69a2308ec70839b278367763c34a34666c75cb88.png?imageMogr2/format/webp",
"pid": "600002475",
"sid": "2000296203",
"programId": "600002475",
"needToken": true,
"mustToken": false,
"title": "湖南卫视",
"videoUrl": [
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226307/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226211/index.m3u8"
]
},
{
"id": 35,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/7a6be5a2bb1dc53a945c016ff1f525dc4a84c51db371c15c89aa55404b0ba784.png?imageMogr2/format/webp",
"pid": "600002508",
"sid": "2000294503",
"programId": "600002508",
"needToken": true,
"mustToken": false,
"title": "湖北卫视",
"videoUrl": [
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226477/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226194/index.m3u8"
]
},
{
"id": 36,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/ac4ed6058a87c101ae7147ebc38905d0cae047fb73fd277ee5049b84f52bda36.png?imageMogr2/format/webp",
"pid": "600002505",
"sid": "2000281303",
"programId": "600002505",
"needToken": true,
"mustToken": false,
"title": "辽宁卫视",
"videoUrl": [
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226546/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226201/index.m3u8"
]
},
{
"id": 37,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/380ad685c0c1d5b2c902246b8d2df6d3f9b45e2837abcfe493075bbded597a31.png?imageMogr2/format/webp",
"pid": "600002521",
"sid": "2000295603",
"programId": "600002521",
"needToken": true,
"mustToken": false,
"title": "江苏卫视",
"videoUrl": [
"http://39.134.24.166/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226200/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226200/index.m3u8"
]
},
{
"id": 38,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/3c760d0d00463855890e8a1864ea4a6b6dd66b90c29b4ac714a4b17c16519871.png?imageMogr2/format/webp",
"pid": "600002503",
"sid": "2000294103",
"programId": "600002503",
"needToken": true,
"mustToken": false,
"title": "江西卫视",
"videoUrl": [
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226344/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225764/index.m3u8"
]
},
{
"id": 39,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/22d403f07a7cf5410b3ad3ddb65a11aa229a32475fac213f5344c9f0ec330ca1.png?imageMogr2/format/webp",
"pid": "600002513",
"sid": "2000294803",
"programId": "600002513",
"needToken": true,
"mustToken": false,
"title": "山东卫视",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226209/index.m3u8"
]
},
{
"id": 40,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/28886880a4dc0f06fb7e0a528a1def0591d61a65870e29176ede0cc92033bbfd.png?imageMogr2/format/webp",
"pid": "600002485",
"sid": "2000292703",
"programId": "600002485",
"needToken": true,
"mustToken": false,
"title": "广东卫视",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226216/index.m3u8"
]
},
{
"id": 41,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/54b7e97cb816bb223fe05f3fc44da2c7820eb66e8550c19d23100f2c414ecc38.png?imageMogr2/format/webp",
"pid": "600002509",
"sid": "2000294203",
"programId": "600002509",
"needToken": true,
"mustToken": false,
"title": "广西卫视",
"videoUrl": [
"http://live.gxrb.com.cn/tv/gxtvlive03/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225770/index.m3u8"
]
},
{
"id": 42,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/657651f411de2673d1770d9a78b44c1265704f7468cc41d4be7f51d630768494.png?imageMogr2/format/webp",
"pid": "600002531",
"sid": "2000297803",
"programId": "600002531",
"needToken": true,
"mustToken": false,
"title": "重庆卫视",
"videoUrl": [
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226409/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226202/index.m3u8"
]
},
{
"id": 43,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/74925962148a6d31c85808b6cd4e444c2a54bab393d2c5fc85e960b50e22fa86.png?imageMogr2/format/webp",
"pid": "600002525",
"sid": "2000296103",
"programId": "600002525",
"needToken": true,
"mustToken": false,
"title": "河南卫视",
"videoUrl": [
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226480/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225767/index.m3u8"
]
},
{
"id": 44,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/d545becdc81c60197b08c7f47380705e4665ed3fe55efc8b855e486f6e655378.png?imageMogr2/format/webp",
"pid": "600002493",
"sid": "2000293403",
"programId": "600002493",
"needToken": true,
"mustToken": false,
"title": "河北卫视",
"videoUrl": [
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226406/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225750/index.m3u8"
]
},
{
"id": 45,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/4eb45f4781d33d872af027dc01c941559aab55667dd99cc5c22bef7037807b13.png?imageMogr2/format/webp",
"pid": "600002490",
"sid": "2000293303",
"programId": "600002490",
"needToken": true,
"mustToken": false,
"title": "贵州卫视",
"videoUrl": [
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226474/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225793/index.m3u8"
]
},
{
"id": 46,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/f4f23633c578beea49a3841d88d3490100f029ee349059fa532869db889872c5.png?imageMogr2/format/webp",
"pid": "600002309",
"sid": "2000272103",
"programId": "600002309",
"needToken": true,
"mustToken": false,
"title": "北京卫视",
"videoUrl": [
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221225728/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226222/index.m3u8"
]
},
{
"id": 47,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/d8273ae9be698ce2db21f5b886ecac95a73429593f93713c60ed8c12c38bf0d3.png?imageMogr2/format/webp",
"pid": "600002498",
"sid": "2000293903",
"programId": "600002498",
"needToken": true,
"mustToken": false,
"title": "黑龙江卫视",
"videoUrl": [
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226327/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226215/index.m3u8"
]
},
{
"id": 48,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/a66c836bd98ba3e41a2e9a570d4b9c50dedc6839e9de333e2e78212ad505f37e.png?imageMogr2/format/webp",
"pid": "600002520",
"sid": "2000295503",
"programId": "600002520",
"needToken": true,
"mustToken": false,
"title": "浙江卫视",
"videoUrl": [
"http://hw-m-l.cztv.com/channels/lantian/channel01/1080p.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226199/index.m3u8"
]
},
{
"id": 49,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/f35fa04b51b1ee4984b03578b65403570868ebca03c6c01e11b097f999a58d9b.png?imageMogr2/format/webp",
"pid": "600002532",
"sid": "2000298003",
"programId": "600002532",
"needToken": true,
"mustToken": false,
"title": "安徽卫视",
"videoUrl": [
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226391/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226203/index.m3u8"
]
},
{
"id": 50,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/d59fec04c902e3581c617136d02d4b9b8c4cbe64272781ddd3525e80c823edb7.png?imageMogr2/format/webp",
"pid": "600002481",
"sid": "2000292203",
"programId": "600002481",
"needToken": true,
"mustToken": false,
"title": "深圳卫视",
"videoUrl": [
"http://39.134.24.166/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226205/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221226205/index.m3u8"
]
},
{
"id": 51,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/3276a414ae0eaa0f116f2045cd913367967d0c7c1e978e8621ac3879436c6ed7.png?imageMogr2/format/webp",
"pid": "600002516",
"sid": "2000295003",
"programId": "600002516",
"needToken": true,
"mustToken": false,
"title": "四川卫视",
"videoUrl": [
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225768/index.m3u8",
"http://39.134.24.166/dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225768/index.m3u8"
]
},
{
"id": 52,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/3208fe6564a293c21b711333fb3edb05bb5b406cff840573c9a8d839680a1579.png?imageMogr2/format/webp",
"pid": "600002484",
"sid": "2000292503",
"programId": "600002484",
"needToken": true,
"mustToken": false,
"title": "东南卫视",
"videoUrl": [
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226341/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225766/index.m3u8"
]
},
{
"id": 53,
"videoIndex": 0,
"channel": "地方",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/6e060391fde0469801fc3d84dbf204b4f8d650d251f17d7595a6964c0bb99e81.png?imageMogr2/format/webp",
"pid": "600002506",
"sid": "2000291503",
"programId": "600002506",
"needToken": true,
"mustToken": false,
"title": "海南卫视",
"videoUrl": [
"http://ottrrs.hl.chinamobile.com/PLTV/88888888/224/3221226465/index.m3u8",
"http://dbiptv.sn.chinamobile.com/PLTV/88888890/224/3221225769/index.m3u8"
]
},
{
"id": 54,
"videoIndex": 0,
"channel": "地方",
"logo": "",
"pid": "600152137",
"sid": "2019927003",
"programId": "",
"needToken": true,
"mustToken": false,
"title": "天津卫视",
"videoUrl": [
""
]
},
{
"id": 55,
"videoIndex": 0,
"channel": "地方",
"logo": "",
"pid": "600152138",
"sid": "2019927403",
"programId": "",
"needToken": true,
"mustToken": false,
"title": "新疆卫视",
"videoUrl": [
""
]
},
{
"id": 56,
"videoIndex": 0,
"channel": "国际",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/a72dff758ca1c17cd0ecc8cedc11b893d208f409d5e6302faa0e9d298848abc3.png?imageMogr2/format/webp",
"pid": "600014550",
"sid": "2001656803",
"programId": "600014550",
"needToken": false,
"mustToken": false,
"title": "CGTN",
"videoUrl": [
"http://live.cgtn.com/1000/prog_index.m3u8"
]
},
{
"id": 57,
"videoIndex": 0,
"channel": "国际",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/a8d0046a47433d952bf6ed17062deb8bd2184ba9aec0f7781df6bf9487a3ffcf.png?imageMogr2/format/webp",
"pid": "600084704",
"sid": "2010153503",
"programId": "600084704",
"needToken": false,
"mustToken": false,
"title": "CGTN 法语频道",
"videoUrl": [
"https://livefr.cgtn.com/1000f/prog_index.m3u8"
]
},
{
"id": 58,
"videoIndex": 0,
"channel": "国际",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/bf0a820893cbaf20dd0333e27042e1ef9c8806e5b602b6a8c95af399db0bc77a.png?imageMogr2/format/webp",
"pid": "600084758",
"sid": "2010152603",
"programId": "600084758",
"needToken": false,
"mustToken": false,
"title": "CGTN 俄语频道",
"videoUrl": [
"http://liveru.cgtn.com/1000r/prog_index.m3u8"
]
},
{
"id": 59,
"videoIndex": 0,
"channel": "国际",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202306/2e44e2aa3e7a1cedf07fd0ae59fe69e86a60a2632660a006e3e9e7397b2d107e.png?imageMogr2/format/webp",
"pid": "600084782",
"sid": "2010155203",
"programId": "600084782",
"needToken": false,
"mustToken": false,
"title": "CGTN 阿拉伯语频道",
"videoUrl": [
"http://livear.cgtn.com/1000a/prog_index.m3u8"
]
},
{
"id": 60,
"videoIndex": 0,
"channel": "国际",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202309/7c337e3dbe64402ec7e4678a619a4a6d95144e42f35161181ff78e143b7cf67a.png?imageMogr2/format/webp",
"pid": "600084744",
"sid": "2010152503",
"programId": "600084744",
"needToken": false,
"mustToken": false,
"title": "CGTN 西班牙语频道",
"videoUrl": [
"http://livees.cgtn.com/500e/prog_index.m3u8",
"http://livees.cgtn.com/1000e/prog_index.m3u8"
]
},
{
"id": 61,
"videoIndex": 0,
"channel": "国际",
"logo": "https://resources.yangshipin.cn/assets/oms/image/202309/74d3ac436a7e374879578de1d87a941fbf566d39d5632b027c5097891ed32bd5.png?imageMogr2/format/webp",
"pid": "600084781",
"sid": "2010155403",
"programId": "600084781",
"needToken": false,
"mustToken": false,
"title": "CGTN 纪录频道",
"videoUrl": [
"https://livedoc.cgtn.com/500d/prog_index.m3u8"
]
}
]

Some files were not shown because too many files have changed in this diff Show More