hoangsonww/Moodify-Emotion-Music-App

Feature: Mood Session - Real-time Emotion Blending & Goal-Oriented Playlists (Match / Boost / Calm)

开放

#11 创建于 2025年8月17日

 (0 条评论) (0 个反应) (1 位负责人)JavaScript (23 个派生)auto 404
bugdocumentationduplicateenhancementgood first issuehelp wanted

仓库指标

星标
 (80 个星标)
PR 合并指标
 (PR 指标待抓取)

描述

Summary

Introduce a Mood Session mode that continuously fuses multimodal emotions (text / speech / facial) into a single blended mood vector and generates a dynamic Spotify playlist aligned to a user-selected goal:

  • Match my mood,
  • Boost (increase energy/valence), or
  • Calm (decrease energy/tempo).

The session adapts in real time to incoming signals and user feedback (like/skip), updating track choices and crossfading smoothly.


Motivation

  • Current flow is single-shot: detect → recommend. Users often want continuous, adaptive music as their mood shifts.
  • Goal framing (Match/Boost/Calm) supports emotion regulation, not just reflection—improving engagement and session length.
  • Real-time feedback (skips/likes) gives learning signals to improve recs and evaluate model quality.

Goals

  1. Start/Stop Mood Session with a goal selector (Match/Boost/Calm).
  2. Multimodal blend: fuse text/speech/facial scores into one mood vector (e.g., arousal/valence + discrete labels).
  3. Adaptive playlist: pick tracks by Spotify audio features (valence, energy, tempo, danceability) + genres; refresh as the mood updates.
  4. Realtime updates: react to new detections and user actions (like/skip/seek) within the session.
  5. Crossfade and smooth transitions; maintain a small look-ahead queue.
  6. Privacy controls: clear camera/mic consent; local preview of raw signals; easy pause.
  7. Telemetry: session metrics, regulation success (mood delta), skips/likes, latency.

Non-Goals (for this issue):

  • Long-term personalization models, collaborative filtering across users, social features.

User Stories

  • As a user, I can select Match/Boost/Calm and start a session that updates songs as my mood changes.
  • As a user, I can see why a track was picked (e.g., “high valence & medium energy to boost your mood”).
  • As a user, I can like/skip tracks to influence upcoming recommendations.
  • As a privacy-aware user, I can pause camera/mic at any time and keep running with text-only.

Acceptance Criteria

  • Start/Stop controls visible on Home and Results pages; goal toggle persists per session.
  • Multimodal detections update a blended mood vector at ≤1s p95 from receipt → fusion.
  • Next track selection occurs in ≤1.5s p95 after a new mood signal or skip.
  • Queue maintains ≥3 upcoming tracks; crossfade between tracks without audible gaps.
  • Explain-why tooltip available for each track (surface key audio features + goal).
  • Mobile parity: start/stop, goal selection, likes/skips; microphone/camera permissions handled natively.
  • If no camera/mic consent, session runs with available modalities (degraded state shown).
  • A11y: keyboard navigable controls, ARIA labels, focus states.

UX Notes

  • Session Bar (sticky): [● live] Current mood badge → goal chip (Match/Boost/Calm) → Like/Skip → Pause input → End Session.
  • Now Playing Card: album art, reason “why”, mood + audio features mini-pill (valence↑, energy→, tempo→).
  • Settings: sliders for tempo/energy bounds and explicit content toggle.

API (Django REST — proposed)

Align with existing URL conventions; adjust names as needed.

POST   /api/session/start
body: { userId, goal: "match"|"boost"|"calm", modalities: {text?:bool,speech?:bool,face?:bool} }

POST   /api/session/stop
body: { sessionId }

POST   /api/session/signal
body: { sessionId, signal: { modality:"text"|"speech"|"face", scores:{ valence:number, arousal:number, label:string }, ts?:string } }

GET    /api/session/next
query: sessionId
# returns next track(s), queue state, rationale

POST   /api/session/feedback
body: { sessionId, trackId, action:"like"|"skip"|"played", positionMs?:number }

GET    /api/session/state
query: sessionId
# returns blended mood vector, goal, queue, last update

