@@ -594,20 +594,110 @@ async def get_kokoro_voices():
594
594
data = await response .json ()
595
595
# Process the voices from the response
596
596
voices = []
597
- for voice_id in data .get ("voices" , []):
598
- # Create a readable name from the ID
599
- # Format: language code (af/am) + name
597
+
598
+ # Language/accent codes mapping
599
+ language_codes = {
600
+ 'a' : 'American English' ,
601
+ 'b' : 'British English' ,
602
+ 'e' : 'European Spanish' ,
603
+ 'f' : 'French' ,
604
+ 'g' : 'German' ,
605
+ 'h' : 'Hindi' ,
606
+ 'i' : 'Italian' ,
607
+ 'j' : 'Japanese' ,
608
+ 'k' : 'Korean' ,
609
+ 'p' : 'Polish' ,
610
+ 'r' : 'Russian' ,
611
+ 's' : 'Spanish' ,
612
+ 'z' : 'Chinese'
613
+ }
614
+
615
+ # Get all voice IDs
616
+ voice_ids = data .get ("voices" , [])
617
+
618
+ # Group voices by language/accent
619
+ english_voices = [] # American and British English
620
+ other_voices_by_language = {} # Organize other voices by language code
621
+ unknown_voices = [] # For voices that don't follow the naming pattern
622
+
623
+ for voice_id in voice_ids :
624
+ parts = voice_id .split ('_' )
625
+ if len (parts ) >= 2 :
626
+ lang_code = parts [0 ]
627
+ # First character is language code
628
+ accent_code = lang_code [:1 ]
629
+
630
+ # Prioritize English voices (American and British)
631
+ if accent_code in ['a' , 'b' ]:
632
+ english_voices .append (voice_id )
633
+ else :
634
+ # Group other voices by language
635
+ if accent_code not in other_voices_by_language :
636
+ other_voices_by_language [accent_code ] = []
637
+ other_voices_by_language [accent_code ].append (voice_id )
638
+ else :
639
+ unknown_voices .append (voice_id )
640
+
641
+ # Sort voices within each group
642
+ english_voices .sort ()
643
+ for lang in other_voices_by_language :
644
+ other_voices_by_language [lang ].sort ()
645
+ unknown_voices .sort ()
646
+
647
+ # Create final sorted list: English first, then other languages alphabetically
648
+ sorted_voice_ids = english_voices
649
+
650
+ # Process English voices
651
+ for voice_id in english_voices :
600
652
parts = voice_id .split ('_' )
601
653
if len (parts ) >= 2 :
602
654
lang_code = parts [0 ]
603
655
name = parts [1 ].capitalize ()
604
- gender = "Female" if lang_code == "af" else "Male"
656
+
657
+ accent_code = lang_code [:1 ]
658
+ gender_code = lang_code [1 :2 ]
659
+
660
+ gender = "Female" if gender_code == "f" else "Male"
661
+ accent_label = f" - { language_codes .get (accent_code , 'Unknown' )} "
662
+
605
663
voices .append ({
606
664
"id" : voice_id ,
607
- "name" : f"{ name } ({ gender } )"
665
+ "name" : f"{ name } ({ gender } ){ accent_label } "
608
666
})
609
- else :
610
- # Fallback for voices without standard format
667
+
668
+ # Add other language groups with separators
669
+ for lang in sorted (other_voices_by_language .keys ()):
670
+ # Add a language group header if we have voices for this language
671
+ if other_voices_by_language [lang ]:
672
+ language_name = language_codes .get (lang , "Unknown Language" )
673
+
674
+ # Add a separator for this language group
675
+ voices .append ({
676
+ "id" : f"separator_{ lang } " ,
677
+ "name" : f"--- { language_name } Voices ---"
678
+ })
679
+
680
+ # Add the voices for this language
681
+ for voice_id in other_voices_by_language [lang ]:
682
+ parts = voice_id .split ('_' )
683
+ if len (parts ) >= 2 :
684
+ name = parts [1 ].capitalize ()
685
+ gender_code = parts [0 ][1 :2 ]
686
+ gender = "Female" if gender_code == "f" else "Male"
687
+
688
+ voices .append ({
689
+ "id" : voice_id ,
690
+ "name" : f"{ name } ({ gender } )"
691
+ })
692
+
693
+ # Add unknown voices at the end if any
694
+ if unknown_voices :
695
+ voices .append ({
696
+ "id" : "separator_unknown" ,
697
+ "name" : "--- Other Voices ---"
698
+ })
699
+
700
+ for voice_id in unknown_voices :
611
701
voices .append ({
612
702
"id" : voice_id ,
613
703
"name" : voice_id
0 commit comments