Compare commits

..

12 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
tanhakabir ddf26e206e Release 7.3.0 (adds Changelog) 2021-08-17 10:16:26 -07:00
tanhakabir e319134eb8 Merge pull request #144 from cntrump/pr/replace_deprecated_method
Replace deprecated subscribe method.
2021-08-17 10:12:51 -07:00
Lvv.me 9599f66a0f Replace deprecated subscribe method. 2021-08-17 19:58:44 +08:00
tanhakabir ef231a2570 Release 7.2.1 2021-08-17 03:51:21 -07:00
tanhakabir 350e6ec064 Fix directory bug 2021-08-17 03:51:01 -07:00
tanhakabir ad63b89ede Release 7.2.0 2021-08-17 03:38:52 -07:00
tanhakabir 43e887b823 Merge pull request #143 from tanhakabir/issue-138
Experimental set download location
2021-08-17 03:38:28 -07:00
9 changed files with 87 additions and 50 deletions
+6
View File
@@ -0,0 +1,6 @@
# Changelog
## 7.3.0
- Take in PR from @cntrump to use the non-deprecated subscription pattern in loop feature
+2
View File
@@ -135,6 +135,7 @@
A470FE1B25F9AEB900F135FF /* AudioQueueDirector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioQueueDirector.swift; sourceTree = "<group>"; };
A470FE2025F9AF1400F135FF /* AudioQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioQueue.swift; sourceTree = "<group>"; };
A4827770262A216C00B6918A /* StreamingDownloadDirector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StreamingDownloadDirector.swift; sourceTree = "<group>"; };
A4883AC926CC25DE0073B8B6 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = "<group>"; };
A4B4CC112223ED2A0045554B /* SAPlayerDownloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SAPlayerDownloader.swift; sourceTree = "<group>"; };
A4FBA6B3221B74C900D5A353 /* SAPlayerHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SAPlayerHelpers.swift; sourceTree = "<group>"; };
A4FBA6B6221BAC3D00D5A353 /* SAPlayerUpdateSubscription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SAPlayerUpdateSubscription.swift; sourceTree = "<group>"; };
@@ -255,6 +256,7 @@
children = (
15DF3E7F1B5E10B1BBE49D3E9A67C938 /* LICENSE */,
B8C829A46249957CD3056074B5CC0BBB /* README.md */,
A4883AC926CC25DE0073B8B6 /* CHANGELOG.md */,
6EC04ECC8F7CB2AF2E4E042A6A8ECFA1 /* SwiftAudioPlayer.podspec */,
A4523BC8220A0B3C0079C4BC /* Credited_LICENSE */,
);
+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]
+6 -1
View File
@@ -64,9 +64,14 @@ struct FileStorage {
// MARK:- Audio
extension FileStorage {
struct Audio {
private static let directory: FileManager.SearchPathDirectory = AudioDataManager.shared.downloadDirectory
private init() {}
private static var directory: FileManager.SearchPathDirectory {
get {
return AudioDataManager.shared.downloadDirectory
}
}
static func isStored(_ id: ID) -> Bool {
guard let url = locate(id)?.path else {
return false
+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.
+1 -1
View File
@@ -147,7 +147,7 @@ extension SAPlayer {
guard playingStatusId == nil else { return }
playingStatusId = SAPlayer.Updates.PlayingStatus.subscribe({ (url, status) in
playingStatusId = SAPlayer.Updates.PlayingStatus.subscribe({ (status) in
if status == .ended && enabled {
SAPlayer.shared.seekTo(seconds: 0.0)
SAPlayer.shared.play()
+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.1.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.