Add waveform profile HTTP transport: API endpoint, public proxy, content client method

This commit is contained in:
daniel-c-harvey
2026-06-05 16:57:42 -04:00
parent 9d39843982
commit de4583b759
3 changed files with 96 additions and 0 deletions
@@ -5,7 +5,9 @@ using DeepDrftContent.Audio;
using DeepDrftContent.Constants;
using DeepDrftContent.FileDatabase.Services;
using DeepDrftContent.FileDatabase.Models;
using DeepDrftContent.Processors;
using DeepDrftData;
using DeepDrftModels.DTOs;
using Microsoft.AspNetCore.Mvc;
namespace DeepDrftAPI.Controllers;
@@ -18,6 +20,7 @@ public class TrackController : ControllerBase
private readonly WavOffsetService _wavOffsetService;
private readonly UnifiedTrackService _unifiedService;
private readonly ITrackService _sqlTrackService;
private readonly WaveformProfileService _waveformProfileService;
private readonly ILogger<TrackController> _logger;
// FileDatabase is injected directly for PutTrack because that endpoint receives a pre-processed
@@ -32,6 +35,7 @@ public class TrackController : ControllerBase
WavOffsetService wavOffsetService,
UnifiedTrackService unifiedService,
ITrackService sqlTrackService,
WaveformProfileService waveformProfileService,
ILogger<TrackController> logger)
{
_trackContentService = trackContentService;
@@ -39,6 +43,7 @@ public class TrackController : ControllerBase
_wavOffsetService = wavOffsetService;
_unifiedService = unifiedService;
_sqlTrackService = sqlTrackService;
_waveformProfileService = waveformProfileService;
_logger = logger;
}
@@ -348,6 +353,28 @@ public class TrackController : ControllerBase
}
}
// GET api/track/{trackId}/waveform (unauthenticated)
// Returns the stored waveform loudness profile for a track, base64-encoded. Public listener
// data, same auth posture as GET api/track/{trackId} streaming. 404 when no profile is stored
// (existing tracks predate profiling, or computation failed at upload — the frontend falls back
// to a flat seekbar). The "waveform" literal suffix keeps this distinct from the audio route.
[HttpGet("{trackId}/waveform")]
public async Task<ActionResult> GetWaveform(string trackId)
{
var bytes = await _waveformProfileService.GetProfileAsync(trackId);
if (bytes is null)
{
_logger.LogInformation("No waveform profile for track: {TrackId}", trackId);
return NotFound();
}
return Ok(new WaveformProfileDto
{
BucketCount = bytes.Length,
Data = Convert.ToBase64String(bytes),
});
}
[ApiKeyAuthorize]
[HttpPut("{trackId}")]
public async Task<ActionResult> PutTrack(string trackId, [FromBody] AudioBinaryDto track)