@@ -1225,6 +1217,9 @@ function openFilesModal(fileType) {
}).join('');
elements.filesModal.classList.add('active');
+
+ // 打开弹窗后,异步加载还没有编码信息的文件
+ loadCodecInfoForFiles(files);
}
function closeFilesModal() {
@@ -1635,3 +1630,172 @@ async function loadTemplates() {
console.error('加载模板失败:', error);
}
}
+
+// ============ 缩略图功能已移除 ============
+// 视频和音频文件不再生成缩略图,只显示图标
+// 图片文件直接显示原图,无需生成缩略图
+// 这样可以大幅提升加载速度,特别是处理大量文件时
+
+// ============ 懒加载编码信息 ============
+async function lazyLoadCodecInfo() {
+ console.log('开始懒加载编码信息...');
+
+ // 需要获取编码信息的文件
+ const filesToLoad = state.files.filter(file =>
+ !file.codec_info && (file.file_type === 'video' || file.file_type === 'audio' || file.file_type === 'image')
+ );
+
+ if (filesToLoad.length === 0) {
+ console.log('没有需要加载的编码信息');
+ return;
+ }
+
+ console.log(`需要加载 ${filesToLoad.length} 个文件的编码信息`);
+
+ // 并发加载编码信息(限制并发数为 5,比缩略图可以更多)
+ const concurrency = 5;
+ for (let i = 0; i < filesToLoad.length; i += concurrency) {
+ const batch = filesToLoad.slice(i, i + concurrency);
+ await Promise.all(batch.map(file => loadSingleCodecInfo(file)));
+ }
+
+ console.log('所有编码信息加载完成');
+}
+
+async function loadSingleCodecInfo(file) {
+ try {
+ const codecInfo = await window.tauriInvoke('get_file_info', {
+ path: file.path,
+ fileType: file.file_type
+ });
+
+ // 更新文件对象
+ file.codec_info = codecInfo;
+
+ // 更新 DOM 显示(如果文件列表弹窗已打开)
+ updateCodecInfoInDOM(file);
+
+ console.log(`✅ 编码信息加载成功: ${file.name}`);
+ } catch (error) {
+ console.warn(`⚠️ 编码信息加载失败: ${file.name}`, error);
+ }
+}
+
+function updateCodecInfoInDOM(file) {
+ // 查找文件列表中对应的元素
+ const fileListItems = document.querySelectorAll(`.file-list-item[data-file-id="${file.id}"]`);
+ fileListItems.forEach(item => {
+ const codecEl = item.querySelector('.file-list-codec');
+ if (codecEl && file.codec_info) {
+ const codecInfo = getCodecInfoTextForFile(file);
+ codecEl.textContent = codecInfo;
+ codecEl.title = codecInfo;
+ }
+ });
+}
+
+// 为指定的文件列表加载编码信息
+async function loadCodecInfoForFiles(files) {
+ const filesToLoad = files.filter(file => !file.codec_info);
+
+ if (filesToLoad.length === 0) {
+ return;
+ }
+
+ console.log(`为文件列表加载 ${filesToLoad.length} 个编码信息`);
+
+ // 并发加载
+ const concurrency = 5;
+ for (let i = 0; i < filesToLoad.length; i += concurrency) {
+ const batch = filesToLoad.slice(i, i + concurrency);
+ await Promise.all(batch.map(file => loadSingleCodecInfo(file)));
+ }
+}
+
+// ============ 懒加载图片 ============
+async function lazyLoadImages() {
+ console.log('开始懒加载图片...');
+
+ // 需要加载的图片文件
+ const imagesToLoad = state.files.filter(file =>
+ file.file_type === 'image' && !file.imageData
+ );
+
+ if (imagesToLoad.length === 0) {
+ console.log('没有需要加载的图片');
+ return;
+ }
+
+ console.log(`需要加载 ${imagesToLoad.length} 个图片`);
+
+ // 并发加载图片(限制并发数为 3)
+ const concurrency = 3;
+ for (let i = 0; i < imagesToLoad.length; i += concurrency) {
+ const batch = imagesToLoad.slice(i, i + concurrency);
+ await Promise.all(batch.map(file => loadSingleImage(file)));
+ }
+
+ console.log('所有图片加载完成');
+}
+
+async function loadSingleImage(file) {
+ try {
+ const imageData = await window.tauriInvoke('read_image_as_base64', {
+ path: file.path
+ });
+
+ // 缓存图片数据
+ file.imageData = imageData;
+
+ // 更新 DOM 显示
+ updateImageInDOM(file.id, imageData);
+
+ console.log(`✅ 图片加载成功: ${file.name}`);
+ } catch (error) {
+ console.warn(`⚠️ 图片加载失败: ${file.name}`, error);
+ }
+}
+
+function updateImageInDOM(fileId, imageData) {
+ // 更新预览网格中的图片
+ const previewItems = document.querySelectorAll(`.preview-item[data-file-id="${fileId}"]`);
+ previewItems.forEach(item => {
+ if (item.dataset.loading === 'true') {
+ item.innerHTML = `

`;
+ item.dataset.loading = 'false';
+ item.classList.remove('image');
+ }
+ });
+
+ // 更新文件列表弹窗中的图片
+ const fileListItems = document.querySelectorAll(`.file-list-item[data-file-id="${fileId}"] .file-list-thumbnail`);
+ fileListItems.forEach(item => {
+ item.innerHTML = `

`;
+ });
+}
+
+function getCodecInfoTextForFile(file) {
+ if (!file.codec_info) {
+ return '-';
+ }
+
+ const info = file.codec_info;
+ const parts = [];
+ const fileType = file.file_type;
+
+ if (fileType === 'video') {
+ if (info.resolution) parts.push(info.resolution);
+ if (info.video_codec) parts.push(info.video_codec);
+ if (info.frame_rate) parts.push(info.frame_rate);
+ if (info.duration) parts.push(info.duration);
+ } else if (fileType === 'audio') {
+ if (info.audio_codec) parts.push(info.audio_codec);
+ if (info.sample_rate) parts.push(info.sample_rate);
+ if (info.channels) parts.push(info.channels);
+ if (info.duration) parts.push(info.duration);
+ } else if (fileType === 'image') {
+ if (info.resolution) parts.push(info.resolution);
+ }
+
+ return parts.length > 0 ? parts.join(' · ') : '-';
+}
diff --git a/test.mp4 b/test.mp4
deleted file mode 100755
index dd87695..0000000
Binary files a/test.mp4 and /dev/null differ