欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net

一、项目概述

运行效果图

image-20260409224908835

image-20260409224913526

image-20260409224917600

image-20260409224923475

1.1 应用简介

声音风景记录器是一款创意体验类应用,帮助用户记录世界各地的声音风景,从海浪拍岸到鸟语花香,从市井喧嚣到山间寂静。支持声音录制、波形可视化、地理标记、分类收藏等功能,让用户闭上眼睛就能"听"见世界。应用以宁静的青色为主色调,象征声音的纯净与自然。涵盖声音录制、声音地图、声音收藏、探索发现四大模块,用声音记录生活的美好。

1.2 核心功能

功能模块 功能描述 实现方式
声音录制 录制环境声音 音频录制
波形可视化 实时显示声音波形 CustomPainter
地理标记 记录声音位置 位置服务
声音分类 按类型分类管理 枚举定义
声音地图 在地图上展示声音 地图展示
探索发现 发现他人分享的声音 社区功能

1.3 声音类型定义

序号 类型名称 Emoji 描述 典型声音
1 自然之声 🌊 大自然的原始声音 海浪、雨声、风
2 鸟语花香 🐦 动植物的生机 鸟鸣、虫叫、蛙声
3 城市节拍 🏙️ 都市的生活节奏 车流、人群、地铁
4 市井烟火 🏪 人间的生活气息 叫卖、烹饪、交谈
5 音乐旋律 🎵 人造的美妙音符 街头表演、乐器
6 寺庙钟声 🛕 宗教的庄严氛围 钟声、诵经、木鱼
7 乡村田园 🌾 乡村的宁静祥和 鸡鸣、牛叫、收割
8 山间溪流 ⛰️ 山野的清澈之音 溪水、瀑布、林涛

1.4 声音情绪定义

序号 情绪名称 Emoji 声音特征 典型场景
1 宁静祥和 😌 平缓柔和 晨曦、夜晚
2 活力四射 节奏明快 市集、运动场
3 浪漫温馨 💕 柔美动听 黄昏、花园
4 神秘悠远 🌙 空灵深远 深山、古寺
5 热闹喧嚣 🎉 嘈杂丰富 节日、市场
6 孤寂清冷 🌫️ 单调稀疏 深夜、荒野

1.5 声音质量定义

序号 质量等级 Emoji 时长范围 描述
1 片刻 ⏱️ 0-30秒 短暂的瞬间
2 片段 📼 30秒-2分钟 完整的片段
3 场景 🎬 2-5分钟 完整的场景
4 沉浸 🎧 5分钟以上 沉浸式体验

1.6 声音状态定义

序号 状态名称 Emoji 描述
1 录制中 🔴 正在录制
2 已保存 💾 已保存到本地
3 已分享 🌐 已分享到社区
4 收藏中 已加入收藏

1.7 技术栈

技术领域 技术选型 版本要求
开发框架 Flutter >= 3.0.0
编程语言 Dart >= 2.17.0
设计规范 Material Design 3 -
自定义绘制 CustomPainter -
动画效果 AnimationController -
目标平台 鸿蒙OS / Web API 21+

1.8 项目结构

lib/
└── main_sound_landscape.dart
    ├── SoundLandscapeApp        # 应用入口
    ├── SoundType                # 声音类型枚举
    ├── SoundMood                # 声音情绪枚举
    ├── SoundQuality             # 声音质量枚举
    ├── SoundStatus              # 声音状态枚举
    ├── SoundRecord              # 声音记录模型
    ├── SoundLandscapeHomePage   # 主页面(底部导航)
    ├── _buildRecordPage         # 录制页面
    ├── _buildMapPage            # 地图页面
    ├── _buildCollectionPage     # 收藏页面
    ├── _buildDiscoverPage       # 发现页面
    ├── WaveformPainter          # 波形绘制器
    └── SoundVisualizerPainter   # 声音可视化绘制器

二、系统架构

2.1 整体架构图

Data Layer

Business Layer

Presentation Layer

主页面
SoundLandscapeHomePage

录制页

地图页

收藏页

发现页

录音控制

波形显示

信息编辑

声音地图

位置标记

附近声音

收藏列表

分类管理

播放控制

热门声音

最新分享

搜索发现

录音管理器
RecordManager

播放管理器
PlayerManager

位置服务
LocationService

分享服务
ShareService

SoundRecord
声音记录

Location
位置信息

UserInfo
用户信息

2.2 类图设计

has

has

has

has

SoundLandscapeApp

+Widget build()

«enumeration»

SoundType

+String label

+String emoji

+String description

+List<String> examples

+nature()

+birds()

+city()

+market()

+music()

+temple()

+countryside()

+mountain()

«enumeration»

SoundMood

+String label

+String emoji

