提交
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
//
|
||||
// CallingBellFeature.swift
|
||||
// TUICallKit
|
||||
//
|
||||
// Created by vincepzhang on 2022/12/30.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import AVFAudio
|
||||
import TUICallEngine
|
||||
|
||||
#if canImport(TXLiteAVSDK_TRTC)
|
||||
import TXLiteAVSDK_TRTC
|
||||
#elseif canImport(TXLiteAVSDK_Professional)
|
||||
import TXLiteAVSDK_Professional
|
||||
#endif
|
||||
|
||||
let CALLKIT_AUDIO_DIAL_ID: Int32 = 48
|
||||
|
||||
class CallingBellFeature: NSObject, AVAudioPlayerDelegate {
|
||||
|
||||
enum CallingBellType {
|
||||
case CallingBellTypeHangup
|
||||
case CallingBellTypeCalled
|
||||
case CallingBellTypeDial
|
||||
}
|
||||
|
||||
var player: AVAudioPlayer?
|
||||
var loop: Bool = true
|
||||
private var needPlayRingtone: Bool = false
|
||||
let selfUserCallStatusObserver = Observer()
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
registerNotifications()
|
||||
registerObserveState()
|
||||
}
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
TUICallState.instance.selfUser.value.callStatus.removeObserver(selfUserCallStatusObserver)
|
||||
}
|
||||
|
||||
func registerObserveState() {
|
||||
TUICallState.instance.selfUser.value.callStatus.addObserver(selfUserCallStatusObserver, closure: { newValue, _ in
|
||||
let callStatus = TUICallState.instance.selfUser.value.callStatus.value
|
||||
let callRole = TUICallState.instance.selfUser.value.callRole.value
|
||||
|
||||
if callStatus == TUICallStatus.waiting {
|
||||
if callRole == TUICallRole.called {
|
||||
self.startMusicBasedOnAppState(type: .CallingBellTypeCalled)
|
||||
} else if callRole == TUICallRole.call {
|
||||
self.startPlayMusic(type: .CallingBellTypeDial)
|
||||
}
|
||||
} else {
|
||||
self.stopPlayMusic()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func startMusicBasedOnAppState(type: CallingBellType) {
|
||||
if UIApplication.shared.applicationState != .background {
|
||||
self.setAudioSessionWith(category: .soloAmbient)
|
||||
self.startPlayMusic(type: type)
|
||||
} else {
|
||||
self.needPlayRingtone = true;
|
||||
}
|
||||
}
|
||||
|
||||
func registerNotifications() {
|
||||
if #available(iOS 13.0, *) {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(appDidBecomeActive),
|
||||
name: UIScene.didActivateNotification,
|
||||
object: nil)
|
||||
} else {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(appDidBecomeActive),
|
||||
name: UIApplication.didBecomeActiveNotification,
|
||||
object: nil)
|
||||
}
|
||||
}
|
||||
|
||||
@objc func appDidBecomeActive() {
|
||||
if needPlayRingtone {
|
||||
let _ = startPlayMusic(type: .CallingBellTypeCalled)
|
||||
needPlayRingtone = false;
|
||||
}
|
||||
}
|
||||
|
||||
func startPlayMusic(type: CallingBellType) {
|
||||
guard let bundle = TUICallKitCommon.getTUICallKitBundle() else { return }
|
||||
switch type {
|
||||
case .CallingBellTypeHangup:
|
||||
let path = bundle.bundlePath + "/AudioFile" + "/phone_hangup.mp3"
|
||||
let url = URL(fileURLWithPath: path)
|
||||
return startPlayMusicBySystemPlayer(url: url, loop: false)
|
||||
case .CallingBellTypeCalled:
|
||||
if TUICallState.instance.enableMuteMode {
|
||||
return
|
||||
}
|
||||
var path = bundle.bundlePath + "/AudioFile" + "/phone_ringing.mp3"
|
||||
|
||||
|
||||
if let value = UserDefaults.standard.object(forKey: TUI_CALLING_BELL_KEY) as? String {
|
||||
path = value
|
||||
}
|
||||
|
||||
let url = URL(fileURLWithPath: path)
|
||||
return startPlayMusicBySystemPlayer(url: url)
|
||||
case .CallingBellTypeDial:
|
||||
let path = bundle.bundlePath + "/AudioFile" + "/phone_dialing.m4a"
|
||||
startPlayMusicByTRTCPlayer(path: path, id: CALLKIT_AUDIO_DIAL_ID)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func stopPlayMusic() {
|
||||
setAudioSessionWith(category: .playAndRecord)
|
||||
|
||||
if TUICallState.instance.selfUser.value.callRole.value == .call {
|
||||
stopPlayMusicByTRTCPlayer(id: CALLKIT_AUDIO_DIAL_ID)
|
||||
return
|
||||
}
|
||||
stopPlayMusicBySystemPlayer()
|
||||
needPlayRingtone = false;
|
||||
}
|
||||
|
||||
// MARK: TRTC Audio Player
|
||||
private func startPlayMusicByTRTCPlayer(path: String, id: Int32) {
|
||||
let audioDevice: TUIAudioPlaybackDevice = TUICallState.instance.mediaType.value == .audio ? .earpiece : .speakerphone
|
||||
CallEngineManager.instance.setAudioPlaybackDevice(device: audioDevice)
|
||||
|
||||
let param = TXAudioMusicParam()
|
||||
param.id = id
|
||||
param.isShortFile = true
|
||||
param.path = path
|
||||
|
||||
let audioEffectManager = TUICallEngine.createInstance().getTRTCCloudInstance().getAudioEffectManager()
|
||||
audioEffectManager.startPlayMusic(param, onStart: nil, onProgress: nil)
|
||||
audioEffectManager.setMusicPlayoutVolume(id, volume: 100)
|
||||
}
|
||||
|
||||
private func stopPlayMusicByTRTCPlayer(id: Int32) {
|
||||
let audioEffectManager = TUICallEngine.createInstance().getTRTCCloudInstance().getAudioEffectManager()
|
||||
audioEffectManager.stopPlayMusic(id)
|
||||
}
|
||||
|
||||
// MARK: System AVAudio Player
|
||||
private func startPlayMusicBySystemPlayer(url: URL, loop: Bool = true) {
|
||||
self.loop = loop
|
||||
|
||||
if player != nil {
|
||||
stopPlayMusicBySystemPlayer()
|
||||
}
|
||||
|
||||
do {
|
||||
player = try AVAudioPlayer(contentsOf: url)
|
||||
} catch let error as NSError {
|
||||
print("Error: \(error.localizedDescription)")
|
||||
return
|
||||
}
|
||||
|
||||
guard let prepare = player?.prepareToPlay(), prepare else {
|
||||
return
|
||||
}
|
||||
|
||||
player?.delegate = self
|
||||
player?.play()
|
||||
}
|
||||
|
||||
private func stopPlayMusicBySystemPlayer() {
|
||||
player?.stop()
|
||||
player = nil
|
||||
}
|
||||
|
||||
// MARK: AVAudioPlayerDelegate
|
||||
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
|
||||
if loop {
|
||||
player.play()
|
||||
} else {
|
||||
stopPlayMusicBySystemPlayer()
|
||||
}
|
||||
}
|
||||
|
||||
func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: Error?) {
|
||||
if error != nil {
|
||||
stopPlayMusicBySystemPlayer()
|
||||
}
|
||||
}
|
||||
|
||||
private func setAudioSessionWith(category: AVAudioSession.Category) {
|
||||
let audioSession = AVAudioSession.sharedInstance()
|
||||
do {
|
||||
try audioSession.setCategory(category, options: [.allowBluetooth, .allowBluetoothA2DP, .mixWithOthers])
|
||||
try audioSession.setActive(true)
|
||||
} catch {
|
||||
print("Error setting up audio session: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user