Browse Source

上传音乐通知栏不显示问题

newdev_shunjiawei
liwei1dao 12 months ago
parent
commit
1f12dce90c
  1. 10
      local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift
  2. 77
      local_plugins/music_service/ios/music_service/Sources/music_service/MusicService.swift

10
local_plugins/azure_speech/ios/azure_speech/Sources/azure_speech/AzureSpeechPlugin.swift

@ -18,7 +18,7 @@ import ble_service
// 日志标签 // 日志标签
private let tag = "AzureSpeechPlugin" private let tag = "AzureSpeechPlugin"
// 日志对象 // 日志对象
private let log = OSLog(subsystem: "com.azure.speech", category: "AzureSpeechPlugin") internal let log = OSLog(subsystem: "com.azure.speech", category: "AzureSpeechPlugin")
// MARK: - 防抖相关(iOS 原生层) // MARK: - 防抖相关(iOS 原生层)
// 函数级注释:用于限制 startContinuousRecognition/stopContinuousRecognition 在极短时间内的重复触发 // 函数级注释:用于限制 startContinuousRecognition/stopContinuousRecognition 在极短时间内的重复触发
@ -269,7 +269,7 @@ private func sendAstEvent(_ event: [String: Any]) {
* @param wavData WAV格式的音频数据 * @param wavData WAV格式的音频数据
* @return 纯PCM音频数据,如果提取失败则返回空Data * @return 纯PCM音频数据,如果提取失败则返回空Data
*/ */
private func extractPcmFromWav(_ wavData: Data) -> Data { internal func extractPcmFromWav(_ wavData: Data) -> Data {
// WAV文件头最小长度为44字节 // WAV文件头最小长度为44字节
guard wavData.count >= 44 else { guard wavData.count >= 44 else {
os_log("WAV数据长度不足,无法解析文件头", log: log, type: .error) os_log("WAV数据长度不足,无法解析文件头", log: log, type: .error)
@ -1011,15 +1011,15 @@ private class AstEventCallback: IntegratedSpeechTranslationService.ServiceEventC
public func onSynthesisAudioGenerated(text: String, audioData: Data) { public func onSynthesisAudioGenerated(text: String, audioData: Data) {
guard let plugin = plugin else { return } guard let plugin = plugin else { return }
plugin.os_log("语音合成音频生成,文本=%@,音频数据大小=%d", log: plugin.log, type: .info, text, audioData.count) os_log("语音合成音频生成,文本=%@,音频数据大小=%d", log: plugin.log, type: .info, text, audioData.count)
// Azure TTS返回的是RIFF WAV格式,需要去除文件头提取PCM数据 // Azure TTS返回的是RIFF WAV格式,需要去除文件头提取PCM数据
let pcmData = plugin.extractPcmFromWav(audioData) let pcmData = plugin.extractPcmFromWav(audioData)
if !pcmData.isEmpty { if !pcmData.isEmpty {
plugin.os_log("提取PCM数据,大小=%d字节", log: plugin.log, type: .info, pcmData.count) os_log("提取PCM数据,大小=%d字节", log: plugin.log, type: .info, pcmData.count)
BleService.shared.writeExternalAudioData(data: pcmData) BleService.shared.writeExternalAudioData(data: pcmData)
} else { } else {
plugin.os_log("提取PCM数据失败,音频数据可能不是WAV格式", log: plugin.log, type: .error) os_log("提取PCM数据失败,音频数据可能不是WAV格式", log: plugin.log, type: .error)
} }
// plugin?.sendAsrEvent([ // plugin?.sendAsrEvent([

77
local_plugins/music_service/ios/music_service/Sources/music_service/MusicService.swift

@ -52,10 +52,24 @@ public class MusicService: NSObject {
// MARK: - 音频会话设置 // MARK: - 音频会话设置
private func setupAudioSession() { private func setupAudioSession() {
do { do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.allowAirPlay, .allowBluetooth]) // 设置音频会话类别,添加 mixWithOthers 选项以确保通知正常显示
try AVAudioSession.sharedInstance().setCategory(
.playback,
mode: .default,
options: [.allowAirPlay, .allowBluetooth, .mixWithOthers]
)
try AVAudioSession.sharedInstance().setActive(true) try AVAudioSession.sharedInstance().setActive(true)
print("🎵 [MusicService] ✅ 音频会话设置成功")
} catch { } catch {
print("设置音频会话失败: \(error)") print("🎵 [MusicService] ❌ 设置音频会话失败: \(error)")
// 尝试备用配置
do {
try AVAudioSession.sharedInstance().setCategory(.playback)
try AVAudioSession.sharedInstance().setActive(true)
print("🎵 [MusicService] ✅ 使用备用音频会话配置")
} catch {
print("🎵 [MusicService] ❌ 备用音频会话配置也失败: \(error)")
}
} }
} }
@ -570,30 +584,51 @@ public class MusicService: NSObject {
private func setupRemoteCommandCenter() { private func setupRemoteCommandCenter() {
let commandCenter = MPRemoteCommandCenter.shared() let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.playCommand.addTarget { [unowned self] _ in // 清除之前的目标,避免重复添加
self.resume() commandCenter.playCommand.removeTarget(nil)
commandCenter.pauseCommand.removeTarget(nil)
commandCenter.nextTrackCommand.removeTarget(nil)
commandCenter.previousTrackCommand.removeTarget(nil)
commandCenter.stopCommand.removeTarget(nil)
// 启用命令
commandCenter.playCommand.isEnabled = true
commandCenter.pauseCommand.isEnabled = true
commandCenter.nextTrackCommand.isEnabled = true
commandCenter.previousTrackCommand.isEnabled = true
commandCenter.stopCommand.isEnabled = true
commandCenter.playCommand.addTarget { [weak self] _ in
print("🎵 [RemoteCommand] 播放命令触发")
self?.resume()
return .success return .success
} }
commandCenter.pauseCommand.addTarget { [unowned self] _ in commandCenter.pauseCommand.addTarget { [weak self] _ in
self.pause() print("🎵 [RemoteCommand] 暂停命令触发")
self?.pause()
return .success return .success
} }
commandCenter.nextTrackCommand.addTarget { [unowned self] _ in commandCenter.nextTrackCommand.addTarget { [weak self] _ in
self.next() print("🎵 [RemoteCommand] 下一首命令触发")
self?.next()
return .success return .success
} }
commandCenter.previousTrackCommand.addTarget { [unowned self] _ in commandCenter.previousTrackCommand.addTarget { [weak self] _ in
self.previous() print("🎵 [RemoteCommand] 上一首命令触发")
self?.previous()
return .success return .success
} }
commandCenter.stopCommand.addTarget { [unowned self] _ in commandCenter.stopCommand.addTarget { [weak self] _ in
self.stop() print("🎵 [RemoteCommand] 停止命令触发")
self?.stop()
return .success return .success
} }
print("🎵 [MusicService] ✅ 远程控制中心设置完成")
} }
private func updateNowPlayingInfo(song: [String: Any]) { private func updateNowPlayingInfo(song: [String: Any]) {
@ -641,7 +676,11 @@ public class MusicService: NSObject {
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = Double(currentPosition) / 1000.0 nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = Double(currentPosition) / 1000.0
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = isPlaying ? 1.0 : 0.0 nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = isPlaying ? 1.0 : 0.0
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo // 确保在主线程更新
DispatchQueue.main.async {
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
print("🎵 [MusicService] ✅ 媒体会话进度已更新: \(currentPosition/1000)s/\(duration/1000)s")
}
} }
/// 启用媒体会话回调 /// 启用媒体会话回调
@ -714,9 +753,15 @@ public class MusicService: NSObject {
/// 更新媒体会话播放状态 /// 更新媒体会话播放状态
public func updateMediaSessionPlaybackState(isPlaying: Bool) { public func updateMediaSessionPlaybackState(isPlaying: Bool) {
self.isPlaying = isPlaying self.isPlaying = isPlaying
var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo ?? [:]
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = isPlaying ? 1.0 : 0.0 // 确保在主线程更新
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo DispatchQueue.main.async {
var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo ?? [:]
nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = isPlaying ? 1.0 : 0.0
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
print("🎵 [MusicService] ✅ 媒体会话播放状态已更新: \(isPlaying ? "播放中" : "已暂停")")
}
if isPlaying { if isPlaying {
startProgressTimer() startProgressTimer()

Loading…
Cancel
Save