This commit is contained in:
DDIsFriend
2023-09-06 15:17:24 +08:00
parent 177b77c044
commit 7fda9d2650
37 changed files with 9331 additions and 8117 deletions

View File

@@ -7,75 +7,124 @@
import Foundation
import AVFoundation
//import DDLogKit_Private
public let DDAS = DDAudioService.default
open class DDAudioService {
public static let `default` = DDAudioService()
private var items : [DDAudioServiceItem] = []
private var audioSoundID : SystemSoundID = 0
private var vibrateSoundID : SystemSoundID = 0
private var audioNumberOfLoops : Int = 0
private var vibrateNumberOfLoops : Int = 0
private var endSound : Bool = false
private var endVibrate : Bool = false
public func playSoundWithVibrate(audioUrl:URL,numberOfLoops:Int = 1) {
playVibrate(numberOfLoops: -1)
playSound(audioUrl: audioUrl,numberOfLoops: numberOfLoops) {[weak self] in
self?.stopSound()
self?.stopVibrate()
public func playSoundWithVibrate(audioUrl:URL,name:String,numberOfLoops:Int = 1,timeInterval:TimeInterval = 0,eachLoopCompletionBlock: (() -> Void)? = nil,endCompletionBlock: (() -> Void)? = nil) {
let item = DDAudioServiceItem(name: name)
items.append(item)
item.playSoundWithVibrate(audioUrl: audioUrl,numberOfLoops: numberOfLoops,timeInterval: timeInterval,eachLoopCompletionBlock: eachLoopCompletionBlock,endCompletionBlock: endCompletionBlock)
}
public func playSound(audioUrl:URL,name:String,numberOfLoops:Int = 1,timeInterval:TimeInterval = 0,eachLoopCompletionBlock: (() -> Void)? = nil,endCompletionBlock: (() -> Void)? = nil) {
let item = DDAudioServiceItem(name: name)
items.append(item)
item.playSound(audioUrl: audioUrl,numberOfLoops: numberOfLoops,timeInterval: timeInterval,eachLoopCompletionBlock: eachLoopCompletionBlock,endCompletionBlock: endCompletionBlock)
}
public func playVibrate(name:String,numberOfLoops:Int = 1,timeInterval:TimeInterval = 0,eachLoopCompletionBlock: (() -> Void)? = nil,endCompletionBlock: (() -> Void)? = nil) {
let item = DDAudioServiceItem(name: name)
items.append(item)
item.playVibrate(numberOfLoops: numberOfLoops,timeInterval: timeInterval,eachLoopCompletionBlock: eachLoopCompletionBlock,endCompletionBlock: endCompletionBlock)
}
public func stopSoundWithVibrate(name:String) {
if items.contains(where: { item in
item.name == name
}) == true {
if let index = items.firstIndex(where: { item in
item.name == name
}) {
let item = items[index]
item.stopSoundWithVibrate {[weak self] in
self?.items.remove(at: index)
}
}
}
}
public func stopSoundWithVibrate() {
stopSound()
stopVibrate()
public func stopSound(name:String) {
if items.contains(where: { item in
item.name == name
}) == true {
if let index = items.firstIndex(where: { item in
item.name == name
}) {
let item = items[index]
item.stopSound {[weak self] in
self?.items.remove(at: index)
}
}
}
}
public func playSound(audioUrl:URL,numberOfLoops:Int = 1, endCompletionBlock: (() -> Void)? = nil) {
self.audioNumberOfLoops = numberOfLoops
public func stopVibrate(name:String) {
if items.contains(where: { item in
item.name == name
}) == true {
if let index = items.firstIndex(where: { item in
item.name == name
}) {
let item = items[index]
item.stopVibrate {[weak self] in
self?.items.remove(at: index)
}
}
}
}
}
open class DDAudioServiceItem {
fileprivate var name : String
private var audioSoundID : SystemSoundID = 0
private var vibrateSoundID : SystemSoundID = 0
private var endSound : Bool = false
private var endVibrate : Bool = false
private var stopSoundCompletionHander : (() -> Void)?
private var stopVibrateCompletionHander : (() -> Void)?
init(name:String) {
self.name = name
}
public func playSoundWithVibrate(audioUrl:URL,numberOfLoops:Int = 1,timeInterval:TimeInterval = 0, eachLoopCompletionBlock: (() -> Void)? = nil,endCompletionBlock: (() -> Void)? = nil) {
playVibrate(numberOfLoops: -1)
playSound(audioUrl: audioUrl,numberOfLoops: numberOfLoops,timeInterval: timeInterval,eachLoopCompletionBlock: eachLoopCompletionBlock) {[weak self] in
self?.stopVibrate {
if endCompletionBlock != nil {
endCompletionBlock!()
}
}
}
}
public func stopSoundWithVibrate(completionHander:@escaping (() -> Void)) {
stopSound {[weak self] in
self?.stopVibrate {
completionHander()
}
}
}
public func playSound(audioUrl:URL,numberOfLoops:Int = 1,timeInterval:TimeInterval = 0,eachLoopCompletionBlock: (() -> Void)? = nil,endCompletionBlock: (() -> Void)? = nil) {
var audioSoundID:SystemSoundID = 0
AudioServicesCreateSystemSoundID(audioUrl as CFURL, &audioSoundID)
self.audioSoundID = audioSoundID
DispatchQueue.global().async {[weak self] in
self?.playSound(audioSoundID: audioSoundID,leftNumberOfLoops: numberOfLoops,endCompletionBlock: {
if endCompletionBlock != nil {
endCompletionBlock!()
}
})
self?.playSound(audioSoundID: audioSoundID,leftNumberOfLoops: numberOfLoops,timeInterval: timeInterval,eachLoopCompletionBlock: eachLoopCompletionBlock,endCompletionBlock: endCompletionBlock)
}
}
public func playVibrate(numberOfLoops:Int = 1, endCompletionBlock: (() -> Void)? = nil) {
self.audioNumberOfLoops = numberOfLoops
var vibrateSoundID : SystemSoundID = 0
vibrateSoundID = kSystemSoundID_Vibrate
self.vibrateSoundID = vibrateSoundID
DispatchQueue.global().async {[weak self] in
self?.playVibrate(vibrateSoundID: vibrateSoundID, leftNumberOfLoops: numberOfLoops,endCompletionBlock: {
if endCompletionBlock != nil {
endCompletionBlock!()
}
})
}
}
public func stopSound() {
endSound = true
AudioServicesDisposeSystemSoundID(audioSoundID)
}
public func stopVibrate() {
endVibrate = true
AudioServicesDisposeSystemSoundID(vibrateSoundID)
}
private func playSound(audioSoundID:SystemSoundID,leftNumberOfLoops:Int,timeInterval:TimeInterval = 0,eachLoopCompletionBlock: (() -> Void)? = nil, endCompletionBlock: (() -> Void)? = nil) {
private func playSound(audioSoundID:SystemSoundID,leftNumberOfLoops:Int,timeInterval:TimeInterval,eachLoopCompletionBlock: (() -> Void)?, endCompletionBlock: (() -> Void)?) {
var changeLeftNumberOfLoops = leftNumberOfLoops
AudioServicesPlaySystemSoundWithCompletion(audioSoundID) {[weak self] in
// loop
if eachLoopCompletionBlock != nil {
eachLoopCompletionBlock!()
}
@@ -83,22 +132,61 @@ open class DDAudioService {
// 0
changeLeftNumberOfLoops-=1
if changeLeftNumberOfLoops == 0 || self?.endSound == true {
self?.stopSound()
if endCompletionBlock != nil {
//
AudioServicesDisposeSystemSoundID(audioSoundID)
// DDLog(message: "name = \(self?.name ?? "")sound")
//
self?.audioSoundID = 0
self?.endSound = false
// stop
if self?.stopSoundCompletionHander != nil {
self?.stopSoundCompletionHander!()
}else if endCompletionBlock != nil {
// playloops
endCompletionBlock!()
}
print("sound播放结束")
}else{
DispatchQueue.global().asyncAfter(deadline: .now() + timeInterval, execute: {
self?.playSound(audioSoundID: audioSoundID, leftNumberOfLoops: changeLeftNumberOfLoops,timeInterval: timeInterval)
self?.playSound(audioSoundID: audioSoundID, leftNumberOfLoops: changeLeftNumberOfLoops,timeInterval: timeInterval,eachLoopCompletionBlock: eachLoopCompletionBlock,endCompletionBlock: endCompletionBlock)
})
}
}
}
private func playVibrate(vibrateSoundID:SystemSoundID,leftNumberOfLoops:Int,timeInterval:TimeInterval = 0,eachLoopCompletionBlock: (() -> Void)? = nil, endCompletionBlock: (() -> Void)? = nil) {
public func stopSound(completionHandler:@escaping (() -> Void)) {
stopSoundCompletionHander = completionHandler
//
let status = AudioServicesDisposeSystemSoundID(audioSoundID)
// DDLog(message: "sound dispose status = \(status)")
if status != 0 {
//
endSound = true
}else {
audioSoundID = 0
// DDLog(message: "name = \(name)sound")
completionHandler()
}
}
public func playVibrate(numberOfLoops:Int = 1,timeInterval:TimeInterval = 0,eachLoopCompletionBlock: (() -> Void)? = nil,endCompletionBlock: (() -> Void)? = nil) {
self.endVibrate = false
var vibrateSoundID : SystemSoundID = 0
vibrateSoundID = kSystemSoundID_Vibrate
self.vibrateSoundID = vibrateSoundID
DispatchQueue.global().async {[weak self] in
self?.playVibrate(vibrateSoundID: vibrateSoundID, leftNumberOfLoops: numberOfLoops,timeInterval: timeInterval,eachLoopCompletionBlock: eachLoopCompletionBlock,endCompletionBlock: endCompletionBlock)
}
}
private func playVibrate(vibrateSoundID:SystemSoundID,leftNumberOfLoops:Int,timeInterval:TimeInterval = 0,eachLoopCompletionBlock: (() -> Void)?, endCompletionBlock: (() -> Void)?) {
var changeLeftNumberOfLoops = leftNumberOfLoops
AudioServicesPlayAlertSoundWithCompletion(vibrateSoundID) {[weak self] in
// loop
if eachLoopCompletionBlock != nil {
eachLoopCompletionBlock!()
}
@@ -106,17 +194,43 @@ open class DDAudioService {
// 0
changeLeftNumberOfLoops-=1
if changeLeftNumberOfLoops == 0 || self?.endVibrate == true {
self?.stopVibrate()
if endCompletionBlock != nil {
//
AudioServicesDisposeSystemSoundID(vibrateSoundID)
// DDLog(message: "name = \(self?.name ?? "")vibrate")
//
self?.vibrateSoundID = 0
self?.endVibrate = false
// stop
if self?.stopVibrateCompletionHander != nil {
self?.stopVibrateCompletionHander!()
}else if endCompletionBlock != nil {
// playloops
endCompletionBlock!()
}
print("vibrate播放结束")
}else{
DispatchQueue.global().asyncAfter(deadline: .now() + timeInterval, execute: {
self?.playVibrate(vibrateSoundID: vibrateSoundID, leftNumberOfLoops: changeLeftNumberOfLoops,timeInterval: timeInterval)
self?.playVibrate(vibrateSoundID: vibrateSoundID, leftNumberOfLoops: changeLeftNumberOfLoops,timeInterval: timeInterval,eachLoopCompletionBlock: eachLoopCompletionBlock,endCompletionBlock: endCompletionBlock)
})
}
}
}
public func stopVibrate(completionHandler:@escaping (() -> Void)) {
stopVibrateCompletionHander = completionHandler
//
let status = AudioServicesDisposeSystemSoundID(vibrateSoundID)
// DDLog(message: "vibrate dispose status = \(status)")
// if status != 0 {
// //
endVibrate = true
// }else{
// vibrateSoundID = 0
// DDLog(message: "name = \(name)vibrate")
// completionHandler()
// }
}
}

View File

@@ -0,0 +1,93 @@
//
// DDSpeechSynthesizer.swift
// DDAudioPlayerKit_Private
//
// Created by on 2023/9/5.
//
import Foundation
import AVFoundation
public let DDSS = DDSpeechSynthesizer.default
open class DDSpeechSynthesizer {
public static let `default` = DDSpeechSynthesizer()
private var items : [DDSpeechSynthesizerItem] = []
public func play(text:String,name:String,numberOfLoops:Int = 1,timeInterval:TimeInterval = 0,eachLoopCompletionBlock: (() -> Void)? = nil, endCompletionBlock: (() -> Void)? = nil) {
let item = DDSpeechSynthesizerItem(name: name)
items.append(item)
item.play(text: text,numberOfLoops:numberOfLoops,timeInterval:timeInterval,eachLoopCompletionBlock:eachLoopCompletionBlock,endCompletionBlock:endCompletionBlock)
}
public func stop(name:String) {
if items.contains(where: { item in
item.name == name
}) == true {
if let index = items.firstIndex(where: { item in
item.name == name
}) {
let item = items[index]
item.stop()
items.remove(at: index)
}
}
}
}
class DDSpeechSynthesizerItem: NSObject, AVSpeechSynthesizerDelegate {
private var synthesizer : AVSpeechSynthesizer?
private var utterance : AVSpeechUtterance?
public var name : String
private var numberOfLoops : Int = 0
private var timeInterval : TimeInterval = 0
private var eachLoopCompletionBlock : (() -> Void)?
private var endCompletionBlock : (() -> Void)?
init(name:String) {
self.name = name
}
func play(text:String,numberOfLoops:Int,timeInterval:TimeInterval,eachLoopCompletionBlock: (() -> Void)?, endCompletionBlock: (() -> Void)?) {
self.numberOfLoops = numberOfLoops
self.timeInterval = timeInterval
self.eachLoopCompletionBlock = eachLoopCompletionBlock
self.endCompletionBlock = endCompletionBlock
synthesizer = AVSpeechSynthesizer()
synthesizer?.delegate = self
utterance = AVSpeechUtterance(string: text)
utterance?.voice = AVSpeechSynthesisVoice(language: "zh-Hans")
utterance?.rate = AVSpeechUtteranceDefaultSpeechRate
if let utterance {
synthesizer?.speak(utterance)
}
}
public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
if eachLoopCompletionBlock != nil {
eachLoopCompletionBlock!()
}
numberOfLoops-=1
if numberOfLoops == 0 {
if endCompletionBlock != nil {
endCompletionBlock!()
}
}else{
DispatchQueue.global().asyncAfter(deadline: .now() + timeInterval, execute: {[weak self] in
if let utterance = self?.utterance {
self?.synthesizer?.speak(utterance)
}
})
}
}
func stop() {
synthesizer?.stopSpeaking(at: .immediate)
synthesizer?.delegate = nil
synthesizer = nil
utterance = nil
}
}