You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift中Amazon Polly无法读取/听不到首个单词问题求助

解决iOS中Amazon Polly Joanna语音丢失首个单词的问题

嘿,我来帮你搞定这个首个单词听不到的问题!这种情况我之前在使用AVPlayer播放预签名URL音频时遇到过,大概率是音频还没完全加载完成就触发了播放,导致开头的内容被跳过了。咱们来一步步调整你的代码:

首先先把你的原始代码贴出来方便参考:

let input = AWSPollySynthesizeSpeechURLBuilderRequest()
// Text to synthesize
input.text = "Sample text"
// We expect the output in MP3 format
input.outputFormat = AWSPollyOutputFormat.mp3
// Choose the voice ID
input.voiceId = AWSPollyVoiceId.joanna

// Create an task to synthesize speech using the given synthesis input
let builder = AWSPollySynthesizeSpeechURLBuilder.default().getPreSignedURL(input)

// Request the URL for synthesis result
builder.continueOnSuccessWith(block: { (awsTask: AWSTask<NSURL>) -> Any? in
    // The result of getPresignedURL task is NSURL.
    // Again, we ignore the errors in the example.
    let url = awsTask.result!
    // Try playing the data using the system AVAudioPlayer
    self.audioPlayer.replaceCurrentItem(with: AVPlayerItem(url: url as URL))
    self.audioPlayer.play()
    return nil
})

接下来是具体的修复方案:

方案1:等待AVPlayerItem完全就绪后再播放

AVPlayer的play()调用如果在音频还没缓冲好的时候执行,很容易跳过开头内容。我们可以通过监听AVPlayerItem的状态来确保播放时机正确:

修改后的代码如下:

builder.continueOnSuccessWith(block: { (awsTask: AWSTask<NSURL>) -> Any? in
    guard let url = awsTask.result as URL? else { return nil }
    
    let playerItem = AVPlayerItem(url: url)
    self.audioPlayer.replaceCurrentItem(with: playerItem)
    
    // 监听playerItem的状态,确保就绪后再播放
    var observation: NSKeyValueObservation?
    observation = playerItem.observe(\.status, options: [.new]) { [weak self] item, change in
        guard let self = self else { return }
        if item.status == .readyToPlay {
            self.audioPlayer.play()
            observation?.invalidate() // 取消监听,避免内存泄漏
        } else if item.status == .failed {
            print("音频加载失败:\(item.error?.localizedDescription ?? "未知错误")")
            observation?.invalidate()
        }
    }
    
    return nil
})

方案2:改用AVAudioPlayer预加载整个音频

如果你的场景不需要流式播放(比如音频文件不大),改用AVAudioPlayer会更稳定,因为它会把整个音频文件加载到内存后再播放,不会出现开头丢失的问题:

builder.continueOnSuccessWith(block: { (awsTask: AWSTask<NSURL>) -> Any? in
    guard let url = awsTask.result as URL?,
          let audioData = try? Data(contentsOf: url) else {
        print("无法获取音频数据")
        return nil
    }
    
    do {
        // 注意:AVAudioPlayer需要在类中持有引用,否则会被释放
        self.audioPlayer = try AVAudioPlayer(data: audioData)
        self.audioPlayer?.play()
    } catch {
        print("AVAudioPlayer初始化失败:\(error.localizedDescription)")
    }
    
    return nil
})

额外排查点

  • 可以先手动下载Polly生成的音频文件,听听开头是否真的有内容,排除是Polly服务端生成的音频本身缺失首个单词的情况(这种概率很低,但可以快速验证)
  • 测试更换其他文本(比如更长的句子)或者其他Polly语音,看看是否同样出现问题,确认是不是Joanna语音的特殊情况

内容的提问来源于stack exchange,提问作者Akshaykumar Maldhure

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:54:05