+String feature

+String scene

+peaceful()

+energetic()

+romantic()

+mysterious()

+lively()

+lonely()

«enumeration»

SoundQuality

+String label

+String emoji

+int minSeconds

+int maxSeconds

+moment()

+segment()

+scene()

+immersive()

SoundRecord

+String id

+String title

+SoundType type

+SoundMood mood

+SoundQuality quality

+SoundStatus status

+int duration

+String location

+double latitude

+double longitude

+DateTime createdAt

+String description

+List<double> waveform

Location

+String name

+double latitude

+double longitude

+String address

2.3 页面导航流程

录制

地图

收藏

发现

应用启动

录制页

底部导航

开始录制

声音地图

我的收藏

探索发现

录制中

保存声音

编辑信息

查看位置

播放声音

浏览收藏

播放/管理

浏览发现

收藏/分享

2.4 录制流程

存储 波形显示 录音器 录制页 用户 存储 波形显示 录音器 录制页 用户 loop [录制中] 点击录制 开始录音 更新波形 显示波形动画 停止录制 停止录音 保存音频 显示保存成功

三、核心模块设计

3.1 数据模型设计

3.1.1 声音类型枚举 (SoundType)
enum SoundType {
  nature('自然之声', '🌊', '大自然的原始声音', ['海浪', '雨声', '风声']),
  birds('鸟语花香', '🐦', '动植物的生机', ['鸟鸣', '虫叫', '蛙声']),
  city('城市节拍', '🏙️', '都市的生活节奏', ['车流', '人群', '地铁']),
  market('市井烟火', '🏪', '人间的生活气息', ['叫卖', '烹饪', '交谈']),
  music('音乐旋律', '🎵', '人造的美妙音符', ['街头表演', '乐器', '歌唱']),
  temple('寺庙钟声', '🛕', '宗教的庄严氛围', ['钟声', '诵经', '木鱼']),
  countryside('乡村田园', '🌾', '乡村的宁静祥和', ['鸡鸣', '牛叫', '收割']),
  mountain('山间溪流', '⛰️', '山野的清澈之音', ['溪水', '瀑布', '林涛']);

  final String label;
  final String emoji;
  final String description;
  final List<String> examples;
}
3.1.2 声音情绪枚举 (SoundMood)
enum SoundMood {
  peaceful('宁静祥和', '😌', '平缓柔和', '晨曦、夜晚'),
  energetic('活力四射', '⚡', '节奏明快', '市集、运动场'),
  romantic('浪漫温馨', '💕', '柔美动听', '黄昏、花园'),
  mysterious('神秘悠远', '🌙', '空灵深远', '深山、古寺'),
  lively('热闹喧嚣', '🎉', '嘈杂丰富', '节日、市场'),
  lonely('孤寂清冷', '🌫️', '单调稀疏', '深夜、荒野');

  final String label;
  final String emoji;
  final String feature;
  final String scene;
}
3.1.3 声音记录模型 (SoundRecord)
class SoundRecord {
  final String id;              // 声音ID
  final String title;           // 声音标题
  final SoundType type;         // 声音类型
  final SoundMood mood;         // 声音情绪
  final SoundQuality quality;   // 声音质量
  SoundStatus status;           // 声音状态
  final int duration;           // 时长(秒)
  final String location;        // 位置名称
  final double latitude;        // 纬度
  final double longitude;       // 经度
  final DateTime createdAt;     // 创建时间
  final String description;     // 描述
  final List<double> waveform;  // 波形数据
}
3.1.4 声音类型分布
25% 20% 18% 15% 10% 5% 4% 3% 声音类型分布示例 自然之声 鸟语花香 城市节拍 市井烟火 音乐旋律 寺庙钟声 乡村田园 山间溪流

3.2 页面结构设计

3.2.1 主页面布局

SoundLandscapeHomePage

IndexedStack

录制页

地图页

收藏页

发现页

NavigationBar

录制 Tab

地图 Tab

收藏 Tab

发现 Tab

3.2.2 录制页结构

录制页

SliverAppBar

波形显示

录制控制

声音列表

实时波形

动画效果

开始录制

停止录制

播放预览

声音卡片

波形缩略图

基本信息

3.2.3 地图页结构

地图页

SliverAppBar

地图视图

声音标记

附近列表

位置显示

缩放控制

声音图标

点击播放

附近声音

距离显示

3.2.4 收藏页结构

收藏页

SliverAppBar

统计概览

分类筛选

收藏列表

总收藏数

总时长

类型筛选

情绪筛选

声音卡片

播放控制

3.3 波形绘制逻辑

获取音频数据

采样处理

计算振幅

归一化处理

绘制波形

是否动画?

添加动画效果

静态显示

实时更新

