mirror of https://github.com/ErsatzTV/ErsatzTV.git
7 changed files with 122 additions and 7 deletions
@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
|
||||
namespace ErsatzTV.Application.Streaming; |
||||
|
||||
public record GetMusicVideoCreditsByPlayoutItemId(int PlayoutItemId, Option<long> SeekToMs) : IRequest<Option<string>>; |
||||
@ -0,0 +1,94 @@
@@ -0,0 +1,94 @@
|
||||
using ErsatzTV.Core; |
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Core.Interfaces.FFmpeg; |
||||
using ErsatzTV.Infrastructure.Data; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Microsoft.Extensions.Logging; |
||||
|
||||
namespace ErsatzTV.Application.Streaming; |
||||
|
||||
public class GetMusicVideoCreditsByPlayoutItemIdHandler( |
||||
IDbContextFactory<TvContext> dbContextFactory, |
||||
IMusicVideoCreditsGenerator musicVideoCreditsGenerator, |
||||
ILogger<GetMusicVideoCreditsByPlayoutItemIdHandler> logger) |
||||
: IRequestHandler<GetMusicVideoCreditsByPlayoutItemId, Option<string>> |
||||
{ |
||||
public async Task<Option<string>> Handle( |
||||
GetMusicVideoCreditsByPlayoutItemId request, |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken); |
||||
|
||||
Option<PlayoutItem> maybePlayoutItem = await dbContext.PlayoutItems |
||||
.AsNoTracking() |
||||
.Include(pi => pi.MediaItem) |
||||
.ThenInclude(mi => (mi as MusicVideo).MusicVideoMetadata) |
||||
.ThenInclude(mvm => mvm.Subtitles) |
||||
.Include(i => i.MediaItem) |
||||
.ThenInclude(mi => (mi as MusicVideo).MusicVideoMetadata) |
||||
.ThenInclude(mvm => mvm.Artists) |
||||
.Include(i => i.MediaItem) |
||||
.ThenInclude(mi => (mi as MusicVideo).MusicVideoMetadata) |
||||
.ThenInclude(mvm => mvm.Studios) |
||||
.Include(i => i.MediaItem) |
||||
.ThenInclude(mi => (mi as MusicVideo).MusicVideoMetadata) |
||||
.ThenInclude(mvm => mvm.Directors) |
||||
.Include(i => i.MediaItem) |
||||
.ThenInclude(mi => (mi as MusicVideo).MediaVersions) |
||||
.ThenInclude(mv => mv.MediaFiles) |
||||
.Include(i => i.MediaItem) |
||||
.ThenInclude(mi => (mi as MusicVideo).MediaVersions) |
||||
.ThenInclude(mv => mv.Streams) |
||||
.Include(i => i.MediaItem) |
||||
.ThenInclude(mi => (mi as MusicVideo).Artist) |
||||
.ThenInclude(mv => mv.ArtistMetadata) |
||||
.Include(pi => pi.Playout) |
||||
.ThenInclude(p => p.Channel) |
||||
.ThenInclude(c => c.FFmpegProfile) |
||||
.ThenInclude(ff => ff.Resolution) |
||||
.SingleOrDefaultAsync(pi => pi.Id == request.PlayoutItemId, cancellationToken) |
||||
.Map(Optional); |
||||
|
||||
var subtitles = new List<Subtitle>(); |
||||
foreach (PlayoutItem playoutItem in maybePlayoutItem) |
||||
{ |
||||
if (playoutItem.MediaItem is not MusicVideo musicVideo) |
||||
{ |
||||
break; |
||||
} |
||||
|
||||
switch (playoutItem.Playout.Channel.MusicVideoCreditsMode) |
||||
{ |
||||
case ChannelMusicVideoCreditsMode.GenerateSubtitles: |
||||
var fileWithExtension = $"{playoutItem.Playout.Channel.MusicVideoCreditsTemplate}.sbntxt"; |
||||
if (!string.IsNullOrWhiteSpace(fileWithExtension)) |
||||
{ |
||||
subtitles.AddRange( |
||||
await musicVideoCreditsGenerator.GenerateCreditsSubtitleFromTemplate( |
||||
musicVideo, |
||||
playoutItem.Playout.Channel.FFmpegProfile, |
||||
request.SeekToMs.Map(TimeSpan.FromMilliseconds), |
||||
Path.Combine(FileSystemLayout.MusicVideoCreditsTemplatesFolder, fileWithExtension))); |
||||
} |
||||
else |
||||
{ |
||||
logger.LogWarning( |
||||
"Music video credits template {Template} does not exist; falling back to built-in template", |
||||
fileWithExtension); |
||||
|
||||
subtitles.AddRange( |
||||
await musicVideoCreditsGenerator.GenerateCreditsSubtitle( |
||||
musicVideo, |
||||
playoutItem.Playout.Channel.FFmpegProfile)); |
||||
} |
||||
|
||||
break; |
||||
case ChannelMusicVideoCreditsMode.None: |
||||
default: |
||||
break; |
||||
} |
||||
} |
||||
|
||||
return subtitles.HeadOrNone().Map(s => s.Path); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue