v1.0
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
|
||||
A TikTok-style web player for Emby / Jellyfin. Experience your private media library in a whole new, immersive way.
|
||||
|
||||

|
||||
|
||||
## ✨ Features
|
||||
|
||||
- **Fluid Playback**: TikTok-style vertical scrolling for an **immersive** experience.
|
||||
|
||||
+4
-2
@@ -2,10 +2,12 @@
|
||||
|
||||
EmbyX 是一款专为 Emby / Jellyfin 打造的 Web 原生应用,完美复刻抖音·短视频沉浸式交互,让你的私人媒体库焕发全新的刷片体验。🎉
|
||||
|
||||

|
||||
|
||||
## ✨ 功能特色
|
||||
|
||||
- **流式播放**:抖音风格上下滑动,沉浸式全屏体验
|
||||
- **直接播放**:安卓最高支持 8K HEVC / AV1 不转码
|
||||
- **流式播放**:抖音操作习惯,沉浸式全屏体验
|
||||
- **直接播放**:安卓最高支持 8K AV1 不转码
|
||||
- **相册视图**:封面墙浏览,支持分页、换一批
|
||||
- **Emby 同步**:支持媒体库、播放列表、收藏夹
|
||||
- **键鼠适配**:纯按键控制,电脑、电视轻松摸鱼
|
||||
|
||||
+21
-21
@@ -4,7 +4,7 @@
|
||||
© 2026 All Rights Reserved
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
@@ -282,7 +282,8 @@
|
||||
<div class="space-y-4 bg-gray-800/40 p-4 rounded-lg border border-gray-700/50">
|
||||
<div>
|
||||
<label class="text-gray-400 text-xs block mb-1.5">Server URL</label>
|
||||
<input type="text" id="configServer" placeholder="Use HTTPS for remote connections"
|
||||
<input type="text" id="configServer"
|
||||
placeholder="Reverse proxy or Self-host EmbyX for HTTP"
|
||||
class="w-full bg-gray-900 text-white text-sm rounded px-3 py-2.5 outline-none border border-gray-700 focus:border-primary transition-colors focusable-item">
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
@@ -365,7 +366,7 @@
|
||||
|
||||
<div>
|
||||
<h4 class="text-gray-300">🔮 Playback</h4>
|
||||
<ul class="list-disc list-inside space-y-1 text-gray-400 text-xs">
|
||||
<ul class="list-disc list-inside space-y-1 text-gray-400 text-xs mt-2">
|
||||
<li>Native HTML5 player, best on modern devices.</li>
|
||||
<li>Older devices can use server transcoding.</li>
|
||||
</ul>
|
||||
@@ -409,10 +410,9 @@
|
||||
|
||||
<div>
|
||||
<h4 class="text-gray-300">🧩 Tips & Tricks</h4>
|
||||
<ul class="list-disc list-inside space-y-1 text-gray-400 text-xs">
|
||||
<li>Setup: Use a dedicated account; < 1,000 videos per library.</li>
|
||||
<li>PWA: 📲 Add to Home Screen or Install as App.</li>
|
||||
<li>Controls: Full Mouse, Keyboard support for PC & TV.</li>
|
||||
<ul class="list-disc list-inside space-y-1 text-gray-400 text-xs mt-2">
|
||||
<li>Best Practice: < 1,000 items per library</li>
|
||||
<li>PWA: 📲 Add to Home Screen or Install as App</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -500,16 +500,16 @@
|
||||
<a href="https://x.com/juneix_tse" target="_blank"
|
||||
class="flex items-center justify-center text-white bg-white/10 hover:bg-white/20 px-3 py-1.5 rounded-full transition-colors border border-white/20 text-[10px] whitespace-nowrap">
|
||||
<i data-lucide="twitter"
|
||||
class="w-3.5 h-3.5 mr-1.5 grayscale brightness-200"></i> X / Twitter</a>
|
||||
class="w-3.5 h-3.5 mr-1.5 grayscale brightness-200"></i> X • Follow</a>
|
||||
<a href="https://t.me/juneix_en" target="_blank"
|
||||
class="flex items-center justify-center text-[#26A5E4] bg-[#26A5E4]/10 hover:bg-[#26A5E4]/20 px-3 py-1.5 rounded-full transition-colors border border-[#26A5E4]/20 text-[10px] whitespace-nowrap">
|
||||
<i data-lucide="send" class="w-3.5 h-3.5 mr-1.5"></i> Telegram</a>
|
||||
<i data-lucide="send" class="w-3.5 h-3.5 mr-1.5"></i> Telegram • Channel</a>
|
||||
<a href="https://ko-fi.com/juneixtse" target="_blank"
|
||||
class="flex items-center justify-center text-[#FF5E5B] bg-[#FF5E5B]/10 hover:bg-[#FF5E5B]/20 px-3 py-1.5 rounded-full transition-colors border border-[#FF5E5B]/20 text-[10px] whitespace-nowrap">
|
||||
<i data-lucide="coffee" class="w-3.5 h-3.5 mr-1.5"></i> Ko-fi</a>
|
||||
<a href="https://paypal.me/juneixtse" target="_blank"
|
||||
class="flex items-center justify-center text-[#ffc439] bg-[#ffc439]/10 hover:bg-[#ffc439]/20 px-3 py-1.5 rounded-full transition-colors border border-[#ffc439]/20 text-[10px] whitespace-nowrap">
|
||||
<i data-lucide="credit-card" class="w-3.5 h-3.5 mr-1.5"></i> PayPal</a>
|
||||
<i data-lucide="coffee" class="w-3.5 h-3.5 mr-1.5"></i> Ko-fi • Support</a>
|
||||
<a href="https://github.com/juneix/embyx" target="_blank"
|
||||
class="flex items-center justify-center text-white bg-white/10 hover:bg-white/20 px-3 py-1.5 rounded-full transition-colors border border-white/20 text-[10px] whitespace-nowrap active:scale-95">
|
||||
<i data-lucide="github" class="w-3.5 h-3.5 mr-1.5"></i> GitHub • Source</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -688,13 +688,13 @@
|
||||
body: JSON.stringify({ Username: user, Pw: pwd })
|
||||
});
|
||||
if (res.status === 401) {
|
||||
this.showToast('Auth failed: Invalid Username or Password');
|
||||
this.showToast('❌ Auth failed: Invalid Username or Password');
|
||||
return;
|
||||
} else if (res.status === 404) {
|
||||
this.showToast('Connection Failed: Check port');
|
||||
this.showToast('❌ Connection Failed: Check port');
|
||||
return;
|
||||
} else if (!res.ok) {
|
||||
this.showToast(`Connection Failed ${res.status}. Check Emby logs.`);
|
||||
this.showToast('❌ Connection Failed ' + res.status + '. Check Emby logs.');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -724,7 +724,7 @@
|
||||
this.toggleModal('profilePage', false);
|
||||
this.fetchVideos();
|
||||
} else {
|
||||
this.showToast('Auth failed: Invalid Username or Password');
|
||||
this.showToast('❌ Auth failed: Invalid Username or Password');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('saveConfig error:', e);
|
||||
@@ -732,11 +732,11 @@
|
||||
const isHttps = location.protocol === 'https:';
|
||||
const targetHttp = server.startsWith('http:');
|
||||
if (isHttps && targetHttp) {
|
||||
this.showToast('Blocked: HTTP Emby not allowed from HTTPS page');
|
||||
this.showToast('❌ Blocked: Mixed Content (HTTPS -> HTTP)');
|
||||
} else if (msg.includes('Failed to fetch') || msg.includes('NetworkError') || msg.includes('ERR_CONNECTION')) {
|
||||
this.showToast('Cannot connect to server');
|
||||
this.showToast('❌ Cannot connect to server');
|
||||
} else {
|
||||
this.showToast('Connection Failed:' + (msg || 'Unknown error'));
|
||||
this.showToast('❌ Connection Failed: ' + (msg || 'Unknown error'));
|
||||
}
|
||||
} finally {
|
||||
this.toggleLoading(false);
|
||||
@@ -1822,7 +1822,7 @@
|
||||
<span class="col-span-2 text-gray-200 font-mono">${fileSizeStr}</span>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-2 py-2 items-center">
|
||||
<span class="text-gray-500 text-right">Playback Policy</span>
|
||||
<span class="text-gray-500 text-right">Playback</span>
|
||||
<span class="col-span-2 text-gray-200">${transcodeState}</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 145 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 146 KiB |
+31
-23
@@ -299,7 +299,7 @@
|
||||
<div class="space-y-4 bg-gray-800/40 p-4 rounded-lg border border-gray-700/50">
|
||||
<div>
|
||||
<label class="text-gray-400 text-xs block mb-1.5">服务器地址</label>
|
||||
<input type="text" id="configServer" placeholder="非局域网请使用 HTTPS"
|
||||
<input type="text" id="configServer" placeholder="HTTP 访问可反代或自建 EmbyX"
|
||||
class="w-full bg-gray-900 text-white text-sm rounded px-3 py-2.5 outline-none border border-gray-700 focus:border-primary transition-colors focusable-item">
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
@@ -383,9 +383,9 @@
|
||||
|
||||
<div>
|
||||
<h4 class="text-gray-300">🔮 播放性能</h4>
|
||||
<ul class="list-disc list-inside space-y-1 text-gray-400 text-xs">
|
||||
<ul class="list-disc list-inside space-y-1 text-gray-400 text-xs mt-2">
|
||||
<li>原生 HTML5 播放器,新设备体验最佳</li>
|
||||
<li>老设备需服务器转码,<del>不如放到**上回收了(没打钱</del>😂</li>
|
||||
<li>老设备需服务器转码,<del>不如放到**上回收(没打钱</del>😂</li>
|
||||
</ul>
|
||||
<div class="bg-black/40 rounded-lg overflow-hidden border border-gray-700/50 mt-3">
|
||||
<table class="w-full text-center text-[11px] leading-tight border-collapse">
|
||||
@@ -423,10 +423,9 @@
|
||||
|
||||
<div>
|
||||
<h4 class="text-gray-300">🧩 使用技巧</h4>
|
||||
<ul class="list-disc list-inside space-y-1 text-gray-400 text-xs">
|
||||
<li>配置建议:新建专用账号,每个媒体库 < 1000 个视频</li>
|
||||
<ul class="list-disc list-inside space-y-1 text-gray-400 text-xs mt-2">
|
||||
<li>配置建议:每个媒体库 < 1000 个视频</li>
|
||||
<li>PWA应用:📲 添加到主屏幕/作为应用安装</li>
|
||||
<li>键鼠适配:纯按键控制,电脑、电视轻松摸鱼</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -502,16 +501,25 @@
|
||||
|
||||
<div>
|
||||
<h4 class="text-gray-300">🚀 交流与支持</h4>
|
||||
<ul class="list-disc list-inside space-y-1 text-gray-400 text-xs mt-3">
|
||||
<li><span class="text-gray-300 font-medium">打赏鼓励:</span>支持我开发更多有趣应用</li>
|
||||
<li><span class="text-gray-300 font-medium">互动群聊:</span>加入<a
|
||||
href="mqqapi://card/show_pslcard?src_type=internal&version=1&uin=646913307&card_type=group&source=qrcode"
|
||||
class="text-primary hover:underline">💬QQ 群</a>可在线催更</li>
|
||||
<li><span class="text-gray-300 font-medium">更多内容:</span>访问➡️<a
|
||||
href="https://5nav.eu.org" target="_blank"
|
||||
class="text-primary hover:underline">谢週五の藏经阁</a></li>
|
||||
</ul>
|
||||
<div class="flex justify-center space-x-3 mt-4">
|
||||
<p class="text-gray-400 text-xs mt-2">💬 欢迎转发分享本项目,关注社媒动态、加群催更互动!</p>
|
||||
<!-- 胶囊按钮组:社区 & 开源 -->
|
||||
<div class="grid grid-cols-2 gap-2 mt-3">
|
||||
<a href="https://space.bilibili.com/765334/" target="_blank"
|
||||
class="flex items-center justify-center text-[#FB7299] bg-[#FB7299]/10 hover:bg-[#FB7299]/20 px-3 py-1.5 rounded-full transition-colors border border-[#FB7299]/20 text-[10px] whitespace-nowrap active:scale-95">
|
||||
<i data-lucide="tv-2" class="w-3.5 h-3.5 mr-1.5"></i> B 站·教程</a>
|
||||
<a href="https://xhslink.com/m/XSWtx7YRfI" target="_blank"
|
||||
class="flex items-center justify-center text-[#FF2442] bg-[#FF2442]/10 hover:bg-[#FF2442]/20 px-3 py-1.5 rounded-full transition-colors border border-[#FF2442]/20 text-[10px] whitespace-nowrap active:scale-95">
|
||||
<i data-lucide="book-open" class="w-3.5 h-3.5 mr-1.5"></i> 小红书·攻略</a>
|
||||
<a href="mqqapi://card/show_pslcard?src_type=internal&version=1&uin=646913307&card_type=group&source=qrcode"
|
||||
class="flex items-center justify-center text-[#12B7F5] bg-[#12B7F5]/10 hover:bg-[#12B7F5]/20 px-3 py-1.5 rounded-full transition-colors border border-[#12B7F5]/20 text-[10px] whitespace-nowrap active:scale-95">
|
||||
<i data-lucide="message-circle" class="w-3.5 h-3.5 mr-1.5"></i> QQ 群·催更</a>
|
||||
<a href="https://github.com/juneix/embyx" target="_blank"
|
||||
class="flex items-center justify-center text-white bg-white/10 hover:bg-white/20 px-3 py-1.5 rounded-full transition-colors border border-white/20 text-[10px] whitespace-nowrap active:scale-95">
|
||||
<i data-lucide="github" class="w-3.5 h-3.5 mr-1.5"></i> GitHub · 开源</a>
|
||||
</div>
|
||||
<!-- 打赏区 -->
|
||||
<p class="text-gray-400 text-xs mt-4 mb-2">☕ 打赏鼓励,支持我开发更多有趣应用~</p>
|
||||
<div class="flex justify-center space-x-3">
|
||||
<a href="weixin://profile/gh_86f7c0a73738">
|
||||
<div class="flex flex-col items-center">
|
||||
<img src="wechat.webp" alt="微信" class="w-24 h-24 object-cover rounded">
|
||||
@@ -722,13 +730,13 @@
|
||||
});
|
||||
// 先按状态码分流,再尝试解析 JSON(避免非 JSON 响应体导致 json() 报错)
|
||||
if (res.status === 401) {
|
||||
this.showToast('认证失败:用户名或密码错误');
|
||||
this.showToast('❌认证失败:用户名或密码错误');
|
||||
return;
|
||||
} else if (res.status === 404) {
|
||||
this.showToast('连接失败:请检查端口号');
|
||||
this.showToast('❌连接失败:请检查端口号');
|
||||
return;
|
||||
} else if (!res.ok) {
|
||||
this.showToast(`连接失败 ${res.status},请检查 Emby 日志`);
|
||||
this.showToast('❌连接失败 ' + res.status + ',请检查 Emby 日志');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -760,7 +768,7 @@
|
||||
this.toggleModal('profilePage', false);
|
||||
this.fetchVideos();
|
||||
} else {
|
||||
this.showToast('认证失败:用户名或密码错误');
|
||||
this.showToast('❌ 认证失败:用户名或密码错误');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('saveConfig error:', e);
|
||||
@@ -770,11 +778,11 @@
|
||||
const targetHttp = server.startsWith('http:');
|
||||
if (isHttps && targetHttp) {
|
||||
// HTTPS 页面请求 HTTP Emby 会被浏览器拦截(Mixed Content)
|
||||
this.showToast('请求被拦截:非局域网不允许 http 协议');
|
||||
this.showToast('❌ 连接失败:请求被拦截 (HTTPS -> HTTP)');
|
||||
} else if (msg.includes('Failed to fetch') || msg.includes('NetworkError') || msg.includes('ERR_CONNECTION')) {
|
||||
this.showToast('无法连接服务器');
|
||||
this.showToast('❌ 无法连接服务器');
|
||||
} else {
|
||||
this.showToast('连接失败:' + (msg || '未知错误'));
|
||||
this.showToast('❌ 连接失败:' + (msg || '未知错误'));
|
||||
}
|
||||
} finally {
|
||||
this.toggleLoading(false);
|
||||
|
||||
Reference in New Issue
Block a user