Browse Source

add more fields to music video credit templates (#1210)

pull/1211/head
Jason Dove 3 years ago committed by GitHub
parent
commit
b2f7bcaf1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      CHANGELOG.md
  2. 6
      ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs
  3. 1
      ErsatzTV.Core/Domain/Metadata/MusicVideoMetadata.cs
  4. 1
      ErsatzTV.Core/Interfaces/Repositories/IMusicVideoRepository.cs
  5. 4
      ErsatzTV.Infrastructure/Data/Configurations/Metadata/MusicVideoMetadataConfiguration.cs
  6. 11
      ErsatzTV.Infrastructure/Data/Repositories/MusicVideoRepository.cs
  7. 2
      ErsatzTV.Infrastructure/FFmpeg/MusicVideoCreditsGenerator.cs
  8. 4429
      ErsatzTV.Infrastructure/Migrations/20230316002451_Add_MusicVideo_Directors.Designer.cs
  9. 49
      ErsatzTV.Infrastructure/Migrations/20230316002451_Add_MusicVideo_Directors.cs
  10. 12
      ErsatzTV.Infrastructure/Migrations/TvContextModelSnapshot.cs
  11. 15
      ErsatzTV.Scanner.Tests/Core/Metadata/Nfo/MusicVideoNfoReaderTests.cs
  12. 23
      ErsatzTV.Scanner/Core/Metadata/LocalMetadataProvider.cs
  13. 2
      ErsatzTV.Scanner/Core/Metadata/Nfo/MusicVideoNfo.cs
  14. 6
      ErsatzTV.Scanner/Core/Metadata/Nfo/MusicVideoNfoReader.cs
  15. 2
      ErsatzTV/Resources/Templates/_ArtistTitleAlbum_CenterTop.sbntxt

2
CHANGELOG.md

@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased]
### Added
- Add `Troubleshooting` page with aggregated settings/hardware accel info for easy reference
- Read `director` fields from music video NFO metadata
- Pass `directors` and `studios` to music video credit templates
### Fixed
- Fix scaling anamorphic content from non-local libraries

6
ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs

@ -98,6 +98,12 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler< @@ -98,6 +98,12 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler<
.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)

1
ErsatzTV.Core/Domain/Metadata/MusicVideoMetadata.cs

@ -8,4 +8,5 @@ public class MusicVideoMetadata : Metadata @@ -8,4 +8,5 @@ public class MusicVideoMetadata : Metadata
public int MusicVideoId { get; set; }
public MusicVideo MusicVideo { get; set; }
public List<MusicVideoArtist> Artists { get; set; }
public List<Director> Directors { get; set; }
}

1
ErsatzTV.Core/Interfaces/Repositories/IMusicVideoRepository.cs

@ -16,6 +16,7 @@ public interface IMusicVideoRepository @@ -16,6 +16,7 @@ public interface IMusicVideoRepository
Task<bool> AddGenre(MusicVideoMetadata metadata, Genre genre);
Task<bool> AddTag(MusicVideoMetadata metadata, Tag tag);
Task<bool> AddStudio(MusicVideoMetadata metadata, Studio studio);
Task<bool> AddDirector(MusicVideoMetadata metadata, Director director);
Task<bool> RemoveArtist(MusicVideoArtist artist);
Task<List<MusicVideoMetadata>> GetMusicVideosForCards(List<int> ids);
Task<IEnumerable<string>> FindOrphanPaths(LibraryPath libraryPath);

4
ErsatzTV.Infrastructure/Data/Configurations/Metadata/MusicVideoMetadataConfiguration.cs

@ -41,5 +41,9 @@ public class MusicVideoMetadataConfiguration : IEntityTypeConfiguration<MusicVid @@ -41,5 +41,9 @@ public class MusicVideoMetadataConfiguration : IEntityTypeConfiguration<MusicVid
builder.HasMany(mvm => mvm.Artists)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
builder.HasMany(mvm => mvm.Directors)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
}
}

11
ErsatzTV.Infrastructure/Data/Repositories/MusicVideoRepository.cs

