Compare commits

..

11 Commits

Author SHA1 Message Date
David Chavez 40ea7ad2f9 Release 0.14.7 2022-02-24 08:49:31 +01:00
David Chavez f2f1c1236c Add tests for new seek improvements 2022-02-24 08:48:54 +01:00
Terkel a75f0d0201 fix: make moveItem public and accessible from outside the class (#9) 2022-02-23 21:40:39 +01:00
Jacob Spizziri 9e4e7f6807 fix(seek): fix an issue causing seek to fail if called immediatly after load (#11) 2022-02-23 21:27:38 +01:00
David Chavez dbd3b03989 Release 0.14.6 2021-11-06 14:38:13 +01:00
David Chavez 7e19604df7 Create LICENSE (#5)
* Create LICENSE

* Update LICENSE
2021-11-06 14:29:06 +01:00
David Chavez 481130dc58 Release 0.14.5 2021-10-25 14:08:31 +02:00
David Chavez 300b34afa3 Do not emit paused state when changing tracks 2021-10-25 14:08:01 +02:00
David Chavez da3af0e9db Release 0.14.4 2021-09-28 10:58:23 +02:00
David Chavez d9eb313c1b Deprecate syncRemoteCommandsWithCommandCenter 2021-09-28 10:57:36 +02:00
David Chavez cca7f68da4 Increase deployment target for Test Target 2021-09-28 10:12:22 +02:00
7 changed files with 100 additions and 23 deletions
+12 -10
View File
@@ -44,9 +44,9 @@
607FACEC1AFB9204008FA782 /* AVPlayerObserverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* AVPlayerObserverTests.swift */; };
9B05AA312660276400C7A389 /* Quick in Frameworks */ = {isa = PBXBuildFile; productRef = 9B05AA302660276400C7A389 /* Quick */; };
9B05AA332660276400C7A389 /* Nimble in Frameworks */ = {isa = PBXBuildFile; productRef = 9B05AA322660276400C7A389 /* Nimble */; };
9B1D5E1E27C76F5C004CA883 /* SwiftAudioEx in Frameworks */ = {isa = PBXBuildFile; productRef = 9B1D5E1D27C76F5C004CA883 /* SwiftAudioEx */; };
9B1D5E2027C76F6F004CA883 /* SwiftAudioEx in Frameworks */ = {isa = PBXBuildFile; productRef = 9B1D5E1F27C76F6F004CA883 /* SwiftAudioEx */; };
9B521D0E2662937600EF0C3A /* MockDispatchQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B521D0D2662937600EF0C3A /* MockDispatchQueue.swift */; };
9B77D79426C522D0004BAF2F /* SwiftAudioEx in Frameworks */ = {isa = PBXBuildFile; productRef = 9B77D79326C522D0004BAF2F /* SwiftAudioEx */; };
9B77D79626C52382004BAF2F /* SwiftAudioEx in Frameworks */ = {isa = PBXBuildFile; productRef = 9B77D79526C52382004BAF2F /* SwiftAudioEx */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -94,7 +94,7 @@
607FACE51AFB9204008FA782 /* SwiftAudio_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftAudio_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
607FACEB1AFB9204008FA782 /* AVPlayerObserverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVPlayerObserverTests.swift; sourceTree = "<group>"; };
9B05AA38266028D600C7A389 /* SwiftAudio */ = {isa = PBXFileReference; lastKnownFileType = folder; name = SwiftAudio; path = ..; sourceTree = "<group>"; };
9B1D5E1C27C76F49004CA883 /* SwiftAudioEx */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = SwiftAudioEx; path = ..; sourceTree = "<group>"; };
9B521D0D2662937600EF0C3A /* MockDispatchQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockDispatchQueue.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -103,7 +103,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9B77D79426C522D0004BAF2F /* SwiftAudioEx in Frameworks */,
9B1D5E2027C76F6F004CA883 /* SwiftAudioEx in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -111,7 +111,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9B77D79626C52382004BAF2F /* SwiftAudioEx in Frameworks */,
9B1D5E1E27C76F5C004CA883 /* SwiftAudioEx in Frameworks */,
9B05AA312660276400C7A389 /* Quick in Frameworks */,
9B05AA332660276400C7A389 /* Nimble in Frameworks */,
);
@@ -222,7 +222,7 @@
9B05AA2F2660276400C7A389 /* Frameworks */ = {
isa = PBXGroup;
children = (
9B05AA38266028D600C7A389 /* SwiftAudio */,
9B1D5E1C27C76F49004CA883 /* SwiftAudioEx */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -244,7 +244,7 @@
);
name = SwiftAudio_Example;
packageProductDependencies = (
9B77D79326C522D0004BAF2F /* SwiftAudioEx */,
9B1D5E1F27C76F6F004CA883 /* SwiftAudioEx */,
);
productName = SwiftAudio;
productReference = 607FACD01AFB9204008FA782 /* SwiftAudio_Example.app */;
@@ -267,7 +267,7 @@
packageProductDependencies = (
9B05AA302660276400C7A389 /* Quick */,
9B05AA322660276400C7A389 /* Nimble */,
9B77D79526C52382004BAF2F /* SwiftAudioEx */,
9B1D5E1D27C76F5C004CA883 /* SwiftAudioEx */,
);
productName = Tests;
productReference = 607FACE51AFB9204008FA782 /* SwiftAudio_Tests.xctest */;
@@ -577,6 +577,7 @@
"$(inherited)",
);
INFOPLIST_FILE = Tests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -598,6 +599,7 @@
"$(inherited)",
);
INFOPLIST_FILE = Tests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -672,11 +674,11 @@
package = 9B05AA2C2660274F00C7A389 /* XCRemoteSwiftPackageReference "Nimble" */;
productName = Nimble;
};
9B77D79326C522D0004BAF2F /* SwiftAudioEx */ = {
9B1D5E1D27C76F5C004CA883 /* SwiftAudioEx */ = {
isa = XCSwiftPackageProductDependency;
productName = SwiftAudioEx;
};
9B77D79526C52382004BAF2F /* SwiftAudioEx */ = {
9B1D5E1F27C76F6F004CA883 /* SwiftAudioEx */ = {
isa = XCSwiftPackageProductDependency;
productName = SwiftAudioEx;
};
+11
View File
@@ -145,6 +145,17 @@ class AVPlayerWrapperTests: XCTestCase {
wrapper.load(from: Source.url, playWhenReady: false)
wait(for: [expectation], timeout: 20.0)
}
func test_AVPlayerWrapper__seeking__should_seek_while_not_yet_loaded() {
let seekTime: TimeInterval = 5.0
let expectation = XCTestExpectation()
holder.didSeekTo = { seconds in
expectation.fulfill()
}
wrapper.load(from: Source.url, playWhenReady: false)
wrapper.seek(to: seekTime)
wait(for: [expectation], timeout: 20.0)
}
func test_AVPlayerWrapper__loading_source_with_initial_time__should_seek() {
let expectation = XCTestExpectation()
+42
View File
@@ -0,0 +1,42 @@
MIT License
Copyright (c) 2021 Double Symmetry
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Copyright (c) 2018 Jørgen Henrichsen <jh.henrichs@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+1 -1
View File
@@ -8,7 +8,7 @@
Pod::Spec.new do |s|
s.name = 'SwiftAudioEx'
s.version = '0.14.3'
s.version = '0.14.7'
s.summary = 'Easy audio streaming for iOS'
s.description = <<-DESC
SwiftAudioEx is an audio player written in Swift, making it simpler to work with audio playback from streams and files.
@@ -37,6 +37,9 @@ class AVPlayerWrapper: AVPlayerWrapperProtocol {
*/
fileprivate var _playWhenReady: Bool = true
fileprivate var _initialTime: TimeInterval?
/// True when the track was paused for the purpose of switching tracks
fileprivate var _pausedForLoad: Bool = false
fileprivate var _state: AVPlayerWrapperState = AVPlayerWrapperState.idle {
didSet {
@@ -100,7 +103,7 @@ class AVPlayerWrapper: AVPlayerWrapperProtocol {
return seconds
}
else if let seconds = currentItem?.loadedTimeRanges.first?.timeRangeValue.duration.seconds,
!seconds.isNaN {
!seconds.isNaN {
return seconds
}
return 0.0
@@ -162,16 +165,21 @@ class AVPlayerWrapper: AVPlayerWrapperProtocol {
}
func seek(to seconds: TimeInterval) {
avPlayer.seek(to: CMTimeMakeWithSeconds(seconds, preferredTimescale: 1000)) { (finished) in
if let _ = self._initialTime {
self._initialTime = nil
if self._playWhenReady {
self.play()
}
}
self.delegate?.AVWrapper(seekTo: Int(seconds), didFinish: finished)
}
}
// if the player is loading then we need to defer seeking until it's ready.
if (self._state == AVPlayerWrapperState.loading) {
self._initialTime = seconds
} else {
avPlayer.seek(to: CMTimeMakeWithSeconds(seconds, preferredTimescale: 1000)) { (finished) in
if let _ = self._initialTime {
self._initialTime = nil
if self._playWhenReady {
self.play()
}
}
self.delegate?.AVWrapper(seekTo: Int(seconds), didFinish: finished)
}
}
}
@@ -236,7 +244,10 @@ class AVPlayerWrapper: AVPlayerWrapperProtocol {
func load(from url: URL, playWhenReady: Bool, initialTime: TimeInterval? = nil, options: [String : Any]? = nil) {
_initialTime = initialTime
_pausedForLoad = true
self.pause()
self.load(from: url, playWhenReady: playWhenReady, options: options)
}
@@ -277,6 +288,7 @@ extension AVPlayerWrapper: AVPlayerObserverDelegate {
if currentItem == nil {
_state = .idle
}
else if _pausedForLoad == true {}
else {
self._state = .paused
}
@@ -293,6 +305,7 @@ extension AVPlayerWrapper: AVPlayerObserverDelegate {
switch status {
case .readyToPlay:
self._state = .ready
self._pausedForLoad = false
if _playWhenReady && (_initialTime ?? 0) == 0 {
self.play()
}
+9
View File
@@ -240,6 +240,15 @@ public class AudioPlayer: AVPlayerWrapperDelegate {
self.enableRemoteCommands(remoteCommands)
}
}
/**
Syncs the current remoteCommands with the iOS command center.
Can be used to update item states - e.g. like, dislike and bookmark.
*/
@available(*, deprecated, message: "Directly set .remoteCommands instead")
public func syncRemoteCommandsWithCommandCenter() {
self.enableRemoteCommands(remoteCommands)
}
// MARK: - NowPlayingInfo
+1 -1
View File
@@ -178,7 +178,7 @@ public class QueuedAudioPlayer: AudioPlayer, QueueManagerDelegate {
- parameter toIndex: The index to move the item to.
- throws: `APError.QueueError`
*/
func moveItem(fromIndex: Int, toIndex: Int) throws {
public func moveItem(fromIndex: Int, toIndex: Int) throws {
try queueManager.moveItem(fromIndex: fromIndex, toIndex: toIndex)
}