Browse Source

fix content_total_duration in graphics engine (#2643)

pull/2644/head
Jason Dove 9 months ago committed by GitHub
parent
commit
6603500132
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      CHANGELOG.md
  2. 2
      ErsatzTV.Application/Streaming/Queries/GetPlayoutItemProcessByChannelNumberHandler.cs
  3. 1
      ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlaybackHandler.cs
  4. 4
      ErsatzTV.Core/FFmpeg/FFmpegLibraryProcessService.cs
  5. 1
      ErsatzTV.Core/Interfaces/FFmpeg/IFFmpegProcessService.cs
  6. 3
      ErsatzTV.Core/Interfaces/Streaming/GraphicsEngineContext.cs
  7. 20
      ErsatzTV.Core/Scheduling/BlockScheduling/BlockPlayoutFillerBuilder.cs
  8. 2
      ErsatzTV.Infrastructure/Streaming/Graphics/GraphicsEngine.cs
  9. 2
      ErsatzTV.Scanner.Tests/Core/FFmpeg/TranscodingTests.cs

4
CHANGELOG.md

@ -50,7 +50,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- All `etv:` nodes will be stripped from the XMLTV data when requested by a client - All `etv:` nodes will be stripped from the XMLTV data when requested by a client
- Add channel troubleshooting button to channels list - Add channel troubleshooting button to channels list
- This will open the playback troubleshooting tool in "channel" mode - This will open the playback troubleshooting tool in "channel" mode
- This mode requires entering a date and time, and will play up to 30 seconds of *one item from that channel's playout* - This mode requires entering a date and time, and will play up to 30 seconds of *one item from that channel's playout* starting at the entered date and time
### Fixed ### Fixed
- Fix HLS Direct playback with Jellyfin 10.11 - Fix HLS Direct playback with Jellyfin 10.11
@ -75,6 +75,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Fix (3 year old) bug removing tags from local libraries when they are removed from NFO files (all content types) - Fix (3 year old) bug removing tags from local libraries when they are removed from NFO files (all content types)
- New scans will properly remove old tags; NFO files may need to be touched to force updating during a scan - New scans will properly remove old tags; NFO files may need to be touched to force updating during a scan
- Fix bug where looping motion graphics wouldn't be displayed when seeking into second half of content - Fix bug where looping motion graphics wouldn't be displayed when seeking into second half of content
- Fix `content_total_duration` value in graphics engine opacity expressions
- This bug caused some graphics elements to display too early after first joining a channel
### Changed ### Changed
- Use smaller batch size for search index updates (100, down from 1000) - Use smaller batch size for search index updates (100, down from 1000)

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

@ -280,6 +280,7 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler<
TimeSpan outPoint = playoutItemWithPath.PlayoutItem.OutPoint; TimeSpan outPoint = playoutItemWithPath.PlayoutItem.OutPoint;
DateTimeOffset effectiveNow = request.StartAtZero ? start : now; DateTimeOffset effectiveNow = request.StartAtZero ? start : now;
TimeSpan duration = finish - effectiveNow; TimeSpan duration = finish - effectiveNow;
TimeSpan originalDuration = duration;
bool isComplete = true; bool isComplete = true;
@ -434,6 +435,7 @@ public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler<
start, start,
finish, finish,
effectiveNow, effectiveNow,
originalDuration,
watermarks, watermarks,
graphicsElements, graphicsElements,
channel.FFmpegProfile.VaapiDisplay, channel.FFmpegProfile.VaapiDisplay,

1
ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlaybackHandler.cs

@ -303,6 +303,7 @@ public class PrepareTroubleshootingPlaybackHandler(
now, now,
now + duration, now + duration,
now, now,
duration,
watermarks, watermarks,
graphicsElements.Map(ge => new PlayoutItemGraphicsElement { GraphicsElement = ge }).ToList(), graphicsElements.Map(ge => new PlayoutItemGraphicsElement { GraphicsElement = ge }).ToList(),
ffmpegProfile.VaapiDisplay, ffmpegProfile.VaapiDisplay,

4
ErsatzTV.Core/FFmpeg/FFmpegLibraryProcessService.cs

@ -85,6 +85,7 @@ public class FFmpegLibraryProcessService : IFFmpegProcessService
DateTimeOffset start, DateTimeOffset start,
DateTimeOffset finish, DateTimeOffset finish,
DateTimeOffset now, DateTimeOffset now,
TimeSpan originalContentDuration,
List<WatermarkOptions> watermarks, List<WatermarkOptions> watermarks,
List<PlayoutItemGraphicsElement> graphicsElements, List<PlayoutItemGraphicsElement> graphicsElements,
string vaapiDisplay, string vaapiDisplay,
@ -530,7 +531,8 @@ public class FFmpegLibraryProcessService : IFFmpegProcessService
channelStartTime, channelStartTime,
start, start,
await playbackSettings.StreamSeek.IfNoneAsync(TimeSpan.Zero), await playbackSettings.StreamSeek.IfNoneAsync(TimeSpan.Zero),
finish - now); finish - now,
originalContentDuration);
context = await _graphicsElementLoader.LoadAll(context, graphicsElements, cancellationToken); context = await _graphicsElementLoader.LoadAll(context, graphicsElements, cancellationToken);

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