@ -33,6 +33,8 @@ public class MusicVideoRepository : IMusicVideoRepository @@ -33,6 +33,8 @@ public class MusicVideoRepository : IMusicVideoRepository
.ThenInclude(mvm => mvm.Tags)
.Include(mv => mv.MusicVideoMetadata)
.ThenInclude(mvm => mvm.Studios)
.Include(mv => mv.MusicVideoMetadata)
.ThenInclude(mvm => mvm.Directors)
.Include(mv => mv.LibraryPath)
.ThenInclude(lp => lp.Library)
.Include(mv => mv.MediaVersions)
@ -134,6 +136,14 @@ public class MusicVideoRepository : IMusicVideoRepository @@ -134,6 +136,14 @@ public class MusicVideoRepository : IMusicVideoRepository
new { studio.Name, MetadataId = metadata.Id }).Map(result => result > 0);
}
public async Task<bool> AddDirector(MusicVideoMetadata metadata, Director director)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
return await dbContext.Connection.ExecuteAsync(
"INSERT INTO Director (Name, MusicVideoMetadataId) VALUES (@Name, @MetadataId)",
new { director.Name, MetadataId = metadata.Id }).Map(result => result > 0);
}
public async Task<bool> RemoveArtist(MusicVideoArtist artist)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
@ -191,6 +201,7 @@ public class MusicVideoRepository : IMusicVideoRepository @@ -191,6 +201,7 @@ public class MusicVideoRepository : IMusicVideoRepository
.Include(m => m.Genres)
.Include(m => m.Tags)
.Include(m => m.Studios)
.Include(m => m.Directors)
.Include(m => m.MusicVideo)
.ThenInclude(mv => mv.Artist)
.ThenInclude(a => a.ArtistMetadata)

2
ErsatzTV.Infrastructure/FFmpeg/MusicVideoCreditsGenerator.cs

@ -120,6 +120,8 @@ public class MusicVideoCreditsGenerator : IMusicVideoCreditsGenerator @@ -120,6 +120,8 @@ public class MusicVideoCreditsGenerator : IMusicVideoCreditsGenerator
metadata.ReleaseDate,
AllArtists = (metadata.Artists ?? new List<MusicVideoArtist>()).Map(a => a.Name),
Artist = artist,
Studios = (metadata.Studios ?? new List<Studio>()).Map(s => s.Name),
Directors = (metadata.Directors ?? new List<Director>()).Map(s => s.Name),
musicVideo.GetHeadVersion().Duration,
StreamSeek = await settings.StreamSeek.IfNoneAsync(TimeSpan.Zero)
});

4429
ErsatzTV.Infrastructure/Migrations/20230316002451_Add_MusicVideo_Directors.Designer.cs generated

File diff suppressed because it is too large Load Diff

49
ErsatzTV.Infrastructure/Migrations/20230316002451_Add_MusicVideo_Directors.cs

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ErsatzTV.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class Add_MusicVideo_Directors : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "MusicVideoMetadataId",
table: "Director",
type: "INTEGER",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Director_MusicVideoMetadataId",
table: "Director",
column: "MusicVideoMetadataId");
migrationBuilder.AddForeignKey(
name: "FK_Director_MusicVideoMetadata_MusicVideoMetadataId",
table: "Director",
column: "MusicVideoMetadataId",
principalTable: "MusicVideoMetadata",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Director_MusicVideoMetadata_MusicVideoMetadataId",
table: "Director");
migrationBuilder.DropIndex(
name: "IX_Director_MusicVideoMetadataId",
table: "Director");
migrationBuilder.DropColumn(
name: "MusicVideoMetadataId",
table: "Director");
}
}
}

12
ErsatzTV.Infrastructure/Migrations/TvContextModelSnapshot.cs

@ -397,6 +397,9 @@ namespace ErsatzTV.Infrastructure.Migrations @@ -397,6 +397,9 @@ namespace ErsatzTV.Infrastructure.Migrations
b.Property<int?>("MovieMetadataId")
.HasColumnType("INTEGER");
b.Property<int?>("MusicVideoMetadataId")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.HasColumnType("TEXT");
@ -409,6 +412,8 @@ namespace ErsatzTV.Infrastructure.Migrations @@ -409,6 +412,8 @@ namespace ErsatzTV.Infrastructure.Migrations
b.HasIndex("MovieMetadataId");
b.HasIndex("MusicVideoMetadataId");
b.HasIndex("OtherVideoMetadataId");
b.ToTable("Director", (string)null);
@ -2857,6 +2862,11 @@ namespace ErsatzTV.Infrastructure.Migrations @@ -2857,6 +2862,11 @@ namespace ErsatzTV.Infrastructure.Migrations
.HasForeignKey("MovieMetadataId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null)
.WithMany("Directors")
.HasForeignKey("MusicVideoMetadataId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null)
.WithMany("Directors")
.HasForeignKey("OtherVideoMetadataId")
@ -4206,6 +4216,8 @@ namespace ErsatzTV.Infrastructure.Migrations @@ -4206,6 +4216,8 @@ namespace ErsatzTV.Infrastructure.Migrations
b.Navigation("Artwork");
b.Navigation("Directors");
b.Navigation("Genres");
b.Navigation("Guids");

15
ErsatzTV.Scanner.Tests/Core/Metadata/Nfo/MusicVideoNfoReaderTests.cs

@ -182,6 +182,21 @@ Le groupe a également enregistré une version espagnole de ce titre, La reina d @@ -182,6 +182,21 @@ Le groupe a également enregistré une version espagnole de ce titre, La reina d
nfo.Studios.Should().BeEquivalentTo(new List<string> { "Test Studio" });
}
}
[Test]
public async Task MetadataNfo_With_Directors_Should_Return_Nfo()
{
await using var stream = new MemoryStream(
Encoding.UTF8.GetBytes(@"<musicvideo><director>Test Director</director></musicvideo>"));
Either<BaseError, MusicVideoNfo> result = await _musicVideoNfoReader.Read(stream);
result.IsRight.Should().BeTrue();
foreach (MusicVideoNfo nfo in result.RightToSeq())
{
nfo.Directors.Should().BeEquivalentTo(new List<string> { "Test Director" });
}
}
private static string NormalizeLineEndingsLF(string str) =>
str

