Maximofn commited on
Commit
d73543f
·
1 Parent(s): 149ed58

Add diarize_library.py for speaker diarization functionality

Browse files

- Implement Pyannote-based audio diarization with flexible speaker configuration
- Create functions to diarize audio and parse RTTM output
- Support custom speaker count, device selection, and segment parsing
- Utilize environment variables for authentication

Files changed (1) hide show
  1. diarize_library.py +93 -0
diarize_library.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import dotenv
3
+ from pyannote.audio import Pipeline
4
+ import torch
5
+ import torchaudio
6
+
7
+ dotenv.load_dotenv()
8
+ SUBTIFY_TOKEN = os.getenv("SUBTIFY_TOKEN")
9
+
10
+ def diarize(audio_path: str, num_speakers: int = 0, min_speakers: int = 0, max_speakers: int = 0, device: str = "cpu") -> list:
11
+ """
12
+ Diarize an audio file using Pyannote.
13
+
14
+ Args:
15
+ audio_path (str): The path to the audio file to diarize.
16
+
17
+ Returns:
18
+ list: A list of segments with start, duration, end, and speaker.
19
+ """
20
+ # Load audio
21
+ waveform, sample_rate = torchaudio.load(audio_path)
22
+
23
+ # Parameters
24
+ params = {}
25
+ if num_speakers > 0:
26
+ params["num_speakers"] = num_speakers
27
+ if min_speakers > 0:
28
+ params["min_speakers"] = min_speakers
29
+ if max_speakers > 0:
30
+ params["max_speakers"] = max_speakers
31
+
32
+ # Device
33
+ device = torch.device(device)
34
+
35
+ # Create pipeline
36
+ pipeline = Pipeline.from_pretrained("pyannote/speaker-diarization-3.1", use_auth_token=SUBTIFY_TOKEN)
37
+ pipeline.to(device)
38
+
39
+ # Diarize
40
+ diarization = pipeline({"waveform": waveform, "sample_rate": sample_rate}, **params)
41
+
42
+ return diarization
43
+
44
+ def parse_rttm(rttm_string):
45
+ """
46
+ Parse an RTTM string into a list of segments.
47
+
48
+ Args:
49
+ rttm_string (str): The RTTM string to parse.
50
+
51
+ Returns:
52
+ list: A list of segments with start, duration, end, and speaker.
53
+ """
54
+
55
+ # Parse RTTM
56
+ segments = []
57
+
58
+ # Parse each line
59
+ for line in rttm_string.strip().split('\n'):
60
+ # Split line into parts
61
+ parts = line.split()
62
+
63
+ # Create segment
64
+ segment = {
65
+ 'start': float(parts[3]),
66
+ 'duration': float(parts[4]),
67
+ 'end': float(parts[3]) + float(parts[4]),
68
+ 'speaker': parts[7]
69
+ }
70
+
71
+ # Add segment to list
72
+ segments.append(segment)
73
+ return segments
74
+
75
+ def diarize_audio(audio_path: str, num_speakers: int = 0, min_speakers: int = 0, max_speakers: int = 0, device: str = "cpu") -> list:
76
+ """
77
+ Diarize an audio file using Pyannote.
78
+
79
+ Args:
80
+ audio_path (str): The path to the audio file to diarize.
81
+
82
+ Returns:
83
+ list: A list of segments with start, duration, end, and speaker.
84
+ """
85
+
86
+ # Diarize
87
+ diarization = diarize(audio_path, num_speakers, min_speakers, max_speakers, device)
88
+
89
+ # Format diarization
90
+ rttm_output = diarization.to_rttm()
91
+
92
+ # Parse RTTM
93
+ return parse_rttm(rttm_output)