Browse Source

add stream_seek to music video credits template (#985)

pull/986/head
Jason Dove 4 years ago committed by GitHub
parent
commit
393c67213d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 16
      ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs
  3. 15
      ErsatzTV.Core/FFmpeg/FFmpegLibraryProcessService.cs
  4. 2
      ErsatzTV.Core/Interfaces/FFmpeg/IFFmpegProcessService.cs
  5. 2
      ErsatzTV.Core/Interfaces/FFmpeg/IMusicVideoCreditsGenerator.cs
  6. 4
      ErsatzTV.Infrastructure/FFmpeg/MusicVideoCreditsGenerator.cs

1
CHANGELOG.md

@ -25,6 +25,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- `artist`: the music videos artist (the parent folder) - `artist`: the music videos artist (the parent folder)
- `all_artists`: a list of additional artists from the music video's sidecar NFO metadata file - `all_artists`: a list of additional artists from the music video's sidecar NFO metadata file
- `duration`: the timespan duration of the music video, which can be used to calculate timing of additional subtitles - `duration`: the timespan duration of the music video, which can be used to calculate timing of additional subtitles
- `stream_seek`: the timespan that ffmpeg will seek into the media item before beginning playback
## [0.6.8-beta] - 2022-10-05 ## [0.6.8-beta] - 2022-10-05
### Fixed ### Fixed

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

@ -4,6 +4,7 @@ using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Domain.Filler; using ErsatzTV.Core.Domain.Filler;
using ErsatzTV.Core.Errors; using ErsatzTV.Core.Errors;
using ErsatzTV.Core.Extensions; using ErsatzTV.Core.Extensions;
using ErsatzTV.Core.FFmpeg;
using ErsatzTV.Core.Interfaces.Emby; using ErsatzTV.Core.Interfaces.Emby;
using ErsatzTV.Core.Interfaces.FFmpeg; using ErsatzTV.Core.Interfaces.FFmpeg;
using ErsatzTV.Core.Interfaces.Jellyfin; using ErsatzTV.Core.Interfaces.Jellyfin;
@ -164,8 +165,6 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler<
.GetValue<bool>(ConfigElementKey.FFmpegSaveReports) .GetValue<bool>(ConfigElementKey.FFmpegSaveReports)
.Map(result => result.IfNone(false)); .Map(result => result.IfNone(false));
List<Subtitle> subtitles = await GetSubtitles(playoutItemWithPath, channel);
Command process = await _ffmpegProcessService.ForPlayoutItem( Command process = await _ffmpegProcessService.ForPlayoutItem(
ffmpegPath, ffmpegPath,
ffprobePath, ffprobePath,
@ -175,7 +174,7 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler<
audioVersion, audioVersion,
videoPath, videoPath,
audioPath, audioPath,
subtitles, settings => GetSubtitles(playoutItemWithPath, channel, settings),
playoutItemWithPath.PlayoutItem.PreferredAudioLanguageCode ?? channel.PreferredAudioLanguageCode, playoutItemWithPath.PlayoutItem.PreferredAudioLanguageCode ?? channel.PreferredAudioLanguageCode,
playoutItemWithPath.PlayoutItem.PreferredAudioTitle ?? channel.PreferredAudioTitle, playoutItemWithPath.PlayoutItem.PreferredAudioTitle ?? channel.PreferredAudioTitle,
playoutItemWithPath.PlayoutItem.PreferredSubtitleLanguageCode ?? channel.PreferredSubtitleLanguageCode, playoutItemWithPath.PlayoutItem.PreferredSubtitleLanguageCode ?? channel.PreferredSubtitleLanguageCode,
@ -272,7 +271,8 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler<
private async Task<List<Subtitle>> GetSubtitles( private async Task<List<Subtitle>> GetSubtitles(
PlayoutItemWithPath playoutItemWithPath, PlayoutItemWithPath playoutItemWithPath,
Channel channel) Channel channel,
FFmpegPlaybackSettings settings)
{ {
List<Subtitle> allSubtitles = playoutItemWithPath.PlayoutItem.MediaItem switch List<Subtitle> allSubtitles = playoutItemWithPath.PlayoutItem.MediaItem switch
{ {
@ -282,7 +282,7 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler<
Movie movie => await Optional(movie.MovieMetadata).Flatten().HeadOrNone() Movie movie => await Optional(movie.MovieMetadata).Flatten().HeadOrNone()
.Map(mm => mm.Subtitles ?? new List<Subtitle>()) .Map(mm => mm.Subtitles ?? new List<Subtitle>())
.IfNoneAsync(new List<Subtitle>()), .IfNoneAsync(new List<Subtitle>()),
MusicVideo musicVideo => await GetMusicVideoSubtitles(musicVideo, channel), MusicVideo musicVideo => await GetMusicVideoSubtitles(musicVideo, channel, settings),
OtherVideo otherVideo => await Optional(otherVideo.OtherVideoMetadata).Flatten().HeadOrNone() OtherVideo otherVideo => await Optional(otherVideo.OtherVideoMetadata).Flatten().HeadOrNone()
.Map(mm => mm.Subtitles ?? new List<Subtitle>()) .Map(mm => mm.Subtitles ?? new List<Subtitle>())
.IfNoneAsync(new List<Subtitle>()), .IfNoneAsync(new List<Subtitle>()),
@ -323,7 +323,10 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler<
return allSubtitles; return allSubtitles;
} }
private async Task<List<Subtitle>> GetMusicVideoSubtitles(MusicVideo musicVideo, Channel channel) private async Task<List<Subtitle>> GetMusicVideoSubtitles(
MusicVideo musicVideo,
Channel channel,
FFmpegPlaybackSettings settings)
{ {
var subtitles = new List<Subtitle>(); var subtitles = new List<Subtitle>();
@ -337,6 +340,7 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler<
await _musicVideoCreditsGenerator.GenerateCreditsSubtitleFromTemplate( await _musicVideoCreditsGenerator.GenerateCreditsSubtitleFromTemplate(
musicVideo, musicVideo,
channel.FFmpegProfile, channel.FFmpegProfile,
settings,
Path.Combine(FileSystemLayout.MusicVideoCreditsTemplatesFolder, fileWithExtension))); Path.Combine(FileSystemLayout.MusicVideoCreditsTemplatesFolder, fileWithExtension)));
} }
else else

15
ErsatzTV.Core/FFmpeg/FFmpegLibraryProcessService.cs

@ -51,7 +51,7 @@ public class FFmpegLibraryProcessService : IFFmpegProcessService
MediaVersion audioVersion, MediaVersion audioVersion,
string videoPath, string videoPath,
string audioPath, string audioPath,
List<Subtitle> subtitles, Func<FFmpegPlaybackSettings, Task<List<Subtitle>>> getSubtitles,
string preferredAudioLanguage, string preferredAudioLanguage,
string preferredAudioTitle, string preferredAudioTitle,
string preferredSubtitleLanguage, string preferredSubtitleLanguage,
@ -80,12 +80,6 @@ public class FFmpegLibraryProcessService : IFFmpegProcessService
channel.Number, channel.Number,
preferredAudioLanguage, preferredAudioLanguage,
preferredAudioTitle); preferredAudioTitle);
Option<Subtitle> maybeSubtitle =
await _ffmpegStreamSelector.SelectSubtitleStream(
subtitles,
channel,
preferredSubtitleLanguage,
subtitleMode);
FFmpegPlaybackSettings playbackSettings = _playbackSettingsCalculator.CalculateSettings( FFmpegPlaybackSettings playbackSettings = _playbackSettingsCalculator.CalculateSettings(
channel.StreamingMode, channel.StreamingMode,
@ -100,6 +94,13 @@ public class FFmpegLibraryProcessService : IFFmpegProcessService
hlsRealtime, hlsRealtime,
targetFramerate); targetFramerate);
Option<Subtitle> maybeSubtitle =
await _ffmpegStreamSelector.SelectSubtitleStream(
await getSubtitles(playbackSettings),
channel,
preferredSubtitleLanguage,
subtitleMode);
Option<WatermarkOptions> watermarkOptions = disableWatermarks Option<WatermarkOptions> watermarkOptions = disableWatermarks
? None ? None
: await _ffmpegProcessService.GetWatermarkOptions( : await _ffmpegProcessService.GetWatermarkOptions(

2
ErsatzTV.Core/Interfaces/FFmpeg/IFFmpegProcessService.cs

@ -17,7 +17,7 @@ public interface IFFmpegProcessService
MediaVersion audioVersion, MediaVersion audioVersion,
string videoPath, string videoPath,
string audioPath, string audioPath,
List<Subtitle> subtitles, Func<FFmpegPlaybackSettings, Task<List<Subtitle>>> getSubtitles,
string preferredAudioLanguage, string preferredAudioLanguage,
string preferredAudioTitle, string preferredAudioTitle,
string preferredSubtitleLanguage, string preferredSubtitleLanguage,

2
ErsatzTV.Core/Interfaces/FFmpeg/IMusicVideoCreditsGenerator.cs

@ -1,4 +1,5 @@
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.FFmpeg;
namespace ErsatzTV.Core.Interfaces.FFmpeg; namespace ErsatzTV.Core.Interfaces.FFmpeg;
@ -9,5 +10,6 @@ public interface IMusicVideoCreditsGenerator
Task<Option<Subtitle>> GenerateCreditsSubtitleFromTemplate( Task<Option<Subtitle>> GenerateCreditsSubtitleFromTemplate(
MusicVideo musicVideo, MusicVideo musicVideo,
FFmpegProfile ffmpegProfile, FFmpegProfile ffmpegProfile,
FFmpegPlaybackSettings settings,
string templateFileName); string templateFileName);
} }

4
ErsatzTV.Infrastructure/FFmpeg/MusicVideoCreditsGenerator.cs

@ -94,6 +94,7 @@ public class MusicVideoCreditsGenerator : IMusicVideoCreditsGenerator
public async Task<Option<Subtitle>> GenerateCreditsSubtitleFromTemplate( public async Task<Option<Subtitle>> GenerateCreditsSubtitleFromTemplate(
MusicVideo musicVideo, MusicVideo musicVideo,
FFmpegProfile ffmpegProfile, FFmpegProfile ffmpegProfile,
FFmpegPlaybackSettings settings,
string templateFileName) string templateFileName)
{ {
try try
@ -119,7 +120,8 @@ public class MusicVideoCreditsGenerator : IMusicVideoCreditsGenerator
metadata.ReleaseDate, metadata.ReleaseDate,
AllArtists = (metadata.Artists ?? new List<MusicVideoArtist>()).Map(a => a.Name), AllArtists = (metadata.Artists ?? new List<MusicVideoArtist>()).Map(a => a.Name),
Artist = artist, Artist = artist,
musicVideo.GetHeadVersion().Duration musicVideo.GetHeadVersion().Duration,
settings.StreamSeek
}); });
string fileName = _tempFilePool.GetNextTempFile(TempFileCategory.Subtitle); string fileName = _tempFilePool.GetNextTempFile(TempFileCategory.Subtitle);

Loading…
Cancel
Save