Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(infra): Update runners #76

Merged
merged 3 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,10 @@ concurrency:
cancel-in-progress: true
jobs:
unit-tests:
runs-on: macos-latest
runs-on: blaze/macos-14
strategy:
matrix:
destination:
[
'platform=iOS Simulator,name=iPhone 12 Pro',
]
destination: ["platform=iOS Simulator,name=iPhone 15 Pro"]
steps:
- name: Checkout Repo
uses: actions/checkout@v2
Expand Down
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

SwiftAudioEx is an audio player written in Swift, making it simpler to work with audio playback from streams and files.

_[Blaze](https://runblaze.dev) sponsors SwiftAudioEx by providing super fast Apple Silicon based macOS Github Action Runners. Use the discount code `RNTP50` at checkout to get 50% off your first year._

## Example

To see the audio player in action, run the example project!
Expand All @@ -16,11 +18,13 @@ XCode project navigator and Build/Run it in a simulator (or on an actual
device).

## Requirements

iOS 11.0+

## Installation

### Swift Package Manager

[Swift Package Manager](https://swift.org/package-manager/) (SwiftPM) is a tool for managing the distribution of Swift code as well as C-family dependency. From Xcode 11, SwiftPM got natively integrated with Xcode.

SwiftAudioEx supports SwiftPM from version 0.12.0. To use SwiftPM, you should use Xcode 11 to open your project. Click `File` -> `Swift Packages` -> `Add Package Dependency`, enter [SwiftAudioEx repo's URL](https://github.com/doublesymmetry/SwiftAudio.git). Or you can login Xcode with your GitHub account and just type `SwiftAudioEx` to search.
Expand All @@ -40,6 +44,7 @@ let package = Package(
```

### CocoaPods

SwiftAudioEx is available through [CocoaPods](http://cocoapods.org). To install
it, simply add the following line to your Podfile:

Expand All @@ -48,16 +53,21 @@ pod 'SwiftAudioEx', '~> 1.0.0'
```

### Carthage

SwiftAudioEx supports [Carthage](https://github.com/Carthage/Carthage). Add this to your Cartfile:

```ruby
github "doublesymmetry/SwiftAudioEx" ~> 1.0.0
```

Then follow the rest of Carthage instructions on [adding a framework](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application).

## Usage

### AudioPlayer

To get started playing some audio:

```swift
let player = AudioPlayer()
let audioItem = DefaultAudioItem(audioUrl: "someUrl", sourceType: .stream)
Expand All @@ -66,6 +76,7 @@ player.load(item: audioItem, playWhenReady: true) // Load the item and start pla

To listen for events in the `AudioPlayer`, subscribe to events found in the `event` property of the `AudioPlayer`.
To subscribe to an event:

```swift
class MyCustomViewController: UIViewController {

Expand All @@ -83,7 +94,9 @@ class MyCustomViewController: UIViewController {
```

#### QueuedAudioPlayer

The `QueuedAudioPlayer` is a subclass of `AudioPlayer` that maintains a queue of audio tracks.

```swift
let player = QueuedAudioPlayer()
let audioItem = DefaultAudioItem(audioUrl: "someUrl", sourceType: .stream)
Expand All @@ -93,21 +106,26 @@ player.add(item: audioItem, playWhenReady: true) // Since this is the first item
When a track is done playing, the player will load the next track and update the queue.

##### Navigating the queue

All `AudioItem`s are stored in either `previousItems` or `nextItems`, which refers to items that come prior to the `currentItem` and after, respectively. The queue is navigated with:

```swift
player.next() // Increments the queue, and loads the next item.
player.previous() // Decrements the queue, and loads the previous item.
player.jumpToItem(atIndex:) // Jumps to a certain item and loads that item.
```

##### Manipulating the queue

```swift
player.removeItem(at:) // Remove a specific item from the queue.
player.removeUpcomingItems() // Remove all items in nextItems.
```

### Configuring the AudioPlayer

Current options for configuring the `AudioPlayer`:

- `bufferDuration`: The amount of seconds to be buffered by the player.
- `timeEventFrequency`: How often the player should call the delegate with time progress events.
- `automaticallyWaitsToMinimizeStalling`: Indicates whether the player should automatically delay playback in order to minimize stalling.
Expand All @@ -117,10 +135,13 @@ Current options for configuring the `AudioPlayer`:
- `audioTimePitchAlgorithm`: This value decides the `AVAudioTimePitchAlgorithm` used for each `AudioItem`. Implement `TimePitching` in your `AudioItem`-subclass to override individually for each `AudioItem`.

Options particular to `QueuedAudioPlayer`:

- `repeatMode`: The repeat mode: off, track, queue

### Audio Session

Remember to activate an audio session with an appropriate category for your app. This can be done with `AudioSessionController`:

```swift
try? AudioSessionController.shared.set(category: .playback)
//...
Expand All @@ -133,34 +154,43 @@ try? AudioSessionController.shared.activateSession()
App Settings -> Capabilities -> Background Modes -> Check 'Audio, AirPlay, and Picture in Picture'.

#### Interruptions

If you are using the `AudioSessionController` for setting up the audio session, you can use it to handle interruptions too.
Implement `AudioSessionControllerDelegate` and you will be notified by `handleInterruption(type: AVAudioSessionInterruptionType)`.
If you are storing progress for playback time on items when the app quits, it can be a good idea to do it on interruptions as well.
To disable interruption notifcations set `isObservingForInterruptions` to `false`.

### Now Playing Info

The `AudioPlayer` can automatically update `nowPlayingInfo` for you. This requires `automaticallyUpdateNowPlayingInfo` to be true (default), and that the `AudioItem` that is passed in return values for the getters. The `AudioPlayer` will update: artist, title, album, artwork, elapsed time, duration and rate.

Additional properties for items can be set by accessing the setter of the `nowPlayingInforController`:

```swift
let player = AudioPlayer()
player.load(item: someItem)
player.nowPlayingInfoController.set(keyValue: NowPlayingInfoProperty.isLiveStream(true))
```

The set(keyValue:) and set(keyValues:) accept both `MediaItemProperty` and `NowPlayingInfoProperty`.

The info can be forced to reload/update from the `AudioPlayer`.

```swift
audioPlayer.loadNowPlayingMetaValues()
audioPlayer.updateNowPlayingPlaybackValues()
```

The current info can be cleared with:

```swift
audioPlayer.nowPlayingInfoController.clear()
```

### Remote Commands

To enable remote commands for the player you need to populate the RemoteCommands array for the player:

```swift
audioPlayer.remoteCommands = [
.play,
Expand All @@ -169,19 +199,24 @@ audioPlayer.remoteCommands = [
.skipBackward(intervals: [30]),
]
```

These commands will be activated for each `AudioItem`. If you need some audio items to have different commands, implement `RemoteCommandable` in a custom `AudioItem`-subclass. These commands will override the commands found in `AudioPlayer.remoteCommands` so make sure to supply all commands you need for that particular `AudioItem`.

#### Custom handlers for remote commands

To supply custom handlers for your remote commands, just override the handlers contained in the player's `RemoteCommandController`:

```swift
let player = QueuedAudioPlayer()
player.remoteCommandController.handlePlayCommand = { (event) in
// Handle remote command here.
}
```

All available overrides can be found by looking at `RemoteCommandController`.

### Start playback from a certain point in time

Make your `AudioItem`-subclass conform to `InitialTiming` to be able to start playback from a certain time.

## Author
Expand Down
Loading