- 视频分析: MiMo 2.5 大模型直接分析 - 场景检测: AI 视觉模型识别分镜头 - 语音识别: 每个场景单独 ASR - 语音克隆: MiMo TTS 语音克隆 - 下载功能: 单文件/批量 ZIP 下载 - 系统设置: API 密钥配置 - 文件夹管理: 创建/移动/筛选 - 扁平化 UI: 简约按钮样式
280 lines
14 KiB
Plaintext
280 lines
14 KiB
Plaintext
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>拍摄素材管理</title>
|
||
<link rel="stylesheet" href="/static/style.css?v=36">
|
||
</head>
|
||
<body>
|
||
<div class="app-layout">
|
||
<!-- Left Sidebar -->
|
||
<aside class="sidebar" id="sidebar">
|
||
<div class="sidebar-header">
|
||
<span class="sidebar-logo">🎬</span>
|
||
<span class="sidebar-title">拍摄剪辑</span>
|
||
</div>
|
||
|
||
<nav class="sidebar-nav">
|
||
<div class="nav-section">
|
||
<div class="nav-item" onclick="showCreateFolderModal()" style="cursor:pointer;color:#1a73e8">
|
||
<span class="nav-icon">➕</span>
|
||
<span class="nav-label">新建文件夹</span>
|
||
</div>
|
||
<div class="nav-item active" data-filter="" onclick="filterByNav(this, 'all')">
|
||
<span class="nav-icon">📁</span>
|
||
<span class="nav-label">全部</span>
|
||
<span class="nav-count" id="countAll">0</span>
|
||
</div>
|
||
<div class="nav-item" data-filter="未分析" onclick="filterByNav(this, 'unanalyzed')">
|
||
<span class="nav-icon">🏷️</span>
|
||
<span class="nav-label">未标签</span>
|
||
<span class="nav-count" id="countUnanalyzed">0</span>
|
||
</div>
|
||
<div class="nav-item" data-filter="已分析" onclick="filterByNav(this, 'analyzed')">
|
||
<span class="nav-icon">✅</span>
|
||
<span class="nav-label">待拉片</span>
|
||
<span class="nav-count" id="countAnalyzed">0</span>
|
||
</div>
|
||
<div class="nav-item" data-filter="已剪辑" onclick="filterByNav(this, 'clipped')">
|
||
<span class="nav-icon">🎬</span>
|
||
<span class="nav-label">已拉片</span>
|
||
<span class="nav-count" id="countClipped">0</span>
|
||
</div>
|
||
<div class="nav-item" data-filter="recycle" onclick="filterByNav(this, 'recycle')">
|
||
<span class="nav-icon">🗑️</span>
|
||
<span class="nav-label">回收站</span>
|
||
<span class="nav-count" id="countRecycle">0</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="nav-divider"></div>
|
||
|
||
<div class="nav-section">
|
||
<div class="nav-section-title">任务管理</div>
|
||
<div id="taskList">
|
||
<div class="nav-item" onclick="showTasks()">
|
||
<span class="nav-icon">📋</span>
|
||
<span class="nav-label">分析任务</span>
|
||
<span class="nav-count" id="countRunning">0</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="nav-divider"></div>
|
||
|
||
<div class="nav-section">
|
||
<div class="nav-section-title">智能文件夹</div>
|
||
<div id="categoryList"></div>
|
||
</div>
|
||
</nav>
|
||
|
||
<div class="sidebar-footer">
|
||
<button class="btn btn-block btn-upload" onclick="openUploadModal()">📤 上传素材</button>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- Main Area -->
|
||
<div class="main-area">
|
||
<!-- Top Bar -->
|
||
<div class="topbar">
|
||
<div class="topbar-left">
|
||
<button class="btn btn-icon" id="btnToggleSidebar" onclick="toggleSidebar()">☰</button>
|
||
<div class="breadcrumb">
|
||
<span class="breadcrumb-item" id="breadcrumbRoot">拍摄剪辑</span>
|
||
<span class="breadcrumb-sep">›</span>
|
||
<span class="breadcrumb-item active" id="breadcrumbCurrent">全部</span>
|
||
</div>
|
||
</div>
|
||
<div class="topbar-center">
|
||
<div class="slider-group">
|
||
<span class="slider-label">小</span>
|
||
<input type="range" id="cardSizeSlider" min="160" max="360" value="240" oninput="setCardSize(this.value)">
|
||
<span class="slider-label">大</span>
|
||
</div>
|
||
</div>
|
||
<div class="topbar-right">
|
||
<div class="view-toggle">
|
||
<button class="view-btn active" id="btnGrid" onclick="setView('grid')">▦</button>
|
||
<button class="view-btn" id="btnList" onclick="setView('list')">☰</button>
|
||
</div>
|
||
<div class="search-box">
|
||
<input type="text" id="search" placeholder="搜索文件名或AI描述..." oninput="applyFilters()">
|
||
</div>
|
||
<button class="btn btn-analyze" id="btnAnalyze" onclick="startAnalysis()">🔍 分析</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Filter Bar -->
|
||
<div class="filterbar">
|
||
<div class="filter-group">
|
||
<label>时长:</label>
|
||
<input type="number" id="minDur" placeholder="最小" min="0" step="1" style="width:55px">
|
||
<span>-</span>
|
||
<input type="number" id="maxDur" placeholder="最大" min="0" step="1" style="width:55px">
|
||
<span>秒</span>
|
||
</div>
|
||
<div class="filter-group">
|
||
<label>分辨率:</label>
|
||
<select id="resolutionFilter" onchange="applyFilters()">
|
||
<option value="">全部</option>
|
||
<option value="4k">4K</option>
|
||
<option value="1080p">1080P</option>
|
||
<option value="vertical">竖屏</option>
|
||
</select>
|
||
</div>
|
||
<div class="filter-results" id="filterResults"></div>
|
||
<button class="btn btn-select-all" onclick="selectAllPage()">☑ 全选本页</button>
|
||
</div>
|
||
|
||
<!-- Grid -->
|
||
<div class="content-area">
|
||
<div class="grid-container">
|
||
<div class="grid" id="grid"></div>
|
||
<div class="empty-state" id="emptyState" style="display:none">
|
||
<p>📭 没有找到匹配的素材</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Pagination -->
|
||
<div class="pagination" id="pagination"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Upload Modal -->
|
||
<div class="modal" id="uploadModal">
|
||
<div class="modal-overlay" onclick="closeUploadModal()"></div>
|
||
<div class="modal-content" style="max-width:600px">
|
||
<button class="modal-close" onclick="event.stopPropagation();closeUploadModal()">✕</button>
|
||
<div class="upload-header">
|
||
<h2>📤 上传视频素材</h2>
|
||
<p>支持 MP4、MOV、AVI、MKV 等格式,最大 4GB</p>
|
||
</div>
|
||
<div class="upload-body">
|
||
<div class="upload-dropzone" id="dropzone">
|
||
<div class="dropzone-icon">📁</div>
|
||
<p>拖拽文件到此处,或点击选择文件</p>
|
||
<input type="file" id="fileInput" multiple accept="video/*,.mp4,.mov,.avi,.mkv,.mts,.mxf,.wmv" style="position:absolute;width:100%;height:100%;top:0;left:0;opacity:0;cursor:pointer;z-index:10">
|
||
</div>
|
||
<div class="upload-category">
|
||
<label>分类:</label>
|
||
<input type="text" id="uploadCategory" value="上传素材" placeholder="输入分类名称">
|
||
</div>
|
||
<div class="upload-filelist" id="uploadFilelist"></div>
|
||
<div class="upload-progress" id="uploadProgress" style="display:none">
|
||
<div class="progress-bar">
|
||
<div class="progress-fill" id="uploadProgressFill"></div>
|
||
</div>
|
||
<span class="progress-text" id="uploadProgressText">上传中...</span>
|
||
</div>
|
||
<div class="upload-result" id="uploadResult" style="display:none"></div>
|
||
<button class="btn btn-upload-submit" id="btnUploadSubmit" onclick="submitUpload()" disabled>开始上传</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Task Panel -->
|
||
<div class="task-panel" id="taskPanel" style="display:none">
|
||
<div class="task-panel-header">
|
||
<span>📋 分析任务</span>
|
||
<button class="btn btn-icon" onclick="hideTasks()">✕</button>
|
||
</div>
|
||
<div class="task-panel-body" id="taskPanelBody"></div>
|
||
</div>
|
||
|
||
<!-- Analysis Progress -->
|
||
<div class="progress-overlay" id="progressBar" style="display:none">
|
||
<div class="progress-bar">
|
||
<div class="progress-fill" id="progressFill"></div>
|
||
</div>
|
||
<span class="progress-text" id="progressText">分析中...</span>
|
||
</div>
|
||
|
||
<!-- Video Preview Modal -->
|
||
<div class="modal" id="modal">
|
||
<div class="modal-overlay" onclick="closeModal()"></div>
|
||
<div class="modal-content">
|
||
<button class="modal-close" onclick="event.stopPropagation();closeModal()">✕</button>
|
||
<div class="modal-tabs">
|
||
<button class="modal-tab active" onclick="switchModalTab('preview', this)">🎬 预览</button>
|
||
<button class="modal-tab" onclick="switchModalTab('report', this)">📊 分析报告</button>
|
||
</div>
|
||
<div class="modal-tab-content" id="tabPreview">
|
||
<video id="videoPlayer" controls preload="auto"></video>
|
||
<div class="clip-toolbar" id="clipToolbar">
|
||
<div class="clip-timeline-wrapper">
|
||
<div class="clip-timeline" id="clipTimeline">
|
||
<div class="clip-played" id="clipPlayed"></div>
|
||
<div class="clip-selection" id="clipSelection"></div>
|
||
<div class="clip-marker clip-marker-in" id="clipMarkerIn"></div>
|
||
<div class="clip-marker clip-marker-out" id="clipMarkerOut"></div>
|
||
<div class="clip-playhead" id="clipPlayhead"></div>
|
||
</div>
|
||
<div class="clip-timeaxis" id="clipTimeaxis"></div>
|
||
</div>
|
||
<div class="clip-row">
|
||
<button class="btn btn-clip-set" onclick="setClipStart()">📍 入点</button>
|
||
<span class="clip-time" id="clipStart">00:00.000</span>
|
||
<span class="clip-sep">→</span>
|
||
<button class="btn btn-clip-set" onclick="setClipEnd()">📍 出点</button>
|
||
<span class="clip-time" id="clipEnd">00:00.000</span>
|
||
<span class="clip-duration" id="clipDuration">时长: 0s</span>
|
||
<button class="btn btn-clip-play" onclick="playClipRange()">▶ 播放选区</button>
|
||
<button class="btn btn-clip-split" onclick="splitClip()">✂️ 分割</button>
|
||
<button class="btn btn-clip-save" onclick="saveClip()">💾 保存片段</button>
|
||
<button class="btn btn-clip-add" onclick="addClipToList()">➕ 添加到列表</button>
|
||
</div>
|
||
<div class="clip-list" id="clipList"></div>
|
||
</div>
|
||
<div class="modal-info" id="modalInfo"></div>
|
||
</div>
|
||
<div class="modal-tab-content" id="tabReport" style="display:none">
|
||
<div class="report-container" id="reportContainer"></div>
|
||
<div class="scene-section" id="sceneSection" style="display:none">
|
||
<div id="sceneResults"></div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-actions">
|
||
<button class="btn btn-analyze-modal" id="modalAnalyzeBtn" onclick="analyzeFromModal()">🔍 分析</button>
|
||
<button class="btn btn-prev" onclick="navigateModal(-1)">◀ 上一个</button>
|
||
<button class="btn btn-next" onclick="navigateModal(1)">下一个 ▶</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 新建文件夹模态框 -->
|
||
<div class="modal" id="createFolderModal">
|
||
<div class="modal-overlay" onclick="closeCreateFolderModal()"></div>
|
||
<div class="modal-content" style="max-width:400px">
|
||
<button class="modal-close" onclick="closeCreateFolderModal()">✕</button>
|
||
<h3 style="margin:0 0 16px 0">新建文件夹</h3>
|
||
<input type="text" id="newFolderName" placeholder="输入文件夹名称" maxlength="50" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;font-size:14px;box-sizing:border-box">
|
||
<div style="margin-top:16px;display:flex;gap:8px;justify-content:flex-end">
|
||
<button class="btn btn-clear" onclick="closeCreateFolderModal()">取消</button>
|
||
<button class="btn btn-upload" onclick="createFolder()">创建</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Selected Bar -->
|
||
<div class="selected-bar" id="selectedBar" style="display:none">
|
||
<span>已选择 <strong id="selectedCount">0</strong> 个素材</span>
|
||
<div id="normalActions">
|
||
<button class="btn btn-export" onclick="exportSelected()">📥 导出报告</button>
|
||
<button class="btn btn-analyze-selected" onclick="analyzeSelected()">🔍 分析选中</button>
|
||
<button class="btn btn-move" onclick="showMoveMenu()">📁 移动到文件夹</button>
|
||
<button class="btn btn-delete-selected" onclick="deleteSelected()">🗑 移入回收站</button>
|
||
</div>
|
||
<div id="recycleActions" style="display:none">
|
||
<button class="btn btn-restore" onclick="restoreSelected()">♻️ 恢复选中</button>
|
||
<button class="btn btn-permanent-delete" onclick="permanentDeleteSelected()">🔥 彻底删除</button>
|
||
</div>
|
||
<button class="btn btn-clear" onclick="clearSelection()">✕ 清空</button>
|
||
</div>
|
||
|
||
<script src="/static/folder_functions.js"></script>
|
||
<script src="/static/app.js?v=99"></script>
|
||
</body>
|
||
</html>
|