完成绘制

3.4 声音分类逻辑

获取声音记录

按类型分类

自然之声

鸟语花香

城市节拍

其他类型

统计数量

计算占比

生成分布图


四、UI设计规范

4.1 配色方案

应用以宁静的青色为主色调,象征声音的纯净与自然:

颜色类型 色值 用途
主色 #00BCD4 (Cyan) 导航、主题元素
辅助色 #26C6DA 录制页面
第三色 #4DD0E1 地图页面
强调色 #00ACC1 收藏页面
录制色 #F44336 (Red) 录制状态
播放色 #4CAF50 (Green) 播放状态
背景色 #0A0A1A 页面背景
卡片背景 #1A1A2E 声音卡片

4.2 声音类型配色

声音类型 色值 视觉效果
自然之声 #00BCD4 海洋青色
鸟语花香 #8BC34A 自然绿色
城市节拍 #FF9800 都市橙色
市井烟火 #F44336 热情红色
音乐旋律 #9C27B0 艺术紫色
寺庙钟声 #FFD700 金色庄严
乡村田园 #4CAF50 田园绿色
山间溪流 #2196F3 清澈蓝色

4.3 字体规范

元素 字号 字重 颜色
页面标题 24px Bold 主色
声音名称 16px Bold #FFFFFF
位置信息 12px Regular 白色
时长显示 14px Medium 白色

4.4 组件规范

4.4.1 波形显示区域
┌─────────────────────────────────────┐
│  🎵 声音波形                         │
│                                     │
│  ▁▂▃▅▇█▇▅▃▂▁▁▂▃▅▇█▇▅▃▂▁           │
│  ▃▅▇█▇▅▃▂▁▁▂▃▅▇█▇▅▃▂▁▁▂▃▅▇         │
│                                     │
│  ⏱️ 00:45 / 02:30                   │
└─────────────────────────────────────┘
4.4.2 声音卡片
┌─────────────────────────────────────┐
│  🌊 海浪拍岸                         │
│                                     │
│  ▁▂▃▅▇█▇▅▃▂▁▁▂▃▅▇█▇▅▃▂▁           │
│                                     │
│  自然之声 · 宁静祥和                 │
│  📍 三亚海边 · 2分30秒               │
│                                     │
│  [▶️ 播放] [⭐ 收藏] [📤 分享]       │
└─────────────────────────────────────┘
4.4.3 录制控制
┌─────────────────────────────────────┐
│  🔴 录制中 00:45                     │
│                                     │
│         ┌───────┐                   │
│         │   ⏹️   │                   │
│         │  停止  │                   │
│         └───────┘                   │
│                                     │
│  选择类型: [🌊 自然] [🐦 鸟语] ...   │
└─────────────────────────────────────┘
4.4.4 声音地图标记
┌─────────────────────────────────────┐
│  🗺️ 声音地图                         │
│                                     │
│       🌊        🐦                   │
│           🏙️                         │
│    🎵             🛕                 │
│                                     │
│  附近 12 个声音风景                  │
└─────────────────────────────────────┘
4.4.5 声音统计
┌─────────────────────────────────────┐
│  📊 我的声音统计                     │
│                                     │
│  总录制: 28 个                       │
│  总时长: 1小时32分                   │
│  已分享: 8 个                        │
│                                     │
│  类型分布:                           │
│  🌊 自然  ████████ 10个             │
│  🐦 鸟语  ██████ 8个                │
│  🏙️ 城市  ████ 5个                  │
└─────────────────────────────────────┘

五、核心功能实现

5.1 波形绘制实现

class WaveformPainter extends CustomPainter {
  final List<double> waveform;
  final Color color;
  final double animationValue;

  
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = color
      ..strokeWidth = 2
      ..style = PaintingStyle.stroke;

    final path = Path();
    final step = size.width / waveform.length;
    
    for (int i = 0; i < waveform.length; i++) {
      final x = i * step;
      final y = size.height / 2 + waveform[i] * size.height / 2 * 
                sin(animationValue * 2 * pi + i * 0.1);
      
      if (i == 0) {
        path.moveTo(x, y);
      } else {
        path.lineTo(x, y);
      }
    }
    
    canvas.drawPath(path, paint);
  }
}

5.2 录制状态管理实现

void _toggleRecording() {
  setState(() {
    if (_isRecording) {
      _stopRecording();
    } else {
      _startRecording();
    }
  });
}

void _startRecording() {
  setState(() {
    _isRecording = true;
    _recordingDuration = 0;
    _recordingTimer = Timer.periodic(Duration(seconds: 1), (timer) {
      setState(() {
        _recordingDuration++;
      });
    });
  });
}

void _stopRecording() {
  _recordingTimer?.cancel();
  setState(() {
    _isRecording = false;
  });
  _showSaveDialog();
}

