forked from Manuel/meeting-assistant
feat: add local Resemblyzer speaker recognition
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
using MeetingAssistant.Transcription;
|
||||
|
||||
namespace MeetingAssistant.Speakers;
|
||||
|
||||
internal sealed record SpeakerSampleSpan(
|
||||
string Speaker,
|
||||
TimeSpan Start,
|
||||
TimeSpan End,
|
||||
TimeSpan SpeechDuration,
|
||||
TimeSpan MaximumDuration,
|
||||
IReadOnlyList<TranscriptionSegment> Segments)
|
||||
{
|
||||
public static SpeakerSampleSpan? Create(
|
||||
TranscriptionSegment segment,
|
||||
TimeSpan maximumDuration)
|
||||
{
|
||||
if (maximumDuration <= TimeSpan.Zero)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(
|
||||
nameof(maximumDuration),
|
||||
maximumDuration,
|
||||
"Speaker sample maximum duration must be greater than zero.");
|
||||
}
|
||||
|
||||
var boundedEnd = Min(segment.End, segment.Start + maximumDuration);
|
||||
return boundedEnd > segment.Start
|
||||
? new SpeakerSampleSpan(
|
||||
segment.Speaker,
|
||||
segment.Start,
|
||||
boundedEnd,
|
||||
boundedEnd - segment.Start,
|
||||
maximumDuration,
|
||||
[segment with { End = boundedEnd }])
|
||||
: null;
|
||||
}
|
||||
|
||||
public bool TryExtend(
|
||||
TranscriptionSegment segment,
|
||||
out SpeakerSampleSpan extended)
|
||||
{
|
||||
extended = this;
|
||||
if (!string.Equals(Speaker, segment.Speaker, StringComparison.OrdinalIgnoreCase) ||
|
||||
segment.Start >= Start + MaximumDuration)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var boundedEnd = Min(segment.End, Start + MaximumDuration);
|
||||
if (boundedEnd <= segment.Start)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var uncoveredStart = segment.Start > End ? segment.Start : End;
|
||||
var additionalSpeechDuration = boundedEnd > uncoveredStart
|
||||
? boundedEnd - uncoveredStart
|
||||
: TimeSpan.Zero;
|
||||
extended = this with
|
||||
{
|
||||
End = boundedEnd > End ? boundedEnd : End,
|
||||
SpeechDuration = SpeechDuration + additionalSpeechDuration,
|
||||
Segments = Segments.Append(segment with { End = boundedEnd }).ToList()
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
public TranscriptionSegment ToSegment()
|
||||
{
|
||||
return new TranscriptionSegment(
|
||||
Start,
|
||||
End,
|
||||
Speaker,
|
||||
string.Join(' ', Segments
|
||||
.Select(segment => segment.Text)
|
||||
.Where(text => !string.IsNullOrWhiteSpace(text))));
|
||||
}
|
||||
|
||||
private static TimeSpan Min(TimeSpan left, TimeSpan right)
|
||||
{
|
||||
return left < right ? left : right;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user