Compare commits

...

5 Commits

Author SHA1 Message Date
tanhakabir 879a2816be Release 7.4.0 2021-09-10 11:09:37 -07:00
tanhakabir 2c3ebefd54 Merge pull request #149 from jiangdi0924/master
SAPlayer.shared.audioQueued  no content ,So i fixed it. ( Not sure if it is a good solution, Please review it)
2021-08-26 15:26:51 -07:00
Norton 862dd47509 I found out that SAPlayer.shared.audioQueued no content, and i think it's maybe a bug. 2021-08-26 15:17:55 +08:00
tanhakabir dee22d5193 Merge pull request #147 from cntrump/pr/improve_lockscreen_control
Lockscreen Media Player as public for other players.
2021-08-20 15:24:01 -07:00
Lvv.me 9dd479e377 Lockscreen Media Player as public for other players. 2021-08-19 20:08:20 +08:00
5 changed files with 72 additions and 48 deletions
+1 -1
View File
@@ -171,7 +171,7 @@ You can also directly access and modify the queue from `SAPlayer.shared.audioQue
The engine can handle audio manipulations like speed, pitch, effects, etc. To do this, nodes for effects must be finalized before initialize is called. Look at [audio manipulation documentation](#realtime-audio-manipulation) for more information.
### Lockscreen Media Player
### LockScreen Media Player
Update and set what displays on the lockscreen's media player when the player is active.
+26 -11
View File
@@ -27,20 +27,35 @@ import Foundation
import MediaPlayer
import UIKit
public protocol LockScreenViewPresenter : AnyObject {
func getIsPlaying() -> Bool
func handlePlay()
func handlePause()
func handleSkipBackward()
func handleSkipForward()
func handleSeek(toNeedle needle: Double)
}
// MARK: - Set up lockscreen audio controls
// Documentation: https://developer.apple.com/documentation/avfoundation/media_assets_playback_and_editing/creating_a_basic_video_player_ios_and_tvos/controlling_background_audio
protocol LockScreenViewProtocol {
public protocol LockScreenViewProtocol {
var skipForwardSeconds: Double { get set }
var skipBackwardSeconds: Double { get set }
}
extension LockScreenViewProtocol {
public extension LockScreenViewProtocol {
func clearLockScreenInfo() {
MPNowPlayingInfoCenter.default().nowPlayingInfo = [:]
MPNowPlayingInfoCenter.default().nowPlayingInfo = [:]
let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.playCommand.removeTarget(nil)
commandCenter.pauseCommand.removeTarget(nil)
commandCenter.skipBackwardCommand.removeTarget(nil)
commandCenter.skipForwardCommand.removeTarget(nil)
commandCenter.changePlaybackPositionCommand.removeTarget(nil)
}
@available(iOS 10.0, tvOS 10.0, *)
func setLockScreenInfo(withMediaInfo info: SALockScreenInfo?, duration: Duration) {
func setLockScreenInfo(withMediaInfo info: SALockScreenInfo?, duration: Double) {
var nowPlayingInfo:[String : Any] = [:]
guard let info = info else {
@@ -82,7 +97,7 @@ extension LockScreenViewProtocol {
}
// https://stackoverflow.com/questions/36754934/update-mpremotecommandcenter-play-pause-button
func setLockScreenControls(presenter: SAPlayerPresenter) { //FIXME: this is weird
func setLockScreenControls(presenter: LockScreenViewPresenter) {
// Get the shared MPRemoteCommandCenter
let commandCenter = MPRemoteCommandCenter.shared()
@@ -146,29 +161,29 @@ extension LockScreenViewProtocol {
}
}
func updateLockscreenElapsedTime(needle: Needle) {
func updateLockScreenElapsedTime(needle: Double) {
MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPNowPlayingInfoPropertyElapsedPlaybackTime] = NSNumber(value: Double(needle))
}
func updateLockscreenPlaybackDuration(duration: Duration) {
func updateLockScreenPlaybackDuration(duration: Double) {
MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPMediaItemPropertyPlaybackDuration] = NSNumber(value: duration)
}
func updateLockscreenPaused(){
func updateLockScreenPaused(){
MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPNowPlayingInfoPropertyPlaybackRate] = 0.0
}
func updateLockscreenPlaying(){
func updateLockScreenPlaying(){
MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPNowPlayingInfoPropertyPlaybackRate] = 1.0
}
func updateLockscreenChangePlaybackRate(speed: Float){
func updateLockScreenChangePlaybackRate(speed: Float){
if speed > 0.0{
MPNowPlayingInfoCenter.default().nowPlayingInfo?[MPNowPlayingInfoPropertyPlaybackRate] = speed
}
}
func updateLockscreenSkipIntervals() {
func updateLockScreenSkipIntervals() {
let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.skipBackwardCommand.isEnabled = skipBackwardSeconds > 0
commandCenter.skipBackwardCommand.preferredIntervals = [skipBackwardSeconds] as [NSNumber]
+8 -1
View File
@@ -182,7 +182,14 @@ public class SAPlayer {
/**
List of queued audio for playback. You can edit this list as you wish to modify the queue.
*/
public var audioQueued: [SAAudioQueueItem] = []
public var audioQueued: [SAAudioQueueItem] {
get {
return presenter.audioQueue
}
set {
presenter.audioQueue = newValue
}
}
/**
Total duration of current audio initialized. Returns nil if no audio is initialized in player.
+36 -34
View File
@@ -46,13 +46,11 @@ class SAPlayerPresenter {
init(delegate: SAPlayerDelegate?) {
self.delegate = delegate
delegate?.setLockScreenControls(presenter: self)
durationRef = AudioClockDirector.shared.attachToChangesInDuration(closure: { [weak self] (duration) in
guard let self = self else { throw DirectorError.closureIsDead }
self.delegate?.updateLockscreenPlaybackDuration(duration: duration)
self.delegate?.updateLockScreenPlaybackDuration(duration: duration)
self.duration = duration
self.delegate?.setLockScreenInfo(withMediaInfo: self.delegate?.mediaInfo, duration: duration)
@@ -62,7 +60,7 @@ class SAPlayerPresenter {
guard let self = self else { throw DirectorError.closureIsDead }
self.needle = needle
self.delegate?.updateLockscreenElapsedTime(needle: needle)
self.delegate?.updateLockScreenElapsedTime(needle: needle)
})
playingStatusRef = AudioClockDirector.shared.attachToChangesInPlayingStatus(closure: { [weak self] (isPlaying) in
@@ -106,11 +104,13 @@ class SAPlayerPresenter {
func handlePlaySavedAudio(withSavedUrl url: URL) {
resetCacheForNewAudio(url: url)
delegate?.setLockScreenControls(presenter: self)
delegate?.startAudioDownloaded(withSavedUrl: url)
}
func handlePlayStreamedAudio(withRemoteUrl url: URL, bitrate: SAPlayerBitrate) {
resetCacheForNewAudio(url: url)
delegate?.setLockScreenControls(presenter: self)
delegate?.startAudioStreamed(withRemoteUrl: url, bitrate: bitrate)
}
@@ -156,16 +156,7 @@ class SAPlayerPresenter {
//MARK:- Used by outside world including:
// SPP, lock screen, directors
extension SAPlayerPresenter {
func handlePause() {
delegate?.pauseEngine()
self.delegate?.updateLockscreenPaused()
}
func handlePlay() {
delegate?.playEngine()
self.delegate?.updateLockscreenPlaying()
}
func handleTogglePlayingAndPausing() {
if isPlaying == .playing {
handlePause()
@@ -173,35 +164,46 @@ extension SAPlayerPresenter {
handlePlay()
}
}
func handleSkipForward() {
guard let forward = delegate?.skipForwardSeconds else { return }
handleSeek(toNeedle: (needle ?? 0) + forward)
func handleAudioRateChanged(rate: Float) {
delegate?.updateLockScreenChangePlaybackRate(speed: rate)
}
func handleScrubbingIntervalsChanged() {
delegate?.updateLockScreenSkipIntervals()
}
}
//MARK:- For lock screen
extension SAPlayerPresenter : LockScreenViewPresenter {
func getIsPlaying() -> Bool {
return isPlaying == .playing
}
func handlePlay() {
delegate?.playEngine()
self.delegate?.updateLockScreenPlaying()
}
func handlePause() {
delegate?.pauseEngine()
self.delegate?.updateLockScreenPaused()
}
func handleSkipBackward() {
guard let backward = delegate?.skipForwardSeconds else { return }
handleSeek(toNeedle: (needle ?? 0) - backward)
}
func handleSkipForward() {
guard let forward = delegate?.skipForwardSeconds else { return }
handleSeek(toNeedle: (needle ?? 0) + forward)
}
func handleSeek(toNeedle needle: Needle) {
delegate?.seekEngine(toNeedle: needle)
}
func handleAudioRateChanged(rate: Float) {
delegate?.updateLockscreenChangePlaybackRate(speed: rate)
}
func handleScrubbingIntervalsChanged() {
delegate?.updateLockscreenSkipIntervals()
}
}
//MARK:- For lock screen
extension SAPlayerPresenter {
func getIsPlaying() -> Bool {
return isPlaying == .playing
}
}
//MARK:- AVAudioEngineDelegate
+1 -1
View File
@@ -8,7 +8,7 @@
Pod::Spec.new do |s|
s.name = 'SwiftAudioPlayer'
s.version = '7.3.0'
s.version = '7.4.0'
s.summary = 'SwiftAudioPlayer is a Swift based audio player that can handle streaming from a remote location and audio manipulation.'
# This description is used to generate tags and improve search results.