Skip to content

Playback analytics em app dedicado (apps.streaming)

MediaPlaybackSession e MediaPlaybackHeartbeat (watchtime, heatmap, completion rate) foram extraídos de apps.media para um novo app, apps.streaming, mesmo padrão já usado para desacoplar apps.payments de apps.communities.

Contexto

apps.media cresceu como um pipeline único (views.py 536 linhas, tasks.py 885 linhas) misturando dois domínios:

  1. Pipeline de processamento: upload, import (URL/yt-dlp), transcode+HLS, extração de áudio, transcrição (Deepgram), diarização, sumarização, stem separation (Demucs), dubbing. Todos esses estágios escrevem no mesmo Media row através de uma chain/chord Celery única (enqueue_media_processing, ADR 0004) — fortemente acoplados entre si por design.
  2. Playback analytics: MediaPlaybackSession/MediaPlaybackHeartbeat, alimentados pelo endpoint de heartbeat do player (navigator.sendBeacon) e consumidos pelo resumo de analytics/heatmap. Dependem apenas de uma FK para Media — sem nenhum acoplamento com o pipeline de processamento.

Decisão

Mover playback analytics para apps.streaming:

  • Models: MediaPlaybackSession, MediaPlaybackHeartbeat (FK cross-app para media.Media, mantendo os nomes de tabela originais media_mediaplaybacksession/media_mediaplaybackheartbeat via Meta.db_table — evita qualquer DDL na migração de mudança de app).
  • Views: MediaPlaybackHeartbeatView, MediaAnalyticsSummaryView.
  • URLs inalteradas (/api/v1/media/<id>/heartbeat/, /api/v1/media/<id>/analytics/) — zero impacto no client gerado/frontend, só o módulo Django dono do endpoint muda.
  • Migração feita com SeparateDatabaseAndState (media/migrations/0013_... + streaming/migrations/0001_initial.py): move apenas o state do Django entre apps, sem tocar nas tabelas já existentes (criadas por media/migrations/0012_...).

O pipeline de processamento (transcode/HLS, transcrição, stems, dubbing) permanece em apps.media — os campos HLS/transcript/stems/dubs vivem na mesma row de Media e a chain do Celery depende disso ficar unificado; separar exigiria fragmentar o model Media ou orquestrar tasks cross-app, custo maior que o ganho.

Consequências

  • apps.media volta a ser só "pipeline de processamento de mídia"; apps.streaming é "métricas de reprodução".
  • Uma futura feature de streaming ao vivo/analytics adicional tem um app natural para crescer sem inchar apps.media de novo.
  • Media.hls_video_url/campos HLS continuam em apps.media — não confundir apps.streaming (analytics) com "geração de HLS" (que continua no pipeline).

Strum — Documentação.