23
ErsatzTV.Scanner/Core/Metadata/LocalMetadataProvider.cs

@ -278,7 +278,8 @@ public class LocalMetadataProvider : ILocalMetadataProvider @@ -278,7 +278,8 @@ public class LocalMetadataProvider : ILocalMetadataProvider
Artists = nfo.Artists.Map(a => new MusicVideoArtist { Name = a }).ToList(),
Genres = nfo.Genres.Map(g => new Genre { Name = g }).ToList(),
Tags = nfo.Tags.Map(t => new Tag { Name = t }).ToList(),
Studios = nfo.Studios.Map(s => new Studio { Name = s }).ToList()
Studios = nfo.Studios.Map(s => new Studio { Name = s }).ToList(),
Directors = nfo.Directors.Map(s => new Director { Name = s }).ToList()
};
}
@ -832,6 +833,26 @@ public class LocalMetadataProvider : ILocalMetadataProvider @@ -832,6 +833,26 @@ public class LocalMetadataProvider : ILocalMetadataProvider
updated = true;
}
}
foreach (Director director in existing.Directors
.Filter(d => metadata.Directors.All(d2 => d2.Name != d.Name)).ToList())
{
existing.Directors.Remove(director);
if (await _metadataRepository.RemoveDirector(director))
{
updated = true;
}
}
foreach (Director director in metadata.Directors
.Filter(d => existing.Directors.All(d2 => d2.Name != d.Name)).ToList())
{
existing.Directors.Add(director);
if (await _musicVideoRepository.AddDirector(existing, director))
{
updated = true;
}
}
return await _metadataRepository.Update(existing) || updated;
}

2
ErsatzTV.Scanner/Core/Metadata/Nfo/MusicVideoNfo.cs

@ -8,6 +8,7 @@ public class MusicVideoNfo @@ -8,6 +8,7 @@ public class MusicVideoNfo
Genres = new List<string>();
Tags = new List<string>();
Studios = new List<string>();
Directors = new List<string>();
}
public List<string> Artists { get; }
@ -20,4 +21,5 @@ public class MusicVideoNfo @@ -20,4 +21,5 @@ public class MusicVideoNfo
public List<string> Genres { get; }
public List<string> Tags { get; }
public List<string> Studios { get; }
public List<string> Directors { get; }
}

6
ErsatzTV.Scanner/Core/Metadata/Nfo/MusicVideoNfoReader.cs

@ -91,6 +91,12 @@ public class MusicVideoNfoReader : NfoReader<MusicVideoNfo>, IMusicVideoNfoReade @@ -91,6 +91,12 @@ public class MusicVideoNfoReader : NfoReader<MusicVideoNfo>, IMusicVideoNfoReade
nfo,
(musicVideo, studio) => musicVideo.Studios.Add(studio));
break;
case "director":
await ReadStringContent(
reader,
nfo,
(musicVideo, director) => musicVideo.Directors.Add(director));
break;
}
break;

2
ErsatzTV/Resources/Templates/_ArtistTitleAlbum_CenterTop.sbntxt

@ -24,7 +24,7 @@ Style: RoboR,Roboto-Regular.ttf,{{ resolution.height // 20.0 }},&HFFFFFF,&HFFFFF @@ -24,7 +24,7 @@ Style: RoboR,Roboto-Regular.ttf,{{ resolution.height // 20.0 }},&HFFFFFF,&HFFFFF
{{~ _last_end_ts = timespan.from_seconds (_duration_s | math.minus 9) ~}}
{{~ if all_artists | array.size == 0 ~}}
{{~ capture _artists_t ~}}{{~ artist ~}}{{~ end ~}}
{{ else }}
{{~ else ~}}
{{~ capture _artists_t ~}}{{~ all_artists | array.join " | " ~}}{{~ end ~}}
{{~ end ~}}
{{~ capture _fancy_title_t ~}}{%{{\b1}{\fscy150}{\1c&HC2C1BF&}}%}{{~ title ~}}{{~ end ~}}

Loading…
Cancel
Save