import React, { useState, useEffect } from 'react' import { X, BarChart3, Download } from 'lucide-react' import { invoke } from '@tauri-apps/api/core' import { AudioFile } from '../services/audioService' interface AudioChartViewerProps { isOpen: boolean audio: AudioFile | null onClose: () => void } const AudioChartViewer: React.FC = ({ isOpen, audio, onClose }) => { const [chartImageSrc, setChartImageSrc] = useState('') const [loading, setLoading] = useState(false) useEffect(() => { if (isOpen && audio && audio.frequency_chart_path) { loadChartImage() } }, [isOpen, audio]) const loadChartImage = async () => { if (!audio?.frequency_chart_path) return setLoading(true) try { // 使用Tauri的文件读取API将图片转换为data URL const dataUrl = await invoke('read_image_as_data_url', { filePath: audio.frequency_chart_path }) setChartImageSrc(dataUrl) } catch (error) { console.error('Failed to load chart image:', error) setChartImageSrc('') } finally { setLoading(false) } } const handleDownload = () => { if (!chartImageSrc || !audio) return // 创建下载链接 const link = document.createElement('a') link.href = chartImageSrc link.download = `${audio.filename}_frequency_chart.png` document.body.appendChild(link) link.click() document.body.removeChild(link) } if (!isOpen || !audio) return null return (
{/* 标题栏 */}

音频频率分析

{audio.filename}

{chartImageSrc && ( )}
{/* 内容区域 */}
{/* 音频信息摘要 */}
时长: {Math.floor(audio.duration / 60)}:{(audio.duration % 60).toFixed(0).padStart(2, '0')}
采样率: {audio.sample_rate} Hz
{audio.tempo && (
节拍: {audio.tempo.toFixed(1)} BPM
)} {audio.spectral_centroid && (
频谱重心: {audio.spectral_centroid.toFixed(0)} Hz
)}
{/* 频率图表 */}
{loading ? (
加载频率图中...
) : chartImageSrc ? (
{`${audio.filename}
) : (

频率图不可用

可能需要重新处理音频文件

)}
{/* 音频特征详情 */} {(audio.spectral_rolloff || audio.zero_crossing_rate || audio.mfcc_features) && (

音频特征分析

{audio.spectral_rolloff && (
频谱滚降: {audio.spectral_rolloff.toFixed(0)} Hz
)} {audio.zero_crossing_rate && (
过零率: {(audio.zero_crossing_rate * 100).toFixed(2)}%
)} {audio.mfcc_features && (
MFCC特征: {audio.mfcc_features.length} 维
)}
{/* 节拍时间点 */} {audio.beat_times && audio.beat_times.length > 0 && (
检测到节拍点: {audio.beat_times.length} 个
前5个节拍时间: {audio.beat_times.slice(0, 5).map(t => t.toFixed(2)).join('s, ')}s
)}
)}
) } export default AudioChartViewer