新增桶权限选择

This commit is contained in:
CN-JS-HuiBai
2026-04-02 19:32:26 +08:00
parent 2491988d23
commit f991125923
5 changed files with 158 additions and 18 deletions

View File

@@ -129,6 +129,24 @@ header p {
box-shadow: 0 20px 40px rgba(148, 163, 184, 0.15);
}
.top-banner {
background: rgba(255, 255, 255, 0.08);
border: 1px solid var(--panel-border);
border-radius: 16px;
padding: 1rem 1.25rem;
margin-bottom: 1.5rem;
color: var(--text-primary);
font-size: 1.25rem;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
}
.top-banner.hidden {
display: none;
}
.section-header {
display: flex;
justify-content: space-between;
@@ -157,6 +175,39 @@ header p {
margin-bottom: 1rem;
}
.credentials-panel {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
margin-bottom: 1rem;
}
.credential-field {
display: flex;
flex-direction: column;
min-width: 180px;
flex: 1 1 180px;
}
.credential-field label {
color: var(--text-secondary);
font-size: 0.95rem;
margin-bottom: 0.35rem;
}
.credential-field input {
background: rgba(255, 255, 255, 0.08);
color: var(--text-primary);
border: 1px solid var(--panel-border);
border-radius: 10px;
padding: 0.5rem 0.75rem;
outline: none;
}
.credential-field input:focus {
border-color: var(--accent);
}
.codec-panel label {
color: var(--text-secondary);
font-size: 0.95rem;

View File

@@ -17,10 +17,7 @@
</div>
<div class="container">
<header>
<h1>S3 Media <span>Transcoder</span></h1>
<p>Seamlessly transcode videos from AWS S3 to MP4 for browser playback</p>
</header>
<div id="top-banner" class="top-banner hidden"></div>
<main class="dashboard">
<section class="video-list-section glass-panel">
@@ -35,6 +32,16 @@
</button>
</div>
</div>
<div class="credentials-panel">
<div class="credential-field">
<label for="s3-username">Username</label>
<input id="s3-username" type="text" placeholder="Access key" autocomplete="username">
</div>
<div class="credential-field">
<label for="s3-password">Password</label>
<input id="s3-password" type="password" placeholder="Secret key" autocomplete="current-password">
</div>
</div>
<div class="codec-panel">
<label for="codec-select">编码方式:</label>
<select id="codec-select">

View File

@@ -3,6 +3,8 @@ document.addEventListener('DOMContentLoaded', () => {
const loadingSpinner = document.getElementById('loading-spinner');
const refreshBtn = document.getElementById('refresh-btn');
const resetCacheBtn = document.getElementById('reset-cache-btn');
const usernameInput = document.getElementById('s3-username');
const passwordInput = document.getElementById('s3-password');
const codecSelect = document.getElementById('codec-select');
const encoderSelect = document.getElementById('encoder-select');
const playerOverlay = document.getElementById('player-overlay');
@@ -15,6 +17,7 @@ document.addEventListener('DOMContentLoaded', () => {
const progressInfo = document.getElementById('progress-info');
const progressText = document.getElementById('progress-text');
const progressFill = document.getElementById('progress-fill');
const topBanner = document.getElementById('top-banner');
let currentPollInterval = null;
let selectedKey = null;
@@ -51,6 +54,21 @@ document.addEventListener('DOMContentLoaded', () => {
}
};
const loadConfig = async () => {
if (!topBanner) return;
try {
const res = await fetch('/api/config');
if (!res.ok) throw new Error('Failed to load config');
const data = await res.json();
const title = data.title || 'S3 Media Transcoder';
topBanner.textContent = title;
topBanner.classList.remove('hidden');
document.title = title;
} catch (err) {
console.error('Config load failed:', err);
}
};
const connectWebSocket = () => {
const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
ws = new WebSocket(`${protocol}://${window.location.host}`);
@@ -90,6 +108,20 @@ document.addEventListener('DOMContentLoaded', () => {
progressFill.style.width = '0%';
};
const getS3AuthHeaders = () => {
const headers = {};
const username = usernameInput?.value?.trim();
const password = passwordInput?.value || '';
if (username) headers['X-S3-Username'] = username;
if (password) headers['X-S3-Password'] = password;
return headers;
};
const getS3AuthPayload = () => ({
username: usernameInput?.value?.trim() || '',
password: passwordInput?.value || ''
});
const resetCache = async () => {
if (!resetCacheBtn) return;
resetCacheBtn.disabled = true;
@@ -149,7 +181,7 @@ document.addEventListener('DOMContentLoaded', () => {
videoListEl.innerHTML = '';
try {
const res = await fetch('/api/videos');
const res = await fetch('/api/videos', { headers: getS3AuthHeaders() });
if (!res.ok) throw new Error('Failed to fetch videos. Check S3 Config.');
const data = await res.json();
@@ -296,10 +328,11 @@ document.addEventListener('DOMContentLoaded', () => {
try {
const codec = codecSelect?.value || 'h264';
const encoder = encoderSelect?.value || 'software';
const authPayload = getS3AuthPayload();
const res = await fetch('/api/transcode', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ key: selectedKey, codec, encoder })
headers: { 'Content-Type': 'application/json', ...getS3AuthHeaders() },
body: JSON.stringify({ key: selectedKey, codec, encoder, ...authPayload })
});
const data = await res.json();
@@ -374,5 +407,6 @@ document.addEventListener('DOMContentLoaded', () => {
// Connect WebSocket and initial load
connectWebSocket();
loadConfig();
fetchVideos();
});