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

feat(web): add setBalance (#58) #1282

Merged
merged 7 commits into from
Oct 21, 2022
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
2 changes: 1 addition & 1 deletion feature_parity_table.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Note: LLM means Low Latency Mode.
<tr><td>stay awake</td><td>yes (except LLM)</td><td>yes</td><td>no</td><td>no</td><td>no</td><td>no</td></tr>
<tr><td>recording active</td><td>not yet</td><td>yes</td><td>no</td><td>no</td><td>no</td><td>no</td></tr>
<tr><td>playing route</td><td>yes (except LLM)</td><td>yes</td><td>no</td><td>no</td><td>no</td><td>no</td></tr>
<tr><td>balance</td><td>no</td><td>no</td><td>no</td><td>no</td><td>yes</td><td>yes</td></tr>
<tr><td>balance</td><td>not yet</td><td>not yet</td><td>not yet</td><td>yes</td><td>yes</td><td>yes</td></tr>
<tr><td colspan="7"><strong>Streams</strong></td></tr>
<tr><td>duration event</td><td>yes</td><td>yes</td><td>yes</td><td>yes</td><td>yes</td><td>yes</td></tr>
<tr><td>position event</td><td>yes</td><td>yes</td><td>yes</td><td>yes</td><td>yes</td><td>yes</td></tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ class PlatformFeatures {
hasRecordingActive: false,
hasPlayingRoute: false,
hasErrorEvent: false,
hasBalance: false,
);

static const androidPlatformFeatures = PlatformFeatures(
Expand Down
55 changes: 55 additions & 0 deletions packages/audioplayers_web/lib/web_audio_js.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import 'dart:html';

import 'package:js/js.dart';

@JS('AudioContext')
@staticInterop
class JsAudioContext {
external JsAudioContext();
}

extension JsAudioContextExtension on JsAudioContext {
external MediaElementAudioSourceNode createMediaElementSource(
AudioElement element,
);

external StereoPannerNode createStereoPanner();

external AudioNode get destination;
}

@JS()
@staticInterop
abstract class AudioNode {
external AudioNode();
}

extension AudioNodeExtension on AudioNode {
external AudioNode connect(AudioNode audioNode);
}

@JS()
@staticInterop
class AudioParam {
external AudioParam();
}

extension AudioParamExtension on AudioParam {
external num value;
}

@JS()
@staticInterop
class StereoPannerNode implements AudioNode {
external StereoPannerNode();
}

extension StereoPannerNodeExtension on StereoPannerNode {
external AudioParam get pan;
}

@JS()
@staticInterop
class MediaElementAudioSourceNode implements AudioNode {
external MediaElementAudioSourceNode();
}
17 changes: 16 additions & 1 deletion packages/audioplayers_web/lib/wrapped_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'dart:html';
import 'package:audioplayers_platform_interface/api/release_mode.dart';
import 'package:audioplayers_platform_interface/streams_interface.dart';
import 'package:audioplayers_web/num_extension.dart';
import 'package:audioplayers_web/web_audio_js.dart';

class WrappedPlayer {
final String playerId;
Expand All @@ -17,6 +18,7 @@ class WrappedPlayer {
bool isPlaying = false;

AudioElement? player;
StereoPannerNode? stereoPanner;
StreamSubscription? playerTimeUpdateSubscription;
StreamSubscription? playerEndedSubscription;
StreamSubscription? playerLoadedDataSubscription;
Expand Down Expand Up @@ -44,7 +46,7 @@ class WrappedPlayer {
}

void setBalance(double balance) {
throw UnimplementedError('setBalance is not currently implemented on Web');
stereoPanner?.pan.value = balance;
}

void setPlaybackRate(double rate) {
Expand All @@ -58,9 +60,21 @@ class WrappedPlayer {
}

final p = player = AudioElement(currentUrl);
// As the AudioElement is created dynamically via script,
// features like 'stereo panning' need the CORS header to be enabled.
// See: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
p.crossOrigin = 'anonymous';
p.loop = shouldLoop();
p.volume = currentVolume;
p.playbackRate = currentPlaybackRate;

// setup stereo panning
final audioContext = JsAudioContext();
final source = audioContext.createMediaElementSource(player!);
stereoPanner = audioContext.createStereoPanner();
source.connect(stereoPanner!);
stereoPanner?.connect(audioContext.destination);

playerPlaySubscription = p.onPlay.listen((_) {
streamsInterface.emitDuration(
playerId,
Expand Down Expand Up @@ -99,6 +113,7 @@ class WrappedPlayer {
void release() {
_cancel();
player = null;
stereoPanner = null;

playerLoadedDataSubscription?.cancel();
playerLoadedDataSubscription = null;
Expand Down
1 change: 1 addition & 0 deletions packages/audioplayers_web/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ dependencies:
sdk: flutter
flutter_web_plugins:
sdk: flutter
js: ^0.6.4

dev_dependencies:
dartdoc: ^5.0.1
Expand Down