Response example (/api/session/next):

{
  "tracks": [
    {
      "trackId": "spotify:track:123",
      "title": "Sunrise Drive",
      "artist": "Night Parade",
      "features": { "valence": 0.78, "energy": 0.62, "tempo": 118 },
      "rationale": "Boost: higher valence than current mood, moderate energy for smooth transition",
      "previewUrl": "https://p.scdn.co/mp3-preview/..."
    }
  ],
  "queueSize": 4,
  "blendedMood": { "valence": 0.41, "arousal": 0.55, "label": "melancholic" }
}

Blending & Ranking (AI/ML)

  • Fusion: weighted average over normalized modality confidence (dropout-robust; if a modality is missing, re-normalize).

  • Goal transform:

    • Match: minimize distance to current mood.
    • Boost: target ↑valence (+Δ), cap energy to user preference.
    • Calm: target ↓arousal/tempo, maintain moderate valence.
  • Retrieval: filter candidate tracks by Spotify audio features & user constraints → rank by (goal distance + popularity penalty + freshness).

  • Online learning: update per-user short-term weights from likes/skips within session scope.


Data Model (MongoDB examples)

  • sessions: { _id, userId, goal, active, blendedMood{valence,arousal,label}, modalities, createdAt, updatedAt }
  • session_events: { sessionId, type: "signal"|"feedback"|"track_play", payload, ts }
  • user_prefs: { userId, bounds:{tempo:[min,max], energy:[min,max]}, explicitAllowed:bool }

Privacy & Security

  • Explicit consent prompts for mic/camera; store consent state locally, not on server.
  • Allow “text-only” mode.
  • Rate-limit /signal and /feedback to prevent abuse.
  • Never store raw audio/video; only derived scores + timestamps.

Performance

  • Keep an in-memory candidate pool per session for fast re-ranking.
  • Redis cache for common seed sets (per goal).
  • Pre-fetch next track’s preview and metadata; crossfade via frontend audio element or Spotify SDK bridge where possible.

Analytics / Metrics

Events:

  • session_start {goal, modalities}
  • session_signal {modality, latencyMs}
  • session_track_recommended {trackId, features, goal}
  • session_feedback {action, trackId} KPIs:
  • Avg session duration, tracks per session, skip rate, mood regulation delta (target vs actual after N tracks), p95 recommendation latency.

Rollout Plan

  1. Phase 1: Backend session lifecycle + fusion + basic ranking; web UI; likes/skip.
  2. Phase 2: Crossfade, queue look-ahead, explanations; mobile parity.
  3. Phase 3: Personalization (short-term learning), advanced settings, A/B for goal transforms.

Tasks

Backend (Django/DRF)

  • Define sessions & session_events collections/models.
  • Implement /session/* endpoints + auth + rate limits.
  • Integrate Spotify features search (valence/energy/tempo/danceability).
  • Fusion & goal transform logic; candidate pool + re-ranker.
  • Unit/integration tests; load test p95 targets.

AI/ML

  • Normalize modality outputs; confidence weighting & dropout handling.
  • Map discrete labels ↔ (valence, arousal).
  • Online feedback updates (lightweight, session-scoped).
  • Quality dashboards (regulation delta, skip correlation).

Frontend (React)

  • Session bar + goal toggle; Now Playing card; explanations tooltip.
  • Queue UI, crossfade, error/empty states, a11y.
  • Permissions prompts & degraded-mode banners.
  • Analytics events.

Mobile (React Native/Expo)

  • Start/stop, goal selector, likes/skip; mic/camera permissions.
  • Lightweight queue UI; background audio constraints documented.

Infra/CI

  • Feature flag mood_session_enabled.
  • Redis for candidate caching; observability dashboards.

Docs

  • README + openapi.yaml updates (new endpoints).
  • Privacy/permissions notes, troubleshooting.

Open Questions

  • Default fusion weights per modality? (propose equal weights, confidence-scaled)
  • Should Boost target both valence and energy by default, or only valence?
  • Minimum track preview length before allowing a skip to count as a negative signal?
  • Spotify SDK vs. web audio for crossfade (licensing & platform differences)?

贡献者指南