diff --git a/README.md b/README.md index 45b0438..e4c0971 100644 --- a/README.md +++ b/README.md @@ -6,47 +6,24 @@ - 频道 [t.me/uzvideoplay](https://t.me/uzvideoplay) - 群组 [t.me/uzVideoApp](https://t.me/uzVideoApp) -- 下载 [123 云盘](https://www.123865.com/s/J0HtVv-QUUxA) -### 扩展仓库 +### 扩展仓库,编写扩展 https://github.com/YYDS678/uzVideo-extensions -### 视频源扩展 +### 将资源内置包内 -> 添加方式 +1. 将 `.ipa` `.apk` `.msix` 后缀改为 `.zip` 使用加压软件解压 +2. 找到 `uzAio.zip` -uz 影视 -> 设置 -> 数据管理 -> 视频源 -> 小齿轮 -> 添加源列表 -> 输入链接 -> 确定 + 1. iOS `/Payload/Runner.app/Frameworks/App.framework/flutter_assets/uzAio/uzAio.zip` + 2. Android `/assets/flutter_assets/uzAio/uzAio.zip` + 3. Win `/data/flutter_assets/uzAio/uzAio.zip` -[大佬扩展源](https://github.moeyy.xyz/https://raw.githubusercontent.com/Yswag/uzVideo/main/js/spider_sources.json) +3. 准备自己的源文件可在 `env.json` 直接将环境变量填写完整 +4. 将自己的源文件命名为 `uzAio.zip` 替换第二部找到的 `uzAio.zip` +5. 将 第一步 解压后的文件重新压缩,并改为之前的后缀 +6. 安装后,打开 app 设置 -> 数据管理 -> + -> 读取应用内文件 -[视频源](https://github.moeyy.xyz/https://raw.githubusercontent.com/YYDS678/uzVideo/main/video_sources_default.json) - -[色色源](https://github.moeyy.xyz/https://raw.githubusercontent.com/YYDS678/uzVideo/main/video_sources_sese.json) - -### 直播 - -[IPTV 大佬 YanG-1989](https://github.com/YanG-1989/m3u) -⚠️ 请注意需要设置 user-agent - -[IPTV 大佬 YueChan](https://github.com/YueChan/Live) - -### 编写 uz 可执行的扩展 - -https://github.com/YYDS678/uzVideo-extensions ### 如有任何相关问题联系:[机器人](https://t.me/uzVideoAppbot) - -### 采集站源格式 - -``` -{ - "api": "采集地址", - "name": "名称", - "remark": "备注", - "noHistory": false, // *不开启*历史记录 默认false(即开启历史记录),用户可自行在 app 内修改 - "userAgent": "", // 设置播放ua,用户可自行在 app 内修改 - "isLock": false, // 是否上锁 默认false(即不上锁),用户可自行在 app 内修改 - "blockClassList": ["短剧"] // 屏蔽分类,用户可自行在 app 内修改 - } -``` diff --git a/html/help.html b/html/help.html index 15e3ada..1821a9c 100644 --- a/html/help.html +++ b/html/help.html @@ -38,7 +38,7 @@

网页添加

- 点击跳转网页,打不开需要挂梯 + 点击跳转网页,打不开需要挂梯

diff --git a/html/install.html b/html/install.html deleted file mode 100644 index 55876e2..0000000 --- a/html/install.html +++ /dev/null @@ -1,304 +0,0 @@ - - - - - - uz影视 资源添加 - - - - - - -
-

添加资源

-
- -
-
-
- - -
-
- -
以下资源收录自网络,请自行甄别。
-
- - - - diff --git a/html/policy.html b/html/policy.html new file mode 100644 index 0000000..e69de29 diff --git a/html/store/config.js b/html/store/config.js new file mode 100644 index 0000000..b7afeac --- /dev/null +++ b/html/store/config.js @@ -0,0 +1,43 @@ +// URL Schemes +export const URL_SCHEMES = { + BASE: 'uzVideo://uzVideo?action=addSub&url=', + INTENT: 'intent://uzVideo?action=addSub&url=' +}; + +// Messages +export const MESSAGES = { + COPY_SUCCESS: '复制成功', + COPY_FAIL: '复制失败,请手动复制:\n\n', + USAGE_PATH: '使用路径:uz影视 -> 设置 -> 数据管理 -> 订阅 -> +', + EMPTY_URL: '请输入资源链接', + INVALID_URL: '请输入有效的URL' +}; + +// Resource Configs +export const RESOURCE_CONFIGS = [ + { + title: 'uz影视 all in one 无代理', + description: '整合大佬们开发的资源,感谢所有大佬. Yswag wangdepeng100', + resourceUrl: 'https://raw.githubusercontent.com/YYDS678/uzVideo-extensions/refs/heads/main/uzAio.zip' + }, + { + title: 'uz影视 all in one', + description: '整合大佬们开发的资源,感谢所有大佬. Yswag wangdepeng100', + resourceUrl: 'https://github.moeyy.xyz/https://raw.githubusercontent.com/YYDS678/uzVideo-extensions/refs/heads/main/uzAio.zip' + }, + { + title: 'pv大佬 all in one', + description: 'proversion2024 大佬 all in one,感谢大佬', + resourceUrl: 'https://ghproxy.cn/https://raw.githubusercontent.com/proversion2024/uz-extensions/refs/heads/master/uzAio.json' + }, + { + title: '网盘源', + description: 'proversion2024 大佬开发,感谢大佬', + resourceUrl: 'https://ghproxy.cn/https://raw.githubusercontent.com/proversion2024/uz-extensions/refs/heads/master/vod/vod.json' + }, + { + title: '采集站', + description: '采集站资源,不需要添加太多两个够用', + resourceUrl: 'https://github.moeyy.xyz/https://raw.githubusercontent.com/YYDS678/uzVideo/main/video_sources_default.json' + } +]; \ No newline at end of file diff --git a/html/store/index.html b/html/store/index.html new file mode 100644 index 0000000..8c1236e --- /dev/null +++ b/html/store/index.html @@ -0,0 +1,38 @@ + + + + + + + uz影视 扩展商店 + + + + + + + +
+ 以下资源收录自网络,请自行甄别。 +
+
+ +
+ + + + \ No newline at end of file diff --git a/html/store/main.js b/html/store/main.js new file mode 100644 index 0000000..184121e --- /dev/null +++ b/html/store/main.js @@ -0,0 +1,141 @@ +import { URL_SCHEMES, MESSAGES, RESOURCE_CONFIGS } from './config.js'; + +// URL验证函数 +function validateUrl(url) { + try { + new URL(url); + return true; + } catch (error) { + return false; + } +} + +// 显示错误信息 +function showError(message) { + const errorEl = document.getElementById('errorMessage'); + errorEl.textContent = message; + setTimeout(() => { + errorEl.textContent = ''; + }, 3000); +} + +// 安装资源 +function installResource(isSpecial, configUrl = null) { + const urlInput = document.getElementById('customUrl'); + let url = configUrl || urlInput.value.trim(); + + if (!url) { + showError(MESSAGES.EMPTY_URL); + return; + } + + if (!validateUrl(url)) { + showError(MESSAGES.INVALID_URL); + return; + } + + const encodedUrl = encodeURIComponent(url); + const finalUrl = isSpecial + ? `${URL_SCHEMES.INTENT}${encodedUrl}#Intent;scheme=uzVideo;end` + : `${URL_SCHEMES.BASE}${encodedUrl}`; + + window.location.href = finalUrl; +} + +// 复制到剪贴板 +async function copyToClipboard(text) { + try { + if (navigator.clipboard && window.isSecureContext) { + await navigator.clipboard.writeText(text); + } else { + const textArea = document.createElement('textarea'); + textArea.value = text; + textArea.style.position = 'fixed'; + textArea.style.left = '-9999px'; + document.body.appendChild(textArea); + textArea.select(); + try { + document.execCommand('copy'); + } catch (err) { + console.error('复制失败:', err); + throw err; + } finally { + document.body.removeChild(textArea); + } + } + + alert(MESSAGES.COPY_SUCCESS + '\n' + MESSAGES.USAGE_PATH); + } catch (err) { + console.error('复制操作失败:', err); + alert(MESSAGES.COPY_FAIL + text); + } +} + +// 创建资源卡片 +function createResourceCard(config) { + const resourceGroup = document.createElement('div'); + resourceGroup.className = 'resource-group'; + resourceGroup.innerHTML = ` +
+
${config.title}
+ ${config.description ? `
${config.description}
` : ''} +
+
+ +
+ `; + return resourceGroup; +} + +// 初始化页面 +window.onload = function () { + const container = document.getElementById('resourcesContainer'); + container.style.marginTop = '20px'; + + RESOURCE_CONFIGS.forEach(config => { + const resourceCard = createResourceCard(config); + container.appendChild(resourceCard); + }); +}; + +// 初始化事件监听器 +function initializeEventListeners() { + document.addEventListener('click', (event) => { + const link = event.target.closest('a[data-action]'); + if (!link) return; + + event.preventDefault(); + const action = link.getAttribute('data-action'); + const url = link.getAttribute('data-url'); + + switch (action) { + case 'copy': + copyToClipboard(url); + break; + case 'install': + installResource(false, url); + break; + case 'help': + window.open('https://uz-video-five.vercel.app/help.html'); + break; + case 'special-install': + installResource(true, url); + break; + } + }); +} + +// 导出函数供HTML使用 +window.installResource = installResource; +window.copyToClipboard = copyToClipboard; + +// 在页面加载完成后初始化事件监听器 +window.addEventListener('load', initializeEventListeners); \ No newline at end of file diff --git a/html/store/styles.css b/html/store/styles.css new file mode 100644 index 0000000..918ffd9 --- /dev/null +++ b/html/store/styles.css @@ -0,0 +1,242 @@ +/* 基础变量定义 */ +:root { + --bg-primary: #ffffff; + --bg-secondary: #f9f9f9; + --text-primary: #333; + --text-secondary: #666; + --border-color: #ddd; + --link-color: #007bff; + --link-hover: #0056b3; + --btn-primary: #007bff; + --btn-success: #28a745; + --btn-warning: #ffc107; + --btn-secondary: #6c757d; + --shadow-color: rgba(0, 0, 0, 0.1); +} + +/* 暗色主题 */ +@media (prefers-color-scheme: dark) { + :root { + --bg-primary: #1a1a1a; + --bg-secondary: #2d2d2d; + --text-primary: #e0e0e0; + --text-secondary: #a0a0a0; + --border-color: #404040; + --link-color: #4da3ff; + --link-hover: #80bdff; + --btn-primary: #4da3ff; + --btn-success: #3dae60; + --btn-warning: #ffd43b; + --btn-secondary: #8c8c8c; + --shadow-color: rgba(0, 0, 0, 0.3); + } +} + +/* 基础样式 */ +body { + background-color: var(--bg-primary); + color: var(--text-primary); + font-family: Arial, sans-serif; + max-width: 600px; + margin: 0 auto; + padding: 20px; +} + +a { + color: var(--link-color); + text-decoration: none; +} + +/* 页面头部 */ +.page-header { + text-align: center; + margin-bottom: 20px; +} + +.page-title { + font-size: 1.5em; + font-weight: bold; + color: var(--text-primary); + margin-bottom: 10px; +} + +.page-description { + color: var(--text-secondary); + font-size: 0.9em; + line-height: 1.6; +} + +/* 资源卡片 */ +.resource-group { + margin-bottom: 15px; + padding: 10px; + border: 1px solid var(--border-color); + border-radius: 5px; + display: flex; + flex-direction: column; + background-color: var(--bg-secondary); +} + +.resource-header { + display: flex; + flex-direction: column; + margin-bottom: 10px; +} + +.resource-title { + font-weight: bold; + margin-bottom: 5px; +} + +.resource-description { + color: var(--text-secondary); + margin-bottom: 10px; + font-size: 0.9em; +} + +/* 按钮样式 */ +.button-row { + display: flex; + justify-content: flex-end; + align-items: center; + gap: 10px; +} + +.btn { + padding: 8px 15px; + background-color: var(--btn-primary); + color: white; + text-decoration: none; + border-radius: 4px; + border: none; + cursor: pointer; + flex-shrink: 0; + min-width: 70px; + text-align: center; +} + +.copy-btn { + background-color: var(--btn-success); +} + +.help-btn { + background-color: var(--btn-warning); +} + +/* 响应式布局 */ +@media (min-width: 768px) { + body { + max-width: 1200px; + } + + #resourcesContainer { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); + gap: 20px; + } +} + +@media (max-width: 767px) { + #resourcesContainer { + display: grid; + grid-template-columns: 1fr; + gap: 15px; + } +} + +/* 下拉菜单 */ +.dropdown { + position: relative; + display: inline-block; +} + +.dropdown-btn { + padding: 8px 16px; + background-color: var(--btn-primary); + color: white; + border: none; + border-radius: 6px; + cursor: pointer; + font-size: 0.9em; + min-width: 90px; + position: relative; + z-index: 2; + transition: all 0.2s ease; + box-shadow: 0 2px 4px var(--shadow-color); +} + +.dropdown-content { + position: absolute; + right: 100%; + top: 0; + background-color: var(--bg-secondary); + min-width: 160px; + box-shadow: 0 4px 16px var(--shadow-color); + z-index: 1; + border-radius: 8px; + border: 1px solid var(--border-color); + margin-right: 10px; + opacity: 0; + visibility: hidden; + transform: translateX(15px); + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + display: flex; + flex-direction: row-reverse; +} + +.dropdown-content a { + color: var(--text-primary); + padding: 10px 16px; + text-decoration: none; + display: block; + transition: all 0.2s ease; + white-space: nowrap; + font-size: 0.95em; + border-radius: 4px; + margin: 2px; +} + +.dropdown-content a:hover { + background-color: var(--bg-primary); + transform: translateX(-3px); + color: var(--link-color); +} + +.dropdown:hover .dropdown-content { + opacity: 1; + visibility: visible; + transform: translateX(0); +} + +.dropdown:hover .dropdown-btn { + background-color: var(--link-hover); + transform: scale(1.05); + box-shadow: 0 4px 8px var(--shadow-color); +} + +/* 移动端下拉菜单适配 */ +@media (max-width: 767px) { + .dropdown-content { + position: absolute; + right: 0; + top: 100%; + margin-top: 8px; + margin-right: 0; + width: auto; + min-width: 200px; + flex-direction: row; + justify-content: space-around; + padding: 8px; + } + + .dropdown-content a { + padding: 8px 12px; + text-align: center; + flex: 1; + margin: 0 4px; + } + + .dropdown-content a:hover { + transform: translateY(-2px); + } +} \ No newline at end of file