Browse Source

add default song album art; adjust default blurhashes (#1946)

* fix song progress on white backgrounds

* remove yellow from default song backgrounds

* add default album art for generated song images

* update changelog
pull/1948/head
Jason Dove 9 months ago committed by GitHub
parent
commit
dc112f0c7d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 67
      ErsatzTV.Core/FFmpeg/SongVideoGenerator.cs
  3. 3
      ErsatzTV.FFmpeg/Filter/SongProgressFilter.cs
  4. 3
      ErsatzTV/ErsatzTV.csproj
  5. BIN
      ErsatzTV/Resources/song_album_cover_512.png
  6. BIN
      ErsatzTV/Resources/song_background_1.png
  7. BIN
      ErsatzTV/Resources/song_background_2.png
  8. BIN
      ErsatzTV/Resources/song_background_3.png
  9. 3
      ErsatzTV/Services/RunOnce/ResourceExtractorService.cs

1
CHANGELOG.md

@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Add `Song Video Mode` to channel settings
- `Default` - existing behavior
- `With Progress` - show animated progress bar at bottom of generated video
- Add fallback album art image for songs that have no album art
### Changed
- **BREAKING CHANGE**: Change channel identifiers used in XMLTV to work around bad behavior in Plex

67
ErsatzTV.Core/FFmpeg/SongVideoGenerator.cs

@ -126,18 +126,15 @@ public class SongVideoGenerator : ISongVideoGenerator @@ -126,18 +126,15 @@ public class SongVideoGenerator : ISongVideoGenerator
int leftMarginPercent = HORIZONTAL_MARGIN_PERCENT;
int rightMarginPercent = HORIZONTAL_MARGIN_PERCENT;
if (metadata.Artwork.Any(a => a.ArtworkKind == ArtworkKind.Thumbnail))
switch (watermarkLocation)
{
switch (watermarkLocation)
{
case WatermarkLocation.BottomLeft:
leftMarginPercent += WATERMARK_WIDTH_PERCENT + HORIZONTAL_MARGIN_PERCENT;
break;
case WatermarkLocation.BottomRight:
leftMarginPercent = rightMarginPercent = HORIZONTAL_MARGIN_PERCENT;
rightMarginPercent += WATERMARK_WIDTH_PERCENT + HORIZONTAL_MARGIN_PERCENT;
break;
}
case WatermarkLocation.BottomLeft:
leftMarginPercent += WATERMARK_WIDTH_PERCENT + HORIZONTAL_MARGIN_PERCENT;
break;
case WatermarkLocation.BottomRight:
leftMarginPercent = rightMarginPercent = HORIZONTAL_MARGIN_PERCENT;
rightMarginPercent += WATERMARK_WIDTH_PERCENT + HORIZONTAL_MARGIN_PERCENT;
break;
}
var leftMargin = (int)Math.Round(leftMarginPercent / 100.0 * channel.FFmpegProfile.Resolution.Width);
@ -161,30 +158,40 @@ public class SongVideoGenerator : ISongVideoGenerator @@ -161,30 +158,40 @@ public class SongVideoGenerator : ISongVideoGenerator
.BuildFile();
// use thumbnail (cover art) if present
foreach (Artwork artwork in Optional(
metadata.Artwork.Find(a => a.ArtworkKind == ArtworkKind.Thumbnail)))
// fall back to default art
Artwork artwork = await Optional(metadata.Artwork.Find(a => a.ArtworkKind == ArtworkKind.Thumbnail))
.IfNoneAsync(
new Artwork
{
Id = 0,
ArtworkKind = ArtworkKind.Thumbnail,
Path = Path.Combine(FileSystemLayout.ResourcesCacheFolder, "song_album_cover_512.png"),
});
// signal that we want to use cover art as watermark
videoVersion = new CoverArtMediaVersion
{
// signal that we want to use cover art as watermark
videoVersion = new CoverArtMediaVersion
Chapters = [],
// always stretch cover art
Width = 192,
Height = 108,
SampleAspectRatio = "1:1",
Streams = new List<MediaStream>
{
Chapters = new List<MediaChapter>(),
// always stretch cover art
Width = 192,
Height = 108,
SampleAspectRatio = "1:1",
Streams = new List<MediaStream>
{
new() { MediaStreamKind = MediaStreamKind.Video, Index = 0 }
}
};
new() { MediaStreamKind = MediaStreamKind.Video, Index = 0 }
}
};
string customPath = _imageCache.GetPathForImage(
artwork.Path,
ArtworkKind.Thumbnail,
Option<int>.None);
string customPath = _imageCache.GetPathForImage(
artwork.Path,
ArtworkKind.Thumbnail,
Option<int>.None);
watermarkPath = customPath;
watermarkPath = customPath;
// only blurhash real album art
if (artwork.Id > 0)
{
// randomize selected blur hash
var hashes = new List<string>
{

3
ErsatzTV.FFmpeg/Filter/SongProgressFilter.cs

@ -17,11 +17,12 @@ public class SongProgressFilter(FrameSize frameSize, Option<TimeSpan> maybeStart @@ -17,11 +17,12 @@ public class SongProgressFilter(FrameSize frameSize, Option<TimeSpan> maybeStart
double alreadyPlayed = start.TotalSeconds / finish.TotalSeconds;
double scale = 1 - alreadyPlayed;
var generateGrayBar = $"color=c=#323232:s={width}x{height},format=rgba,colorchannelmixer=aa=0.4";
var generateWhiteBar = $"color=c=white:s={width}x{height}";
var scaleToFullWidth = $"scale=iw*{alreadyPlayed}+iw*(t/{seconds})*{scale}:ih:eval=frame";
var overlayBar = "overlay=W*0.05:H-h-H*0.05:shortest=1:enable='gt(t,0.1)'";
return $"loop=-1:1[si],{generateWhiteBar},format=rgba,colorchannelmixer=aa=0.9,{scaleToFullWidth}[sbar];[si][sbar]{overlayBar}";
return $"loop=-1:1[si],{generateGrayBar}[gray];{generateWhiteBar},format=rgba,colorchannelmixer=aa=0.9,{scaleToFullWidth}[sbar];[si][gray]{overlayBar}[sgray];[sgray][sbar]{overlayBar}";
}
return string.Empty;

3
ErsatzTV/ErsatzTV.csproj

@ -71,10 +71,11 @@ @@ -71,10 +71,11 @@
<EmbeddedResource Include="Resources\Scripts\_threePartEpisodes.js" />
<EmbeddedResource Include="Resources\Scripts\_episode.js" />
<EmbeddedResource Include="Resources\Scripts\_movie.js" />
<EmbeddedResource Include="Resources\song_progress_overlay.png" />
<EmbeddedResource Include="Resources\song_album_cover_512.png" />
<EmbeddedResource Include="Resources\song_background_1.png" />
<EmbeddedResource Include="Resources\song_background_2.png" />
<EmbeddedResource Include="Resources\song_background_3.png" />
<EmbeddedResource Include="Resources\song_progress_overlay.png" />
<EmbeddedResource Include="Resources\ErsatzTV.png" />
<EmbeddedResource Include="Resources\ISO-639-2_utf-8.txt" />
<EmbeddedResource Include="Resources\Templates\_default.ass.sbntxt" />

BIN
ErsatzTV/Resources/song_album_cover_512.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

BIN
ErsatzTV/Resources/song_background_1.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 KiB

After

Width:  |  Height:  |  Size: 257 KiB

BIN
ErsatzTV/Resources/song_background_2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 KiB

After

Width:  |  Height:  |  Size: 327 KiB

BIN
ErsatzTV/Resources/song_background_3.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 384 KiB

After

Width:  |  Height:  |  Size: 332 KiB

3
ErsatzTV/Services/RunOnce/ResourceExtractorService.cs

@ -17,10 +17,11 @@ public class ResourceExtractorService : BackgroundService @@ -17,10 +17,11 @@ public class ResourceExtractorService : BackgroundService
Assembly assembly = typeof(ResourceExtractorService).GetTypeInfo().Assembly;
await ExtractResource(assembly, "background.png", stoppingToken);
await ExtractResource(assembly, "song_progress_overlay.png", stoppingToken);
await ExtractResource(assembly, "song_album_cover_512.png", stoppingToken);
await ExtractResource(assembly, "song_background_1.png", stoppingToken);
await ExtractResource(assembly, "song_background_2.png", stoppingToken);
await ExtractResource(assembly, "song_background_3.png", stoppingToken);
await ExtractResource(assembly, "song_progress_overlay.png", stoppingToken);
await ExtractResource(assembly, "ErsatzTV.png", stoppingToken);
await ExtractFontResource(assembly, "Sen.ttf", stoppingToken);

Loading…
Cancel
Save