@ -26,6 +26,7 @@ public interface IFFmpegProcessService
DateTimeOffset start, DateTimeOffset start,
DateTimeOffset finish, DateTimeOffset finish,
DateTimeOffset now, DateTimeOffset now,
TimeSpan originalContentDuration,
List<WatermarkOptions> watermarks, List<WatermarkOptions> watermarks,
List<PlayoutItemGraphicsElement> graphicsElements, List<PlayoutItemGraphicsElement> graphicsElements,
string vaapiDisplay, string vaapiDisplay,

3
ErsatzTV.Core/Interfaces/Streaming/GraphicsEngineContext.cs

@ -15,7 +15,8 @@ public record GraphicsEngineContext(
DateTimeOffset ChannelStartTime, DateTimeOffset ChannelStartTime,
DateTimeOffset ContentStartTime, DateTimeOffset ContentStartTime,
TimeSpan Seek, TimeSpan Seek,
TimeSpan Duration); TimeSpan Duration,
TimeSpan ContentTotalDuration);
public abstract record GraphicsElementContext; public abstract record GraphicsElementContext;

20
ErsatzTV.Core/Scheduling/BlockScheduling/BlockPlayoutFillerBuilder.cs

@ -65,18 +65,15 @@ public class BlockPlayoutFillerBuilder(
var collectionEnumerators = new Dictionary<CollectionKey, IMediaCollectionEnumerator>(); var collectionEnumerators = new Dictionary<CollectionKey, IMediaCollectionEnumerator>();
// history doesn't have an equivalent to "remove before"
// so for break content, let's remove all corresponding items that should be removed
var itemsForBreakContent = allItems.Where(x => x.FinishOffset >= removeBefore).ToList();
var breakContentResult = await AddBreakContent( var breakContentResult = await AddBreakContent(
playout, playout,
referenceData, referenceData,
mode, mode,
collectionEnumerators, collectionEnumerators,
itemsForBreakContent, allItems,
filteredExistingHistory, filteredExistingHistory,
result.AddedHistory, result.AddedHistory,
result.RemoveBefore,
cancellationToken); cancellationToken);
// merge break content result // merge break content result
@ -96,17 +93,14 @@ public class BlockPlayoutFillerBuilder(
.ToList(); .ToList();
allItems.AddRange(result.AddedItems); allItems.AddRange(result.AddedItems);
// history doesn't have an equivalent to "remove before"
// so for break content, let's remove all corresponding items that should be removed
itemsForBreakContent = allItems.Where(x => x.FinishOffset >= removeBefore).ToList();
result = await AddDefaultFiller( result = await AddDefaultFiller(
playout, playout,
referenceData, referenceData,
result, result,
collectionEnumerators, collectionEnumerators,
itemsForBreakContent, allItems,
filteredExistingHistory, filteredExistingHistory,
result.RemoveBefore,
cancellationToken); cancellationToken);
return result; return result;
@ -120,6 +114,7 @@ public class BlockPlayoutFillerBuilder(
IReadOnlyCollection<PlayoutItem> allItems, IReadOnlyCollection<PlayoutItem> allItems,
IReadOnlyCollection<PlayoutHistory> filteredExistingHistory, IReadOnlyCollection<PlayoutHistory> filteredExistingHistory,
IReadOnlyCollection<PlayoutHistory> addedHistory, IReadOnlyCollection<PlayoutHistory> addedHistory,
Option<DateTimeOffset> removeBefore,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var result = PlayoutBuildResult.Empty; var result = PlayoutBuildResult.Empty;
@ -134,7 +129,9 @@ public class BlockPlayoutFillerBuilder(
// guide group is template item id // guide group is template item id
// they are reused over multiple days, so we only want to group consecutive items // they are reused over multiple days, so we only want to group consecutive items
IEnumerable<IGrouping<int, PlayoutItem>> consecutiveBlocks = allItems.GroupConsecutiveBy(item => item.GuideGroup); IEnumerable<IGrouping<int, PlayoutItem>> consecutiveBlocks = allItems
.Where(i => i.FinishOffset > result.RemoveBefore.IfNone(SystemTime.MinValueUtc))
.GroupConsecutiveBy(item => item.GuideGroup);
foreach (IGrouping<int, PlayoutItem> blockGroup in consecutiveBlocks) foreach (IGrouping<int, PlayoutItem> blockGroup in consecutiveBlocks)
{ {
var itemsInBlock = blockGroup.ToList(); var itemsInBlock = blockGroup.ToList();
@ -306,6 +303,7 @@ public class BlockPlayoutFillerBuilder(
Dictionary<CollectionKey, IMediaCollectionEnumerator> collectionEnumerators, Dictionary<CollectionKey, IMediaCollectionEnumerator> collectionEnumerators,
List<PlayoutItem> allItems, List<PlayoutItem> allItems,
List<PlayoutHistory> filteredExistingHistory, List<PlayoutHistory> filteredExistingHistory,
Option<DateTimeOffset> removeBefore,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
// find all unscheduled periods // find all unscheduled periods

2
ErsatzTV.Infrastructure/Streaming/Graphics/GraphicsEngine.cs

@ -94,7 +94,7 @@ public class GraphicsEngine(
try try
{ {
// `content_total_seconds` - the total number of seconds in the content // `content_total_seconds` - the total number of seconds in the content
TimeSpan contentTotalTime = context.Seek + context.Duration; TimeSpan contentTotalTime = context.Seek + context.ContentTotalDuration;
while (!cancellationToken.IsCancellationRequested && frameCount < totalFrames) while (!cancellationToken.IsCancellationRequested && frameCount < totalFrames)
{ {

2
ErsatzTV.Scanner.Tests/Core/FFmpeg/TranscodingTests.cs

@ -390,6 +390,7 @@ public class TranscodingTests
now, now,
now + TimeSpan.FromSeconds(3), now + TimeSpan.FromSeconds(3),
now, now,
TimeSpan.FromSeconds(3),
watermarks, watermarks,
[], [],
"drm", "drm",
@ -710,6 +711,7 @@ public class TranscodingTests
now, now,
now + TimeSpan.FromSeconds(3), now + TimeSpan.FromSeconds(3),
now, now,
TimeSpan.FromSeconds(3),
watermarks, watermarks,
[], [],
"drm", "drm",

Loading…
Cancel
Save