feat: add manual segment completed trigger

This commit is contained in:
2026-05-08 23:33:09 +08:00
parent ea41d3e7b4
commit c5346940e7
6 changed files with 110 additions and 2 deletions
@@ -16,6 +16,7 @@ public interface IEventScriptService
RecordResult? recordResult,
string segmentFilePath,
DateTimeOffset occurredAt,
bool forceRun = false,
CancellationToken cancellationToken = default);
Task<EventScriptTestResultDto> TestAsync(
@@ -155,3 +155,12 @@ public sealed class RecordArtifactUploadBatchResultDto
public required IReadOnlyList<RecordArtifactUploadItemResultDto> Items { get; init; }
}
public sealed class ManualSegmentCompletedTriggerResultDto
{
public Guid RecordTaskId { get; init; }
public bool Success { get; init; }
public required string Message { get; init; }
}
@@ -5,6 +5,7 @@ using LiveRecorder.Application.Abstractions.Notifications;
using LiveRecorder.Application.Abstractions.Persistence;
using LiveRecorder.Application.Abstractions.Platforms;
using LiveRecorder.Application.Abstractions.Recording;
using LiveRecorder.Application.Abstractions.Scripting;
using LiveRecorder.Application.Abstractions.Settings;
using LiveRecorder.Application.Abstractions.Storage;
using LiveRecorder.Application.Models.RecordTasks;
@@ -29,6 +30,7 @@ public sealed class RecordService
private readonly ISystemLogService _systemLogService;
private readonly IEmailNotificationService _emailNotificationService;
private readonly IWebhookNotificationService _webhookNotificationService;
private readonly IEventScriptService _eventScriptService;
private readonly LiveRoomStatusService _liveRoomStatusService;
private readonly LiveRoomRecordingSettingsResolver _liveRoomRecordingSettingsResolver;
private readonly IStorageGuardService _storageGuardService;
@@ -47,6 +49,7 @@ public sealed class RecordService
ISystemLogService systemLogService,
IEmailNotificationService emailNotificationService,
IWebhookNotificationService webhookNotificationService,
IEventScriptService eventScriptService,
LiveRoomStatusService liveRoomStatusService,
LiveRoomRecordingSettingsResolver liveRoomRecordingSettingsResolver,
IStorageGuardService storageGuardService,
@@ -64,6 +67,7 @@ public sealed class RecordService
_systemLogService = systemLogService;
_emailNotificationService = emailNotificationService;
_webhookNotificationService = webhookNotificationService;
_eventScriptService = eventScriptService;
_liveRoomStatusService = liveRoomStatusService;
_liveRoomRecordingSettingsResolver = liveRoomRecordingSettingsResolver;
_storageGuardService = storageGuardService;
@@ -536,6 +540,56 @@ public sealed class RecordService
?? throw new KeyNotFoundException("Recording task was not found after starting manual transcoding.");
}
public async Task<ManualSegmentCompletedTriggerResultDto> TriggerSegmentCompletedEventAsync(
Guid id,
CancellationToken cancellationToken = default)
{
var recordTask = await _recordTaskRepository.GetByIdAsync(id, cancellationToken)
?? throw new KeyNotFoundException("Recording task was not found.");
if (IsActiveTaskStatus(recordTask.Status))
{
throw new InvalidOperationException("The recording task is still active. Stop or wait for the segment to finish before triggering the completion event manually.");
}
var recordSession = await _recordSessionRepository.GetByIdAsync(recordTask.RecordSessionId, cancellationToken)
?? throw new KeyNotFoundException("Recording session was not found.");
var segmentFilePath = recordTask.Result?.FilePath ?? recordTask.OutputFilePath;
if (string.IsNullOrWhiteSpace(segmentFilePath))
{
throw new InvalidOperationException("The recording task does not have a segment output path to use for the completion event.");
}
var occurredAt = DateTimeOffset.UtcNow;
await _eventScriptService.RunSegmentCompletedAsync(
recordTask.LiveRoom ?? recordSession.LiveRoom,
recordSession,
recordTask,
recordTask.Result,
segmentFilePath,
occurredAt,
forceRun: true,
cancellationToken);
await _systemLogService.WriteAsync(
SystemLogLevel.Info,
"Script",
"Segment completed event was triggered manually.",
segmentFilePath,
liveRoomId: recordTask.LiveRoomId,
recordSessionId: recordTask.RecordSessionId,
recordTaskId: recordTask.Id,
cancellationToken: cancellationToken);
return new ManualSegmentCompletedTriggerResultDto
{
RecordTaskId = recordTask.Id,
Success = true,
Message = "已手动触发分片完成事件。"
};
}
public async Task<RecordTaskDto> StopAsync(Guid id, CancellationToken cancellationToken = default)
{
var recordTask = await _recordTaskRepository.GetByIdAsync(id, cancellationToken)