Browse Source

add seek seconds to playback troubleshooting (#2300)

pull/2301/head
Jason Dove 6 days ago committed by GitHub
parent
commit
91c4e8f575
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 2
      ErsatzTV.Application/Troubleshooting/Commands/ArchiveTroubleshootingResults.cs
  3. 2
      ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlayback.cs
  4. 19
      ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlaybackHandler.cs
  5. 12
      ErsatzTV/Controllers/Api/TroubleshootController.cs
  6. 26
      ErsatzTV/Pages/PlaybackTroubleshooting.razor

1
CHANGELOG.md

@ -34,6 +34,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -34,6 +34,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- `graphics_on` requires the name of a graphics element template, e.g. `text/cool_element.yml`
- The `variables` property can be used to dynamically replace text from the template
- `graphics_off` will turn off a specific element, or all elements if none are specified
- Add `Seek Seconds` to playback troubleshooting to support capturing timing-related issues
### Fix
- Fix database operations that were slowing down playout builds

2
ErsatzTV.Application/Troubleshooting/Commands/ArchiveTroubleshootingResults.cs

@ -5,5 +5,5 @@ public record ArchiveTroubleshootingResults( @@ -5,5 +5,5 @@ public record ArchiveTroubleshootingResults(
int FFmpegProfileId,
List<int> WatermarkIds,
List<int> GraphicsElementIds,
bool StartFromBeginning)
Option<int> SeekSeconds)
: IRequest<Option<string>>;

2
ErsatzTV.Application/Troubleshooting/Commands/PrepareTroubleshootingPlayback.cs

@ -9,5 +9,5 @@ public record PrepareTroubleshootingPlayback( @@ -9,5 +9,5 @@ public record PrepareTroubleshootingPlayback(
List<int> WatermarkIds,
List<int> GraphicsElementIds,
int? SubtitleId,
bool StartFromBeginning)
Option<int> SeekSeconds)
: IRequest<Either<BaseError, PlayoutItemResult>>;

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

@ -103,14 +103,23 @@ public class PrepareTroubleshootingPlaybackHandler( @@ -103,14 +103,23 @@ public class PrepareTroubleshootingPlaybackHandler(
TimeSpan inPoint = TimeSpan.Zero;
TimeSpan outPoint = duration;
if (!hlsRealtime && !request.StartFromBeginning)
if (!hlsRealtime)
{
inPoint = TimeSpan.FromSeconds(version.Duration.TotalSeconds / 2.0);
if (inPoint.TotalSeconds < 30)
foreach (var seekSeconds in request.SeekSeconds)
{
duration = inPoint;
inPoint = TimeSpan.FromSeconds(seekSeconds);
if (inPoint > version.Duration)
{
inPoint = version.Duration - duration;
}
if (inPoint + duration > version.Duration)
{
duration = version.Duration - inPoint;
}
outPoint = inPoint + duration;
}
outPoint = inPoint + duration;
}
var graphicsElements = await dbContext.GraphicsElements

12
ErsatzTV/Controllers/Api/TroubleshootController.cs

@ -33,13 +33,15 @@ public class TroubleshootController( @@ -33,13 +33,15 @@ public class TroubleshootController(
[FromQuery]
int? subtitleId,
[FromQuery]
bool startFromBeginning,
int seekSeconds,
CancellationToken cancellationToken)
{
try
{
Option<int> ss = seekSeconds > 0 ? seekSeconds : Option<int>.None;
Either<BaseError, PlayoutItemResult> result = await mediator.Send(
new PrepareTroubleshootingPlayback(mediaItem, ffmpegProfile, watermark, graphicsElement, subtitleId, startFromBeginning),
new PrepareTroubleshootingPlayback(mediaItem, ffmpegProfile, watermark, graphicsElement, subtitleId, ss),
cancellationToken);
if (result.IsLeft)
@ -119,11 +121,13 @@ public class TroubleshootController( @@ -119,11 +121,13 @@ public class TroubleshootController(
[FromQuery]
List<int> graphicsElement,
[FromQuery]
bool startFromBeginning,
int seekSeconds,
CancellationToken cancellationToken)
{
Option<int> ss = seekSeconds > 0 ? seekSeconds : Option<int>.None;
Option<string> maybeArchivePath = await mediator.Send(
new ArchiveTroubleshootingResults(mediaItem, ffmpegProfile, watermark, graphicsElement, startFromBeginning),
new ArchiveTroubleshootingResults(mediaItem, ffmpegProfile, watermark, graphicsElement, ss),
cancellationToken);
foreach (string archivePath in maybeArchivePath)

26
ErsatzTV/Pages/PlaybackTroubleshooting.razor

@ -93,7 +93,16 @@ @@ -93,7 +93,16 @@
<div class="d-flex">
<MudText>Start From Beginning</MudText>
</div>
<MudCheckBox @bind-Value="_startFromBeginning" Dense="true" Disabled="@(string.Equals(_info?.Kind, "RemoteStream", StringComparison.OrdinalIgnoreCase))" />
<MudCheckBox T="bool"
Dense="true"
Disabled="@(string.Equals(_info?.Kind, "RemoteStream", StringComparison.OrdinalIgnoreCase))"
ValueChanged="@(c => OnStartFromBeginningChanged(c))" />
</MudStack>
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5">
<div class="d-flex">
<MudText>Seek Seconds</MudText>
</div>
<MudTextField @bind-Value="@(_seekSeconds)" Disabled="@(_startFromBeginning)" />
</MudStack>
<MudText Typo="Typo.h5" Class="mt-10 mb-2">Preview</MudText>
<MudDivider Class="mb-6"/>
@ -138,8 +147,9 @@ @@ -138,8 +147,9 @@
private int _ffmpegProfileId;
private IEnumerable<string> _watermarkNames = new System.Collections.Generic.HashSet<string>();
private IEnumerable<string> _graphicsElementNames = new System.Collections.Generic.HashSet<string>();
private int? _subtitleId;
private bool _startFromBeginning;
private int? _subtitleId;
private int _seekSeconds;
private bool _hasPlayed;
[SupplyParameterFromQuery(Name = "mediaItem")]
@ -178,13 +188,19 @@ @@ -178,13 +188,19 @@
}
}
private void OnStartFromBeginningChanged(bool value)
{
_startFromBeginning = value;
_seekSeconds = value ? 0 : (int)Math.Round((_info?.Duration.TotalSeconds ?? 0) / 2.0);
}
private void LockChanged(object sender, EventArgs e) => InvokeAsync(StateHasChanged);
private async Task PreviewChannel()
{
var uri = new UriBuilder(NavigationManager.ToAbsoluteUri(NavigationManager.Uri));
uri.Path = uri.Path.Replace("/system/troubleshooting/playback", "/api/troubleshoot/playback.m3u8");
uri.Query = $"?mediaItem={MediaItemId}&ffmpegProfile={_ffmpegProfileId}&startFromBeginning={_startFromBeginning}";
uri.Query = $"?mediaItem={MediaItemId}&ffmpegProfile={_ffmpegProfileId}&seekSeconds={_seekSeconds}";
foreach (var watermarkName in _watermarkNames)
{
foreach (var watermark in _watermarks.Where(wm => wm.Name == watermarkName))
@ -221,7 +237,7 @@ @@ -221,7 +237,7 @@
foreach (MediaItemInfo info in maybeInfo.RightToSeq())
{
_info = info;
_startFromBeginning = string.Equals(info.Kind, "RemoteStream", StringComparison.OrdinalIgnoreCase);
OnStartFromBeginningChanged(string.Equals(info.Kind, "RemoteStream", StringComparison.OrdinalIgnoreCase));
_subtitleId = null;
_subtitleStreams.Clear();
@ -239,7 +255,7 @@ @@ -239,7 +255,7 @@
private async Task DownloadResults()
{
var uri = $"api/troubleshoot/playback/archive?mediaItem={MediaItemId ?? 0}&ffmpegProfile={_ffmpegProfileId}&startFromBeginning={_startFromBeginning}";
var uri = $"api/troubleshoot/playback/archive?mediaItem={MediaItemId ?? 0}&ffmpegProfile={_ffmpegProfileId}&seekSeconds={_seekSeconds}";
foreach (var watermarkName in _watermarkNames)
{

Loading…
Cancel
Save