mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Add samples for voices
This commit is contained in:
parent
aad1a51da8
commit
b47b1ca49a
3 changed files with 60 additions and 25 deletions
|
|
@ -9,6 +9,8 @@
|
|||
let language: VoiceLanguage
|
||||
let showLanguageChanger: Bool
|
||||
|
||||
@State var playbackSample: String? = nil
|
||||
|
||||
init(forLanguage: VoiceLanguage, showLanguageChanger: Bool) {
|
||||
self.language = forLanguage
|
||||
self.showLanguageChanger = showLanguageChanger
|
||||
|
|
@ -45,27 +47,7 @@
|
|||
ForEach(language.categories, id: \.self) { category in
|
||||
Section(category.rawValue) {
|
||||
ForEach(audioController.voiceList?.filter { $0.category == category } ?? [], id: \.key.self) { voice in
|
||||
HStack {
|
||||
Button(action: {
|
||||
audioController.setPreferredVoice(voice.key, forLanguage: language.key)
|
||||
audioController.currentVoice = voice.key
|
||||
}, label: {
|
||||
HStack {
|
||||
Text(voice.name)
|
||||
Spacer()
|
||||
|
||||
if voice.selected {
|
||||
if audioController.isPlaying, audioController.isLoading {
|
||||
ProgressView()
|
||||
} else {
|
||||
Image(systemName: "checkmark")
|
||||
}
|
||||
}
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
})
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
}
|
||||
voiceRow(for: voice)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -83,6 +65,39 @@
|
|||
|
||||
func voiceRow(for voice: VoiceItem) -> some View {
|
||||
HStack {
|
||||
Button(action: {
|
||||
if audioController.isPlayingSample(voice: voice.key) {
|
||||
playbackSample = nil
|
||||
audioController.stopVoiceSample()
|
||||
} else {
|
||||
playbackSample = voice.key
|
||||
audioController.playVoiceSample(voice: voice.key)
|
||||
Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { timer in
|
||||
let playing = audioController.isPlayingSample(voice: voice.key)
|
||||
if playing {
|
||||
playbackSample = voice.key
|
||||
} else if !playing {
|
||||
// If the playback sample is something else, its taken ownership
|
||||
// of the value so we just ignore it and shut down our timer.
|
||||
if playbackSample == voice.key {
|
||||
playbackSample = nil
|
||||
}
|
||||
timer.invalidate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}, label: {
|
||||
if playbackSample == voice.key {
|
||||
Image(systemName: "stop.circle")
|
||||
.font(.appTitleTwo)
|
||||
.padding(.trailing, 16)
|
||||
} else {
|
||||
Image(systemName: "play.circle")
|
||||
.font(.appTitleTwo)
|
||||
.padding(.trailing, 16)
|
||||
}
|
||||
})
|
||||
|
||||
Button(action: {
|
||||
audioController.setPreferredVoice(voice.key, forLanguage: language.key)
|
||||
audioController.currentVoice = voice.key
|
||||
|
|
|
|||
|
|
@ -246,6 +246,8 @@
|
|||
var durations: [Double]?
|
||||
var lastReadUpdate = 0.0
|
||||
|
||||
var samplePlayer: AVAudioPlayer?
|
||||
|
||||
public init(dataService: DataService) {
|
||||
self.dataService = dataService
|
||||
|
||||
|
|
@ -631,9 +633,13 @@
|
|||
|
||||
public func playVoiceSample(voice: String) {
|
||||
do {
|
||||
if let url = Bundle.main.url(forResource: "tts-voice-sample-\(voice)", withExtension: "mp3") {
|
||||
let player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
|
||||
player.play()
|
||||
pause()
|
||||
|
||||
if let url = Bundle(url: UtilsPackage.bundleURL)?.url(forResource: voice, withExtension: "mp3") {
|
||||
samplePlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
|
||||
if !(samplePlayer?.play() ?? false) {
|
||||
throw BasicError.message(messageText: "Unable to playback audio")
|
||||
}
|
||||
} else {
|
||||
NSNotification.operationFailed(message: "Error playing voice sample.")
|
||||
}
|
||||
|
|
@ -643,6 +649,20 @@
|
|||
}
|
||||
}
|
||||
|
||||
public func isPlayingSample(voice: String) -> Bool {
|
||||
if let samplePlayer = self.samplePlayer, let url = Bundle(url: UtilsPackage.bundleURL)?.url(forResource: voice, withExtension: "mp3") {
|
||||
return samplePlayer.url == url && samplePlayer.isPlaying
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public func stopVoiceSample() {
|
||||
if let samplePlayer = self.samplePlayer {
|
||||
samplePlayer.stop()
|
||||
self.samplePlayer = nil
|
||||
}
|
||||
}
|
||||
|
||||
private func updateDurations(oldPlayback: Double, newPlayback: Double) {
|
||||
if let oldDurations = durations {
|
||||
durations = oldDurations.map { $0 * oldPlayback / newPlayback }
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ public enum Voices {
|
|||
]
|
||||
|
||||
public static let UltraPairs = [
|
||||
VoicePair(firstKey: "Larry", secondKey: "susan", firstName: "Larry", secondName: "Susan", language: "en-US", category: .enUS),
|
||||
VoicePair(firstKey: "Larry", secondKey: "Susan", firstName: "Larry", secondName: "Susan", language: "en-US", category: .enUS),
|
||||
|
||||
VoicePair(firstKey: "Jordan", secondKey: "William", firstName: "Jordan", secondName: "William", language: "en-US", category: .enUS),
|
||||
VoicePair(firstKey: "Adrian", secondKey: "Anthony", firstName: "Adrian", secondName: "Anthony", language: "en-US", category: .enUS),
|
||||
|
|
|
|||
Loading…
Reference in a new issue