Skip to content

Commit

Permalink
Merge tag 'just_audio-v0.9.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanheise committed Jul 18, 2021
2 parents 67389a8 + 49d8587 commit a3875e5
Show file tree
Hide file tree
Showing 135 changed files with 4,977 additions and 161 deletions.
4 changes: 4 additions & 0 deletions just_audio/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.9.0

* Update to support just_audio_background.

## 0.8.1

* Fix update position bug on Android.
Expand Down
6 changes: 4 additions & 2 deletions just_audio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@

just_audio is a feature-rich audio player for Android, iOS, macOS and web.

![Screenshot with arrows pointing to features](https://user-images.githubusercontent.com/19899190/109920560-92bff580-7d0e-11eb-82fe-bbaaba50d87d.png)
![Screenshot with arrows pointing to features](https://user-images.githubusercontent.com/19899190/125459608-e89cd6d4-9f09-426c-abcc-ed7513d9acfc.png)

### Mixing and matching audio plugins

The flutter plugin ecosystem contains a wide variety of useful audio plugins. In order to allow these to work together in a single app, just_audio "just" plays audio. By focusing on a single responsibility, different audio plugins can safely work together without overlapping responsibilities causing runtime conflicts.

Other common audio capabilities are optionally provided by separate plugins:

* [audio_service](https://pub.dev/packages/audio_service): Use this to allow your app to play audio in the background and respond to controls on the lockscreen, media notification, headset, AndroidAuto/CarPlay or smart watch.
* [just_audio_background](https://pub.dev/packages/just_audio_background): Use this to allow your app to play audio in the background and respond to controls on the lockscreen, media notification, headset, AndroidAuto/CarPlay or smart watch.
* [audio_service](https://pub.dev/packages/audio_service): Use this if your app has more advanced background audio requirements than can be supported by `just_audio_background`.
* [audio_session](https://pub.dev/packages/audio_session): Use this to configure and manage how your app interacts with other audio apps (e.g. phone call or navigator interruptions).

## Vote on upcoming features
Expand Down Expand Up @@ -64,6 +65,7 @@ This project is supported by the amazing open source community of GitHub contrib
| Simultaneous downloading+caching |||| |
| Waveform visualizer (See [#97](https://github.com/ryanheise/just_audio/issues/97)) ||| | |
| FFT visualizer (See [#97](https://github.com/ryanheise/just_audio/issues/97)) || | | |
| Background |||||

Please consider reporting any bugs you encounter [here](https://github.com/ryanheise/just_audio/issues) or submitting pull requests [here](https://github.com/ryanheise/just_audio/pulls).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener, Aud

private final Context context;
private final MethodChannel methodChannel;
private final EventChannel eventChannel;
private EventSink eventSink;
private final BetterEventChannel eventChannel;
private final BetterEventChannel dataEventChannel;

private ProcessingState processingState;
private long updatePosition;
Expand Down Expand Up @@ -132,18 +132,8 @@ public AudioPlayer(final Context applicationContext, final BinaryMessenger messe
this.rawAudioEffects = rawAudioEffects;
methodChannel = new MethodChannel(messenger, "com.ryanheise.just_audio.methods." + id);
methodChannel.setMethodCallHandler(this);
eventChannel = new EventChannel(messenger, "com.ryanheise.just_audio.events." + id);
eventChannel.setStreamHandler(new EventChannel.StreamHandler() {
@Override
public void onListen(final Object arguments, final EventSink eventSink) {
AudioPlayer.this.eventSink = eventSink;
}

@Override
public void onCancel(final Object arguments) {
eventSink = null;
}
});
eventChannel = new BetterEventChannel(messenger, "com.ryanheise.just_audio.events." + id);
dataEventChannel = new BetterEventChannel(messenger, "com.ryanheise.just_audio.data." + id);
processingState = ProcessingState.none;
if (audioLoadConfiguration != null) {
Map<?, ?> loadControlMap = (Map<?, ?>)audioLoadConfiguration.get("androidLoadControl");
Expand Down Expand Up @@ -759,9 +749,7 @@ private void broadcastPlaybackEvent() {
event.put("currentIndex", currentIndex);
event.put("androidAudioSessionId", audioSessionId);

if (eventSink != null) {
eventSink.success(event);
}
eventChannel.success(event);
}

private Map<String, Object> collectIcyMetadata() {
Expand Down Expand Up @@ -809,9 +797,7 @@ private void sendError(String errorCode, String errorMsg) {
prepareResult = null;
}

if (eventSink != null) {
eventSink.error(errorCode, errorMsg, null);
}
eventChannel.error(errorCode, errorMsg, null);
}

private void transition(final ProcessingState newState) {
Expand Down Expand Up @@ -897,8 +883,14 @@ public void seek(final long position, final Integer index, final Result result)
abortSeek();
seekPos = position;
seekResult = result;
int windowIndex = index != null ? index : player.getCurrentWindowIndex();
player.seekTo(windowIndex, position);
try {
int windowIndex = index != null ? index : player.getCurrentWindowIndex();
player.seekTo(windowIndex, position);
} catch (RuntimeException e) {
seekResult = null;
seekPos = null;
throw e;
}
}

public void dispose() {
Expand All @@ -917,19 +909,17 @@ public void dispose() {
player = null;
transition(ProcessingState.none);
}
/*
if (loudness != null) {
loudness.release();
}
*/
if (eventSink != null) {
eventSink.endOfStream();
}
eventChannel.endOfStream();
dataEventChannel.endOfStream();
}

private void abortSeek() {
if (seekResult != null) {
seekResult.success(new HashMap<String, Object>());
try {
seekResult.success(new HashMap<String, Object>());
} catch (RuntimeException e) {
// Result already sent
}
seekResult = null;
seekPos = null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.ryanheise.just_audio;

import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.EventChannel.EventSink;

public class BetterEventChannel implements EventSink {
private EventSink eventSink;

public BetterEventChannel(final BinaryMessenger messenger, final String id) {
EventChannel eventChannel = new EventChannel(messenger, id);
eventChannel.setStreamHandler(new EventChannel.StreamHandler() {
@Override
public void onListen(final Object arguments, final EventSink eventSink) {
BetterEventChannel.this.eventSink = eventSink;
}

@Override
public void onCancel(final Object arguments) {
eventSink = null;
}
});
}

@Override
public void success(Object event) {
if (eventSink != null) eventSink.success(event);
}

@Override
public void error(String errorCode, String errorMessage, Object errorDetails) {
if (eventSink != null) eventSink.error(errorCode, errorMessage, errorDetails);
}

@Override
public void endOfStream() {
if (eventSink != null) eventSink.endOfStream();
}
}
40 changes: 15 additions & 25 deletions just_audio/darwin/Classes/AudioPlayer.m
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#import "BetterEventChannel.h"
#import "AudioPlayer.h"
#import "AudioSource.h"
#import "IndexedAudioSource.h"
Expand All @@ -15,8 +16,8 @@
@implementation AudioPlayer {
NSObject<FlutterPluginRegistrar>* _registrar;
FlutterMethodChannel *_methodChannel;
FlutterEventChannel *_eventChannel;
FlutterEventSink _eventSink;
BetterEventChannel *_eventChannel;
BetterEventChannel *_dataEventChannel;
NSString *_playerId;
AVQueuePlayer *_player;
AudioSource *_audioSource;
Expand Down Expand Up @@ -54,10 +55,12 @@ - (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar
_methodChannel =
[FlutterMethodChannel methodChannelWithName:[NSMutableString stringWithFormat:@"com.ryanheise.just_audio.methods.%@", _playerId]
binaryMessenger:[registrar messenger]];
_eventChannel =
[FlutterEventChannel eventChannelWithName:[NSMutableString stringWithFormat:@"com.ryanheise.just_audio.events.%@", _playerId]
binaryMessenger:[registrar messenger]];
[_eventChannel setStreamHandler:self];
_eventChannel = [[BetterEventChannel alloc]
initWithName:[NSMutableString stringWithFormat:@"com.ryanheise.just_audio.events.%@", _playerId]
messenger:[registrar messenger]];
_dataEventChannel = [[BetterEventChannel alloc]
initWithName:[NSMutableString stringWithFormat:@"com.ryanheise.just_audio.data.%@", _playerId]
messenger:[registrar messenger]];
_index = 0;
_processingState = none;
_loopMode = loopOff;
Expand Down Expand Up @@ -277,18 +280,7 @@ - (void)concatenatingMove:(NSString *)catId currentIndex:(int)currentIndex newIn
[self broadcastPlaybackEvent];
}

- (FlutterError*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventSink {
_eventSink = eventSink;
return nil;
}

- (FlutterError*)onCancelWithArguments:(id)arguments {
_eventSink = nil;
return nil;
}

- (void)checkForDiscontinuity {
if (!_eventSink) return;
if (!_playing || CMTIME_IS_VALID(_seekPos) || _processingState == completed) return;
int position = [self getCurrentPosition];
if (_processingState == buffering) {
Expand Down Expand Up @@ -327,16 +319,15 @@ - (void)leaveBuffering:(NSString *)reason {
}

- (void)broadcastPlaybackEvent {
if (!_eventSink) return;
_eventSink(@{
[_eventChannel sendEvent:@{
@"processingState": @(_processingState),
@"updatePosition": @((long long)1000 * _updatePosition),
@"updateTime": @(_updateTime),
@"bufferedPosition": @((long long)1000 * [self getBufferedPosition]),
@"icyMetadata": _icyMetadata,
@"duration": @([self getDurationMicroseconds]),
@"currentIndex": @(_index),
});
}];
}

- (int)getCurrentPosition {
Expand Down Expand Up @@ -987,10 +978,8 @@ - (void)sendError:(FlutterError *)flutterError playerItem:(IndexedPlayerItem *)p
_loadResult(flutterError);
_loadResult = nil;
}
if (_eventSink) {
// Broadcast all errors even if they aren't on the current item.
_eventSink(flutterError);
}
// Broadcast all errors even if they aren't on the current item.
[_eventChannel sendEvent:flutterError];
}

- (void)abortExistingConnection {
Expand Down Expand Up @@ -1336,7 +1325,8 @@ - (void)dispose {
_player = nil;
}
// Untested:
[_eventChannel setStreamHandler:nil];
[_eventChannel dispose];
[_dataEventChannel dispose];
[_methodChannel setMethodCallHandler:nil];
}

Expand Down
37 changes: 37 additions & 0 deletions just_audio/darwin/Classes/BetterEventChannel.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#import "BetterEventChannel.h"

@implementation BetterEventChannel {
FlutterEventChannel *_eventChannel;
FlutterEventSink _eventSink;
}

- (instancetype)initWithName:(NSString*)name messenger:(NSObject<FlutterBinaryMessenger> *)messenger {
self = [super init];
NSAssert(self, @"super init cannot be nil");
_eventChannel =
[FlutterEventChannel eventChannelWithName:name binaryMessenger:messenger];
[_eventChannel setStreamHandler:self];
_eventSink = nil;
return self;
}

- (FlutterError*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventSink {
_eventSink = eventSink;
return nil;
}

- (FlutterError*)onCancelWithArguments:(id)arguments {
_eventSink = nil;
return nil;
}

- (void)sendEvent:(id)event {
if (!_eventSink) return;
_eventSink(event);
}

- (void)dispose {
[_eventChannel setStreamHandler:nil];
}

@end
3 changes: 3 additions & 0 deletions just_audio/example/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ryanheise.just_audio_example">

<uses-permission android:name="android.permission.INTERNET"/>

<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
Expand All @@ -10,6 +12,7 @@
android:usesCleartextTraffic="true"
android:label="just_audio_example"
android:icon="@mipmap/ic_launcher">

<activity
android:name=".MainActivity"
android:launchMode="singleTop"
Expand Down
Loading

0 comments on commit a3875e5

Please sign in to comment.