Compare commits

..

4 Commits

Author SHA1 Message Date
Tanha 159627c63e Release 2.4.0 2019-12-03 01:43:45 -08:00
tanhakabir 07230cce1a add another status to PlayingStatus for end of audio (#19) 2019-12-03 01:42:56 -08:00
tanhakabir a33aee80d1 Expose engine outside of SAPlayer (#18)
* expose engine outside of player

* add player clearing functionality
2019-12-03 01:25:58 -08:00
tanhakabir e1d3da1ddb Update README.md 2019-12-01 11:10:12 -08:00
10 changed files with 68 additions and 7 deletions
@@ -174,6 +174,10 @@ class ViewController: UIViewController {
self.isPlayable = false
self.playPauseButton.setTitle("Loading", for: .normal)
return
case .ended:
self.isPlayable = false
self.playPauseButton.setTitle("Done", for: .normal)
return
}
}
}
+3 -3
View File
@@ -20,8 +20,8 @@ iOS 10.0 and higher.
1. Clone repo
2. CD to directory
3. run `pod install` in terminal
4. Run
3. Run `pod install` in terminal
4. Build and run
### Installation
@@ -252,7 +252,7 @@ Changes in the duration of the current initialized audio. Especially helpful for
### PlayingStatus
Payload = `SAPlayingStatus`
Changes in the playing status of the player. Can be one of the following 3: `playing`, `paused`, `buffering`.
Changes in the playing status of the player. Can be one of the following 4: `playing`, `paused`, `buffering`, `ended` (audio ended).
### StreamingBuffer
Payload = `SAAudioAvailabilityRange`
+1 -1
View File
@@ -98,7 +98,7 @@ class AudioDiskEngine: AudioEngine {
if state == .resumed {
state = .suspended
}
delegate?.didEndPlaying()
playingStatus = .ended
}
guard audioSampleRate != 0 else {
+6 -1
View File
@@ -27,6 +27,7 @@ import Foundation
import AVFoundation
protocol AudioEngineProtocol {
var engine: AVAudioEngine { get set }
func play()
func pause()
func seek(toNeedle needle: Needle)
@@ -42,7 +43,7 @@ class AudioEngine: AudioEngineProtocol {
weak var delegate:AudioEngineDelegate?
let key:Key
let engine = AVAudioEngine()
var engine = AVAudioEngine()
let playerNode = AVAudioPlayerNode()
var timer: Timer?
@@ -77,6 +78,10 @@ class AudioEngine: AudioEngineProtocol {
return
}
if status == .ended {
delegate?.didEndPlaying()
}
AudioClockDirector.shared.audioPlayingStatusWasChanged(key, status: status)
}
}
+1 -1
View File
@@ -240,7 +240,7 @@ class AudioStreamEngine: AudioEngine {
Log.info("reached end of audio")
seek(toNeedle: 0)
pause()
delegate?.didEndPlaying()
playingStatus = .ended
}
needle = (currentTime + currentTimeOffset)
}
+1
View File
@@ -30,4 +30,5 @@ public enum SAPlayingStatus {
case playing
case paused
case buffering
case ended
}
+4
View File
@@ -35,6 +35,10 @@ protocol LockScreenViewProtocol {
}
extension LockScreenViewProtocol {
func clearLockScreenInfo() {
MPNowPlayingInfoCenter.default().nowPlayingInfo = [:]
}
@available(iOS 10.0, *)
func setLockScreenInfo(withMediaInfo info: SALockScreenInfo?, duration: Duration) {
var nowPlayingInfo:[String : Any] = [:]
+35
View File
@@ -35,6 +35,33 @@ public class SAPlayer {
private var presenter: SAPlayerPresenter!
private var player: AudioEngine?
/**
Access the engine of the player. Engine is nil if player has not been initialized with audio.
- Important: Changes to the engine are not safe guarded, thus unknown behaviour can arise from changing the engine. Just be wary and read [documentation of AVAudioEngine](https://developer.apple.com/documentation/avfoundation/avaudioengine) well when modifying,
*/
public var engine: AVAudioEngine? {
get {
return player?.engine
}
}
/**
Corresponding to the overall volume of the player. Volume's default value is 1.0 and the range of valid values is 0.0 to 1.0. Volume is nil if no audio has been initialized yet.
*/
public var volume: Float? {
get {
return player?.engine.mainMixerNode.volume
}
set {
guard let value = newValue else { return }
guard value >= 0.0 && value <= 1.0 else { return }
player?.engine.mainMixerNode.volume = value
}
}
/**
Corresponding to the skipping forward button on the media player on the lockscreen. Default is set to 30 seconds.
*/
@@ -254,6 +281,14 @@ extension SAPlayer {
self.mediaInfo = mediaInfo
presenter.handlePlayStreamedAudio(withRemoteUrl: url)
}
/**
Resets the player to the state before initializing audio and setting media info.
*/
public func clear() {
player = nil
presenter.handleClear()
}
}
+12
View File
@@ -60,6 +60,18 @@ class SAPlayerPresenter {
urlKeyMap[url.key] = url
}
func handleClear() {
needle = nil
duration = nil
key = nil
mediaInfo = nil
delegate?.clearLockScreenInfo()
AudioClockDirector.shared.detachFromChangesInDuration(withID: durationRef)
AudioClockDirector.shared.detachFromChangesInNeedle(withID: needleRef)
AudioClockDirector.shared.detachFromChangesInPlayingStatus(withID: playingStatusRef)
}
func handlePlaySavedAudio(withSavedUrl url: URL) {
attachForUpdates(url: url)
delegate?.startAudioDownloaded(withSavedUrl: url)
+1 -1
View File
@@ -8,7 +8,7 @@
Pod::Spec.new do |s|
s.name = 'SwiftAudioPlayer'
s.version = '2.3.0'
s.version = '2.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.