测试ucToken
This commit is contained in:
parent
3e0a943c04
commit
7826563de1
|
|
@ -0,0 +1,4 @@
|
||||||
|
kotlin version: 2.0.10
|
||||||
|
error message: The daemon has terminated unexpectedly on startup attempt #1 with error code: 0. The daemon process output:
|
||||||
|
1. Kotlin compile daemon is ready
|
||||||
|
|
||||||
|
|
@ -51,12 +51,13 @@ public class UCApi {
|
||||||
private final String saveDirName = "TV";
|
private final String saveDirName = "TV";
|
||||||
private boolean isVip = false;
|
private boolean isVip = false;
|
||||||
private final Cache cache;
|
private final Cache cache;
|
||||||
|
private final Cache tokenCache;
|
||||||
private ScheduledExecutorService service;
|
private ScheduledExecutorService service;
|
||||||
|
|
||||||
|
|
||||||
private AlertDialog dialog;
|
private AlertDialog dialog;
|
||||||
private String serviceTicket;
|
private String serviceTicket;
|
||||||
private QRCodeHandler qrCodeHandler;
|
private UCTokenHandler qrCodeHandler;
|
||||||
|
|
||||||
private Map<String, String> getHeaders() {
|
private Map<String, String> getHeaders() {
|
||||||
Map<String, String> headers = new HashMap<>();
|
Map<String, String> headers = new HashMap<>();
|
||||||
|
|
@ -82,10 +83,11 @@ public class UCApi {
|
||||||
|
|
||||||
private UCApi() {
|
private UCApi() {
|
||||||
Init.checkPermission();
|
Init.checkPermission();
|
||||||
|
qrCodeHandler = new UCTokenHandler();
|
||||||
cache = Cache.objectFrom(Path.read(getCache()));
|
cache = Cache.objectFrom(Path.read(getCache()));
|
||||||
qrCodeHandler = new QRCodeHandler();
|
tokenCache = Cache.objectFrom(Path.read(qrCodeHandler.getCache()));
|
||||||
this.cookieToken = cache.getUser().getToken();
|
|
||||||
|
this.cookieToken = tokenCache.getUser().getToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Loader {
|
private static class Loader {
|
||||||
|
|
@ -168,6 +170,7 @@ public class UCApi {
|
||||||
return Path.tv("uc");
|
return Path.tv("uc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Vod getVod(ShareData shareData) throws Exception {
|
public Vod getVod(ShareData shareData) throws Exception {
|
||||||
getShareToken(shareData);
|
getShareToken(shareData);
|
||||||
List<Item> files = new ArrayList<>();
|
List<Item> files = new ArrayList<>();
|
||||||
|
|
@ -693,7 +696,7 @@ public class UCApi {
|
||||||
this.saveFileIdCaches.put(fileId, saveFileId);
|
this.saveFileIdCaches.put(fileId, saveFileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
//token 为空,扫码登录
|
//token不为空
|
||||||
if (StringUtils.isNoneBlank(cookieToken)) {
|
if (StringUtils.isNoneBlank(cookieToken)) {
|
||||||
SpiderDebug.log("cookieToken不为空: " + cookieToken + ";开始下载");
|
SpiderDebug.log("cookieToken不为空: " + cookieToken + ";开始下载");
|
||||||
qrCodeHandler.download(cookieToken, this.saveFileIdCaches.get(fileId));
|
qrCodeHandler.download(cookieToken, this.saveFileIdCaches.get(fileId));
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import android.graphics.drawable.ColorDrawable;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import com.github.catvod.bean.uc.Cache;
|
||||||
|
import com.github.catvod.bean.uc.User;
|
||||||
import com.github.catvod.crawler.SpiderDebug;
|
import com.github.catvod.crawler.SpiderDebug;
|
||||||
import com.github.catvod.net.OkHttp;
|
import com.github.catvod.net.OkHttp;
|
||||||
import com.github.catvod.net.OkResult;
|
import com.github.catvod.net.OkResult;
|
||||||
|
|
@ -15,6 +17,7 @@ import com.github.catvod.utils.*;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
@ -25,7 +28,7 @@ import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class QRCodeHandler {
|
public class UCTokenHandler {
|
||||||
private static final String CLIENT_ID = "5acf882d27b74502b7040b0c65519aa7";
|
private static final String CLIENT_ID = "5acf882d27b74502b7040b0c65519aa7";
|
||||||
private static final String SIGN_KEY = "l3srvtd7p42l0d0x1u8d7yc8ye9kki4d";
|
private static final String SIGN_KEY = "l3srvtd7p42l0d0x1u8d7yc8ye9kki4d";
|
||||||
private static final String API_URL = "https://open-api-drive.uc.cn";
|
private static final String API_URL = "https://open-api-drive.uc.cn";
|
||||||
|
|
@ -39,8 +42,13 @@ public class QRCodeHandler {
|
||||||
|
|
||||||
private ScheduledExecutorService service;
|
private ScheduledExecutorService service;
|
||||||
private AlertDialog dialog;
|
private AlertDialog dialog;
|
||||||
|
private final Cache cache;
|
||||||
|
|
||||||
public QRCodeHandler() {
|
public File getCache() {
|
||||||
|
return Path.tv("uctoken");
|
||||||
|
}
|
||||||
|
|
||||||
|
public UCTokenHandler() {
|
||||||
addition.put("DeviceID", "07b48aaba8a739356ab8107b5e230ad4");
|
addition.put("DeviceID", "07b48aaba8a739356ab8107b5e230ad4");
|
||||||
conf.put("api", API_URL);
|
conf.put("api", API_URL);
|
||||||
conf.put("clientID", CLIENT_ID);
|
conf.put("clientID", CLIENT_ID);
|
||||||
|
|
@ -48,6 +56,7 @@ public class QRCodeHandler {
|
||||||
conf.put("appVer", "1.6.8");
|
conf.put("appVer", "1.6.8");
|
||||||
conf.put("channel", "UCTVOFFICIALWEB");
|
conf.put("channel", "UCTVOFFICIALWEB");
|
||||||
conf.put("codeApi", CODE_API_URL);
|
conf.put("codeApi", CODE_API_URL);
|
||||||
|
cache = Cache.objectFrom(Path.read(getCache()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateUUID() {
|
private String generateUUID() {
|
||||||
|
|
@ -116,7 +125,7 @@ public class QRCodeHandler {
|
||||||
}});
|
}});
|
||||||
Init.run(() -> showQRCode(qrCode));
|
Init.run(() -> showQRCode(qrCode));
|
||||||
|
|
||||||
Init.execute(() -> startService());
|
Init.execute(this::startService);
|
||||||
/*Map<String, Object> result = new HashMap<>();
|
/*Map<String, Object> result = new HashMap<>();
|
||||||
result.put("qrcode", "data:image/png;base64," + qrCode);
|
result.put("qrcode", "data:image/png;base64," + qrCode);
|
||||||
result.put("status", "NEW");*/
|
result.put("status", "NEW");*/
|
||||||
|
|
@ -132,7 +141,7 @@ public class QRCodeHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
String pathname = "/oauth/code";
|
String pathname = "/oauth/code";
|
||||||
String timestamp = String.valueOf(new Date().getTime() / 1000) + "000";
|
String timestamp = String.valueOf(new Date().getTime() / 1000 + 1) + "000";
|
||||||
String deviceID = StringUtils.isAllBlank((String) addition.get("DeviceID")) ? (String) addition.get("DeviceID") : generateDeviceID(timestamp);
|
String deviceID = StringUtils.isAllBlank((String) addition.get("DeviceID")) ? (String) addition.get("DeviceID") : generateDeviceID(timestamp);
|
||||||
String reqId = generateReqId(deviceID, timestamp);
|
String reqId = generateReqId(deviceID, timestamp);
|
||||||
String xPanToken = generateXPanToken("GET", pathname, timestamp, (String) conf.get("signKey"));
|
String xPanToken = generateXPanToken("GET", pathname, timestamp, (String) conf.get("signKey"));
|
||||||
|
|
@ -164,7 +173,7 @@ public class QRCodeHandler {
|
||||||
|
|
||||||
OkResult okResult = OkHttp.get(API_URL + pathname, params, headers);
|
OkResult okResult = OkHttp.get(API_URL + pathname, params, headers);
|
||||||
|
|
||||||
|
//扫码成功
|
||||||
if (okResult.getCode() == 200) {
|
if (okResult.getCode() == 200) {
|
||||||
JsonObject resData = Json.safeObject(okResult.getBody());
|
JsonObject resData = Json.safeObject(okResult.getBody());
|
||||||
String code = resData.get("code").getAsString();
|
String code = resData.get("code").getAsString();
|
||||||
|
|
@ -172,7 +181,7 @@ public class QRCodeHandler {
|
||||||
pathname = "/token";
|
pathname = "/token";
|
||||||
reqId = generateReqId(deviceID, timestamp);
|
reqId = generateReqId(deviceID, timestamp);
|
||||||
|
|
||||||
Map<String, Object> postData = new HashMap<>();
|
Map<String, String> postData = new HashMap<>();
|
||||||
postData.put("req_id", reqId);
|
postData.put("req_id", reqId);
|
||||||
postData.put("app_ver", (String) conf.get("appVer"));
|
postData.put("app_ver", (String) conf.get("appVer"));
|
||||||
postData.put("device_id", deviceID);
|
postData.put("device_id", deviceID);
|
||||||
|
|
@ -187,7 +196,7 @@ public class QRCodeHandler {
|
||||||
postData.put("channel", (String) conf.get("channel"));
|
postData.put("channel", (String) conf.get("channel"));
|
||||||
postData.put("code", code);
|
postData.put("code", code);
|
||||||
|
|
||||||
OkResult okResult1 = OkHttp.post(API_URL + pathname, params, headers);
|
OkResult okResult1 = OkHttp.post(conf.get("codeApi") + pathname, Json.toJson(postData), headers);
|
||||||
|
|
||||||
|
|
||||||
if (okResult1.getCode() == 200) {
|
if (okResult1.getCode() == 200) {
|
||||||
|
|
@ -195,7 +204,12 @@ public class QRCodeHandler {
|
||||||
platformStates.remove("UC_TOKEN");
|
platformStates.remove("UC_TOKEN");
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
result.put("status", "CONFIRMED");
|
result.put("status", "CONFIRMED");
|
||||||
result.put("cookie", tokenResData.get("access_token").getAsString());
|
result.put("cookie", tokenResData.get("data").getAsJsonObject().get("access_token").getAsString());
|
||||||
|
SpiderDebug.log("uc Token获取成功:" + tokenResData.get("data").getAsJsonObject().get("access_token").getAsString());
|
||||||
|
|
||||||
|
//保存到本地
|
||||||
|
cache.setUser(User.objectFrom(tokenResData.get("data").getAsJsonObject().get("access_token").getAsString()));
|
||||||
|
|
||||||
//停止检验线程,关闭弹窗
|
//停止检验线程,关闭弹窗
|
||||||
stopService();
|
stopService();
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -295,6 +309,8 @@ public class QRCodeHandler {
|
||||||
|
|
||||||
service.scheduleWithFixedDelay(() -> {
|
service.scheduleWithFixedDelay(() -> {
|
||||||
try {
|
try {
|
||||||
|
SpiderDebug.log("----checkUC_TOKENStatus中");
|
||||||
|
|
||||||
checkUC_TOKENStatus();
|
checkUC_TOKENStatus();
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package com.github.catvod.spider;
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import com.github.catvod.api.QRCodeHandler;
|
import com.github.catvod.api.UCTokenHandler;
|
||||||
import com.github.catvod.bean.Class;
|
import com.github.catvod.bean.Class;
|
||||||
import com.github.catvod.bean.Result;
|
import com.github.catvod.bean.Result;
|
||||||
import com.github.catvod.bean.Vod;
|
import com.github.catvod.bean.Vod;
|
||||||
|
|
@ -53,7 +53,7 @@ public class Introduce extends Spider {
|
||||||
|
|
||||||
//UC Token 扫码
|
//UC Token 扫码
|
||||||
if (vodId.equals("UCToken")) {
|
if (vodId.equals("UCToken")) {
|
||||||
QRCodeHandler qrCodeHandler = new QRCodeHandler();
|
UCTokenHandler qrCodeHandler = new UCTokenHandler();
|
||||||
qrCodeHandler.startUC_TOKENScan();
|
qrCodeHandler.startUC_TOKENScan();
|
||||||
}
|
}
|
||||||
Vod item = new Vod();
|
Vod item = new Vod();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
import android.app.Application;
|
||||||
|
import com.github.catvod.spider.Glod;
|
||||||
|
import com.github.catvod.spider.Init;
|
||||||
|
import com.github.catvod.spider.Introduce;
|
||||||
|
import com.github.catvod.utils.Json;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
@RunWith(RobolectricTestRunner.class)
|
||||||
|
public class IntroduceTest {
|
||||||
|
// @Mock
|
||||||
|
private Application mockContext;
|
||||||
|
|
||||||
|
private Introduce spider;
|
||||||
|
|
||||||
|
@org.junit.Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
mockContext = RuntimeEnvironment.application;
|
||||||
|
Init.init(mockContext);
|
||||||
|
spider = new Introduce();
|
||||||
|
spider.init(mockContext, "https://www.czzy.site/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void homeContent() throws Exception {
|
||||||
|
String content = spider.homeContent(true);
|
||||||
|
JsonObject map = Json.safeObject(content);
|
||||||
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
|
||||||
|
System.out.println("homeContent--" + gson.toJson(map));
|
||||||
|
|
||||||
|
//Assert.assertFalse(map.getAsJsonArray("list").isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void homeVideoContent() throws Exception {
|
||||||
|
String content = spider.homeVideoContent();
|
||||||
|
JsonObject map = Json.safeObject(content);
|
||||||
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
|
||||||
|
System.out.println("homeVideoContent--" + gson.toJson(map));
|
||||||
|
|
||||||
|
//Assert.assertFalse(map.getAsJsonArray("list").isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void categoryContent() throws Exception {
|
||||||
|
String content = spider.categoryContent("2", "2", true, new HashMap<>());
|
||||||
|
JsonObject map = Json.safeObject(content);
|
||||||
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
System.out.println("categoryContent--" + gson.toJson(map));
|
||||||
|
Assert.assertFalse(map.getAsJsonArray("list").isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void detailContent() throws Exception {
|
||||||
|
|
||||||
|
String content = spider.detailContent(Arrays.asList("UCToken"));
|
||||||
|
JsonObject map = Json.safeObject(content);
|
||||||
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
System.out.println("detailContent--" + gson.toJson(map));
|
||||||
|
Assert.assertFalse(map.getAsJsonArray("list").isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void playerContent() throws Exception {
|
||||||
|
String froms = "glod";
|
||||||
|
String urls = "1$/vod/play/126164/sid/1057548#2$/vod/play/126164/sid/1057549#3$/vod/play/126164/sid/1057735#4$/vod/play/126164/sid/1057683";
|
||||||
|
for (int i = 0; i < urls.split("\\$\\$\\$").length; i++) {
|
||||||
|
String content = spider.playerContent(froms.split("\\$\\$\\$")[i], urls.split("\\$\\$\\$")[i].split("#")[0].split("\\$")[1], new ArrayList<>());
|
||||||
|
JsonObject map = Json.safeObject(content);
|
||||||
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
System.out.println("playerContent--" + gson.toJson(map));
|
||||||
|
Assert.assertFalse(map.getAsJsonPrimitive("url").getAsString().isEmpty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void searchContent() throws Exception {
|
||||||
|
String content = spider.searchContent("红", false);
|
||||||
|
JsonObject map = Json.safeObject(content);
|
||||||
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
System.out.println("searchContent--" + gson.toJson(map));
|
||||||
|
Assert.assertFalse(map.getAsJsonArray("list").isEmpty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,44 +1,33 @@
|
||||||
package com.github.catvod.api;
|
package com.github.catvod.api;
|
||||||
|
|
||||||
import com.github.catvod.net.OkHttp;
|
|
||||||
import com.github.catvod.net.OkResult;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyMap;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class QRCodeHandlerTest {
|
public class QRCodeHandlerTest {
|
||||||
|
|
||||||
private QRCodeHandler qrCodeHandler;
|
private UCTokenHandler qrCodeHandler;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
qrCodeHandler = new QRCodeHandler();
|
qrCodeHandler = new UCTokenHandler();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStartUC_TOKENScan() throws Exception {
|
public void testStartUC_TOKENScan() throws Exception {
|
||||||
// Mock the OkHttp.get method to return a predefined OkResult
|
// Mock the OkHttp.get method to return a predefined OkResult
|
||||||
|
|
||||||
|
|
||||||
// Execute the method under test
|
// Execute the method under test
|
||||||
String result = qrCodeHandler.startUC_TOKENScan();
|
String result = qrCodeHandler.startUC_TOKENScan();
|
||||||
System.out.println(result);
|
System.out.println(result);
|
||||||
|
while(true){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Binary file not shown.
|
|
@ -1 +1 @@
|
||||||
48db9198fb3f8c6f47d31c1f349fa815
|
13f6aa4385d4a4a8bedb5c5221e447d5
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;48db9198fb3f8c6f47d31c1f349fa815",
|
"spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;13f6aa4385d4a4a8bedb5c5221e447d5",
|
||||||
"lives": [
|
"lives": [
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;48db9198fb3f8c6f47d31c1f349fa815",
|
"spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;13f6aa4385d4a4a8bedb5c5221e447d5",
|
||||||
"lives": [
|
"lives": [
|
||||||
{
|
{
|
||||||
"name": "直播ipv6",
|
"name": "直播ipv6",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;48db9198fb3f8c6f47d31c1f349fa815",
|
"spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;13f6aa4385d4a4a8bedb5c5221e447d5",
|
||||||
"lives": [
|
"lives": [
|
||||||
{
|
{
|
||||||
"name": "直播ipv6",
|
"name": "直播ipv6",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;48db9198fb3f8c6f47d31c1f349fa815",
|
"spider": "https://androidcatvodspider.netlify.app/jar/custom_spider.jar;md5;13f6aa4385d4a4a8bedb5c5221e447d5",
|
||||||
"lives": [
|
"lives": [
|
||||||
{
|
{
|
||||||
"name": "直播",
|
"name": "直播",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue