Implement media storage and processing features: update configuration in .env.example and appsettings files, enhance Docker setup for media storage, and add media-related services and database entities. Include ffmpeg for media handling and adjust Kestrel settings for large file uploads.
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using TeleWave.Domain.Auth;
|
||||
using TeleWave.Domain.Media;
|
||||
|
||||
namespace TeleWave.Application.Common.Interfaces;
|
||||
|
||||
public interface IAppDbContext
|
||||
{
|
||||
DbSet<RefreshToken> RefreshTokens { get; }
|
||||
DbSet<MediaAsset> MediaAssets { get; }
|
||||
|
||||
Task<int> SaveChangesAsync(CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace TeleWave.Application.Common.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Очередь фоновой обработки ассетов. Продюсеры (endpoint загрузки, inbox-сканер) ставят id ассета,
|
||||
/// единственный фоновый потребитель обрабатывает по одному за раз.
|
||||
/// </summary>
|
||||
public interface IMediaProcessingQueue
|
||||
{
|
||||
void Enqueue(Guid assetId);
|
||||
|
||||
IAsyncEnumerable<Guid> DequeueAllAsync(CancellationToken cancellationToken);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using TeleWave.Domain.Media;
|
||||
|
||||
namespace TeleWave.Application.Common.Interfaces;
|
||||
|
||||
/// <summary>Итог нормализации и нарезки исходника в HLS-сегменты.</summary>
|
||||
public sealed record MediaProcessingResult(
|
||||
TimeSpan Duration,
|
||||
int SegmentSeconds,
|
||||
int SegmentCount,
|
||||
int Width,
|
||||
int Height,
|
||||
string VideoCodec,
|
||||
string AudioCodec,
|
||||
string RelativePath
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Порт обработки медиа (ffprobe + ffmpeg). Реализация читает исходник по <paramref name="assetId"/>
|
||||
/// и <paramref name="extension"/> из хранилища, нормализует в H.264/AAC и режет на сегменты
|
||||
/// фиксированной длины, добивая длительность до кратности сегменту.
|
||||
/// </summary>
|
||||
public interface IMediaProcessor
|
||||
{
|
||||
Task<MediaProcessingResult> ProcessAsync(
|
||||
Guid assetId,
|
||||
string extension,
|
||||
CancellationToken cancellationToken
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using TeleWave.Domain.Media;
|
||||
|
||||
namespace TeleWave.Application.Common.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Порт файлового хранилища медиа. Все относительные пути резолвятся строго внутри корня
|
||||
/// (<c>Storage:RootPath</c>) — защита от path traversal лежит на реализации.
|
||||
/// </summary>
|
||||
public interface IMediaStorage
|
||||
{
|
||||
/// <summary>Свободное место на томе хранилища, байт.</summary>
|
||||
long GetAvailableFreeSpaceBytes();
|
||||
|
||||
/// <summary>
|
||||
/// Стримит загружаемый контент во временный файл в <c>uploads/</c> без буферизации в память.
|
||||
/// Возвращает непрозрачный токен (имя временного файла) для последующего <see cref="PromoteToOriginalAsync"/>.
|
||||
/// </summary>
|
||||
Task<string> SaveUploadAsync(Stream content, string extension, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>Удаляет временный файл загрузки (откат при ошибке до регистрации ассета).</summary>
|
||||
void DeleteUpload(string uploadToken);
|
||||
|
||||
/// <summary>
|
||||
/// Переносит исходник из источника (<c>uploads/</c> для <see cref="MediaSource.Upload"/> либо
|
||||
/// <c>inbox/</c> для <see cref="MediaSource.Inbox"/>) в <c>originals/{assetId}{ext}</c>.
|
||||
/// </summary>
|
||||
Task PromoteToOriginalAsync(
|
||||
MediaSource source,
|
||||
string sourceToken,
|
||||
Guid assetId,
|
||||
string extension,
|
||||
CancellationToken cancellationToken
|
||||
);
|
||||
|
||||
/// <summary>Удаляет все артефакты ассета: исходник в <c>originals/</c> и каталог сегментов <c>assets/{id}/</c>.</summary>
|
||||
void DeleteAssetArtifacts(Guid assetId, string extension);
|
||||
}
|
||||
Reference in New Issue
Block a user