5.3 声音保存实现

void _saveSoundRecord({
  required String title,
  required SoundType type,
  required SoundMood mood,
  required String location,
}) {
  final record = SoundRecord(
    id: 's_${DateTime.now().millisecondsSinceEpoch}',
    title: title,
    type: type,
    mood: mood,
    quality: _determineQuality(_recordingDuration),
    duration: _recordingDuration,
    location: location,
    waveform: _generateWaveform(),
  );

  setState(() {
    _soundRecords.insert(0, record);
  });
}

5.4 波形数据生成实现

List<double> _generateWaveform() {
  final random = Random();
  return List.generate(50, (index) {
    return random.nextDouble() * 0.8 + 0.1;
  });
}

5.5 声音统计实现

Map<SoundType, int> _getTypeDistribution() {
  final distribution = <SoundType, int>{};
  for (final type in SoundType.values) {
    distribution[type] = _soundRecords.where((r) => r.type == type).length;
  }
  return distribution;
}

int _getTotalDuration() {
  return _soundRecords.fold(0, (sum, r) => sum + r.duration);
}

六、交互设计

6.1 录制流程

存储 波形显示 录制页 用户 存储 波形显示 录制页 用户 loop [录制中] 点击录制按钮 开始动画 显示实时波形 停止录制 保存声音 显示保存成功

6.2 播放流程

选择声音

点击播放

开始播放

显示波形动画

播放完成?

停止动画

显示完成状态

6.3 分享流程

选择声音

编辑信息

确认分享

上传中

分享成功


七、扩展功能规划

7.1 后续版本规划

2024-01-07 2024-01-14 2024-01-21 2024-01-28 2024-02-04 2024-02-11 2024-02-18 2024-02-25 2024-03-03 2024-03-10 2024-03-17 2024-03-24 2024-03-31 基础UI框架 录制功能 波形显示 地图功能 分享功能 分类管理 真实录音 云端同步 社区互动 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 声音风景记录器应用开发计划

7.2 功能扩展建议

7.2.1 真实录音

录音功能:

  • 真实音频录制
  • 多格式支持
  • 音质选择
  • 后期编辑
7.2.2 地理定位

定位功能:

  • GPS定位
  • 地址解析
  • 地图展示
  • 附近发现
7.2.3 社区功能

社区功能:

  • 声音分享
  • 评论互动
  • 关注收藏
  • 排行榜

八、注意事项

8.1 开发注意事项

  1. 权限管理:录音和定位需获取用户授权

  2. 波形性能:实时波形绘制需优化性能

  3. 存储管理:音频文件需合理管理存储空间

  4. 数据持久化:声音记录需本地持久化

  5. 动画流畅:波形动画需保持流畅

8.2 常见问题

问题 原因 解决方案
波形卡顿 绘制过于频繁 降低刷新频率
录音失败 权限未授予 检查权限
数据丢失 未正确保存 检查存储逻辑
定位不准 GPS信号弱 提示用户
播放异常 文件损坏 检查文件

8.3 使用技巧

🎧 声音录制技巧 🎧

录制建议

  • 选择安静环境录制
  • 保持设备稳定
  • 录制时长适中
  • 及时保存分类

分类建议

  • 根据声音来源分类
  • 添加详细描述
  • 标记准确位置
  • 选择合适情绪

分享建议

  • 选择优质声音分享
  • 添加精彩描述
  • 保护隐私信息
  • 积极互动交流

九、运行说明

9.1 环境要求

环境 版本要求
Flutter SDK >= 3.0.0
Dart SDK >= 2.17.0
鸿蒙OS API 21+
Web浏览器 Chrome 90+

9.2 运行命令

# 查看可用设备
flutter devices

# 运行到Web服务器
flutter run -d web-server -t lib/main_sound_landscape.dart --web-port 8154

# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_sound_landscape.dart

# 代码分析
flutter analyze lib/main_sound_landscape.dart

十、总结

声音风景记录器应用通过录制、地图、收藏、发现四大模块,为用户提供了一个记录和分享声音风景的平台。应用支持8种声音类型、6种声音情绪、4种声音质量,帮助用户用声音记录生活的美好。

核心功能涵盖声音录制、波形可视化、地理标记、分类管理四大模块。声音类型覆盖自然、城市、人文等多个领域;声音情绪从宁静到热闹,反映不同场景氛围;波形可视化让声音"看得见";地理标记让声音有迹可循。

应用采用 Material Design 3 设计规范,以宁静的青色为主色调,象征声音的纯净与自然。通过本应用,希望能够帮助用户用声音记录世界,闭上眼睛就能"听"见美好。

声音风景记录器——闭上眼睛听世界


欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