const { PrismaClient } = require('@prisma/client'); const prisma = new PrismaClient(); const http = require('http'); async function testAudioPlayback() { console.log('\n🎵 音频播放完整测试\n'); console.log('=' .repeat(60)); const bookId = 5; // 步骤1:检查一个小节的音频URL console.log('📊 步骤1:检查音频数据\n'); const subsection = await prisma.bookChapter.findFirst({ where: { bookId, level: 3 }, select: { id: true, title: true, level: true, audioUrl: true, audioDuration: true, content: true, } }); if (!subsection) { console.log('❌ 找不到小节\n'); await prisma.$disconnect(); return; } console.log(`章节: ${subsection.title}`); console.log(`ID: ${subsection.id}`); console.log(`Level: ${subsection.level}`); console.log(`audioUrl: ${subsection.audioUrl || '无'}`); console.log(`audioDuration: ${subsection.audioDuration || 0}秒`); console.log(`内容: ${subsection.content || '无'}\n`); // 步骤2:检查文件是否存在 console.log('📁 步骤2:检查音频文件\n'); const fs = require('fs'); const path = require('path'); const uuid = subsection.audioUrl.match(/\/uploads\/([^\/]+)\//)?.[1]; if (!uuid) { console.log('❌ 无法解析UUID\n'); await prisma.$disconnect(); return; } const filePath = path.join(__dirname, 'uploads', uuid, 'output.mp3'); console.log(`文件路径: ${filePath}`); if (fs.existsSync(filePath)) { const stats = fs.statSync(filePath); console.log(`✅ 文件存在,大小: ${(stats.size / 1024).toFixed(2)} KB\n`); } else { console.log(`❌ 文件不存在\n`); await prisma.$disconnect(); return; } // 步骤3:测试HTTP访问 console.log('🌐 步骤3:测试HTTP访问\n'); const url = 'http://localhost:3000' + subsection.audioUrl; console.log(`URL: ${url}\n`); return new Promise((resolve) => { http.get(url, (res) => { console.log(`HTTP响应状态: ${res.statusCode}`); console.log(`Content-Type: ${res.headers['content-type']}`); console.log(`Content-Length: ${res.headers['content-length']} bytes\n`); if (res.statusCode === 200) { console.log('✅ 音频URL可以通过HTTP访问\n'); // 步骤4:测试API接口 console.log('📡 步骤4:测试API接口\n'); const apiUrl = `http://localhost:3000/api/player/audio/${subsection.id}`; console.log(`API URL: ${apiUrl}\n`); http.get(apiUrl, { headers: { 'Content-Type': 'application/json' } }, (apiRes) => { let data = ''; apiRes.on('data', chunk => data += chunk); apiRes.on('end', () => { try { const result = JSON.parse(data); console.log(`API响应状态码: ${apiRes.statusCode}`); console.log(`API code: ${result.code}`); console.log(`API message: ${result.message}\n`); if (result.data) { console.log('音频数据:'); console.log(` ID: ${result.data.id}`); console.log(` 标题: ${result.data.title}`); console.log(` audioUrl: ${result.data.audioUrl}`); console.log(` 时长: ${result.data.audioDuration}秒\n`); console.log('=' .repeat(60)); console.log('\n📋 测试总结:\n'); console.log('✅ 所有测试通过!'); console.log('\n前端访问地址:'); console.log(` http://localhost:5173/#/pages/player/index?id=${subsection.id}`); console.log('\n音频应该可以正常播放了!\n'); } } catch (e) { console.log('❌ API响应解析失败:', e.message); } resolve(); }); }).on('error', (err) => { console.log(`❌ API请求失败: ${err.message}\n`); resolve(); }); } else { console.log('❌ 音频URL无法通过HTTP访问\n'); resolve(); } }).on('error', (err) => { console.log(`❌ HTTP请求失败: ${err.message}\n`); resolve(); }); }); } testAudioPlayback().then(() => prisma.$disconnect()).catch(console.error);