Add disposePlayer to platform interface. Retain player.position after dispose.
This commit is contained in:
parent
35a6e4810b
commit
ad9e4518cf
|
@ -37,17 +37,15 @@
|
||||||
FlutterResult _playResult;
|
FlutterResult _playResult;
|
||||||
id _timeObserver;
|
id _timeObserver;
|
||||||
BOOL _automaticallyWaitsToMinimizeStalling;
|
BOOL _automaticallyWaitsToMinimizeStalling;
|
||||||
BOOL _configuredSession;
|
|
||||||
BOOL _playing;
|
BOOL _playing;
|
||||||
float _speed;
|
float _speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar playerId:(NSString*)idParam configuredSession:(BOOL)configuredSession {
|
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar playerId:(NSString*)idParam {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
NSAssert(self, @"super init cannot be nil");
|
NSAssert(self, @"super init cannot be nil");
|
||||||
_registrar = registrar;
|
_registrar = registrar;
|
||||||
_playerId = idParam;
|
_playerId = idParam;
|
||||||
_configuredSession = configuredSession;
|
|
||||||
_methodChannel =
|
_methodChannel =
|
||||||
[FlutterMethodChannel methodChannelWithName:[NSMutableString stringWithFormat:@"com.ryanheise.just_audio.methods.%@", _playerId]
|
[FlutterMethodChannel methodChannelWithName:[NSMutableString stringWithFormat:@"com.ryanheise.just_audio.methods.%@", _playerId]
|
||||||
binaryMessenger:[registrar messenger]];
|
binaryMessenger:[registrar messenger]];
|
||||||
|
@ -113,9 +111,6 @@
|
||||||
[self seek:position index:request[@"index"] completionHandler:^(BOOL finished) {
|
[self seek:position index:request[@"index"] completionHandler:^(BOOL finished) {
|
||||||
result(@{});
|
result(@{});
|
||||||
}];
|
}];
|
||||||
} else if ([@"dispose" isEqualToString:call.method]) {
|
|
||||||
[self dispose];
|
|
||||||
result(@{});
|
|
||||||
} else if ([@"concatenatingInsertAll" isEqualToString:call.method]) {
|
} else if ([@"concatenatingInsertAll" isEqualToString:call.method]) {
|
||||||
[self concatenatingInsertAll:(NSString *)request[@"id"] index:[request[@"index"] intValue] sources:(NSArray *)request[@"children"]];
|
[self concatenatingInsertAll:(NSString *)request[@"id"] index:[request[@"index"] intValue] sources:(NSArray *)request[@"children"]];
|
||||||
result(@{});
|
result(@{});
|
||||||
|
@ -908,11 +903,6 @@
|
||||||
_playResult = result;
|
_playResult = result;
|
||||||
}
|
}
|
||||||
_playing = YES;
|
_playing = YES;
|
||||||
#if TARGET_OS_IPHONE
|
|
||||||
if (_configuredSession) {
|
|
||||||
[[AVAudioSession sharedInstance] setActive:YES error:nil];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
_player.rate = _speed;
|
_player.rate = _speed;
|
||||||
[self updatePosition];
|
[self updatePosition];
|
||||||
if (@available(macOS 10.12, iOS 10.0, *)) {}
|
if (@available(macOS 10.12, iOS 10.0, *)) {}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
@implementation JustAudioPlugin {
|
@implementation JustAudioPlugin {
|
||||||
NSObject<FlutterPluginRegistrar>* _registrar;
|
NSObject<FlutterPluginRegistrar>* _registrar;
|
||||||
BOOL _configuredSession;
|
NSMutableDictionary<NSString *, AudioPlayer *> *_players;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
||||||
|
@ -20,6 +20,7 @@
|
||||||
self = [super init];
|
self = [super init];
|
||||||
NSAssert(self, @"super init cannot be nil");
|
NSAssert(self, @"super init cannot be nil");
|
||||||
_registrar = registrar;
|
_registrar = registrar;
|
||||||
|
_players = [[NSMutableDictionary alloc] init];
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,11 +28,25 @@
|
||||||
if ([@"init" isEqualToString:call.method]) {
|
if ([@"init" isEqualToString:call.method]) {
|
||||||
NSDictionary *request = (NSDictionary *)call.arguments;
|
NSDictionary *request = (NSDictionary *)call.arguments;
|
||||||
NSString *playerId = request[@"id"];
|
NSString *playerId = request[@"id"];
|
||||||
/*AudioPlayer* player =*/ [[AudioPlayer alloc] initWithRegistrar:_registrar playerId:playerId configuredSession:_configuredSession];
|
AudioPlayer* player = [[AudioPlayer alloc] initWithRegistrar:_registrar playerId:playerId];
|
||||||
|
[_players setValue:player forKey:playerId];
|
||||||
result(nil);
|
result(nil);
|
||||||
|
} else if ([@"disposePlayer" isEqualToString:call.method]) {
|
||||||
|
NSDictionary *request = (NSDictionary *)call.arguments;
|
||||||
|
NSString *playerId = request[@"id"];
|
||||||
|
[_players[playerId] dispose];
|
||||||
|
[_players setValue:nil forKey:playerId];
|
||||||
|
result(@{});
|
||||||
} else {
|
} else {
|
||||||
result(FlutterMethodNotImplemented);
|
result(FlutterMethodNotImplemented);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
for (NSString *playerId in _players) {
|
||||||
|
[_players[playerId] dispose];
|
||||||
|
}
|
||||||
|
[_players removeAllObjects];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -10,75 +10,29 @@ project 'Runner', {
|
||||||
'Release' => :release,
|
'Release' => :release,
|
||||||
}
|
}
|
||||||
|
|
||||||
def parse_KV_file(file, separator='=')
|
def flutter_root
|
||||||
file_abs_path = File.expand_path(file)
|
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
|
||||||
if !File.exists? file_abs_path
|
unless File.exist?(generated_xcode_build_settings_path)
|
||||||
return [];
|
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||||
end
|
end
|
||||||
generated_key_values = {}
|
|
||||||
skip_line_start_symbols = ["#", "/"]
|
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||||
File.foreach(file_abs_path) do |line|
|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||||
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
|
return matches[1].strip if matches
|
||||||
plugin = line.split(pattern=separator)
|
|
||||||
if plugin.length == 2
|
|
||||||
podname = plugin[0].strip()
|
|
||||||
path = plugin[1].strip()
|
|
||||||
podpath = File.expand_path("#{path}", file_abs_path)
|
|
||||||
generated_key_values[podname] = podpath
|
|
||||||
else
|
|
||||||
puts "Invalid plugin specification: #{line}"
|
|
||||||
end
|
end
|
||||||
|
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
|
||||||
end
|
end
|
||||||
generated_key_values
|
|
||||||
end
|
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||||
|
|
||||||
|
flutter_ios_podfile_setup
|
||||||
|
|
||||||
target 'Runner' do
|
target 'Runner' do
|
||||||
# Flutter Pod
|
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||||
|
|
||||||
copied_flutter_dir = File.join(__dir__, 'Flutter')
|
|
||||||
copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
|
|
||||||
copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
|
|
||||||
unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
|
|
||||||
# Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
|
|
||||||
# That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
|
|
||||||
# CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
|
|
||||||
|
|
||||||
generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
|
|
||||||
unless File.exist?(generated_xcode_build_settings_path)
|
|
||||||
raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
|
||||||
end
|
|
||||||
generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
|
|
||||||
cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
|
|
||||||
|
|
||||||
unless File.exist?(copied_framework_path)
|
|
||||||
FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
|
|
||||||
end
|
|
||||||
unless File.exist?(copied_podspec_path)
|
|
||||||
FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Keep pod path relative so it can be checked into Podfile.lock.
|
|
||||||
pod 'Flutter', :path => 'Flutter'
|
|
||||||
|
|
||||||
# Plugin Pods
|
|
||||||
|
|
||||||
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
|
|
||||||
# referring to absolute paths on developers' machines.
|
|
||||||
system('rm -rf .symlinks')
|
|
||||||
system('mkdir -p .symlinks/plugins')
|
|
||||||
plugin_pods = parse_KV_file('../.flutter-plugins')
|
|
||||||
plugin_pods.each do |name, path|
|
|
||||||
symlink = File.join('.symlinks', 'plugins', name)
|
|
||||||
File.symlink(path, symlink)
|
|
||||||
pod name, :path => File.join(symlink, 'ios')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
installer.pods_project.targets.each do |target|
|
installer.pods_project.targets.each do |target|
|
||||||
target.build_configurations.each do |config|
|
flutter_additional_ios_build_settings(target)
|
||||||
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,18 +6,12 @@ PODS:
|
||||||
- Flutter
|
- Flutter
|
||||||
- path_provider (0.0.1):
|
- path_provider (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- path_provider_linux (0.0.1):
|
|
||||||
- Flutter
|
|
||||||
- path_provider_macos (0.0.1):
|
|
||||||
- Flutter
|
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- audio_session (from `.symlinks/plugins/audio_session/ios`)
|
- audio_session (from `.symlinks/plugins/audio_session/ios`)
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- just_audio (from `.symlinks/plugins/just_audio/ios`)
|
- just_audio (from `.symlinks/plugins/just_audio/ios`)
|
||||||
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
||||||
- path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`)
|
|
||||||
- path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`)
|
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
audio_session:
|
audio_session:
|
||||||
|
@ -28,19 +22,13 @@ EXTERNAL SOURCES:
|
||||||
:path: ".symlinks/plugins/just_audio/ios"
|
:path: ".symlinks/plugins/just_audio/ios"
|
||||||
path_provider:
|
path_provider:
|
||||||
:path: ".symlinks/plugins/path_provider/ios"
|
:path: ".symlinks/plugins/path_provider/ios"
|
||||||
path_provider_linux:
|
|
||||||
:path: ".symlinks/plugins/path_provider_linux/ios"
|
|
||||||
path_provider_macos:
|
|
||||||
:path: ".symlinks/plugins/path_provider_macos/ios"
|
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
audio_session: 4f3e461722055d21515cf3261b64c973c062f345
|
audio_session: 4f3e461722055d21515cf3261b64c973c062f345
|
||||||
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
|
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
|
||||||
just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa
|
just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa
|
||||||
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
||||||
path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4
|
|
||||||
path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0
|
|
||||||
|
|
||||||
PODFILE CHECKSUM: f32fb4e7c14f8b3ca19a369d7be425dd9241af27
|
PODFILE CHECKSUM: 8e679eca47255a8ca8067c4c67aab20e64cb974d
|
||||||
|
|
||||||
COCOAPODS: 1.9.3
|
COCOAPODS: 1.9.3
|
||||||
|
|
|
@ -5,12 +5,12 @@
|
||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
import path_provider_macos
|
|
||||||
import audio_session
|
import audio_session
|
||||||
import just_audio
|
import just_audio
|
||||||
|
import path_provider_macos
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
|
||||||
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
|
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
|
||||||
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
|
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
|
||||||
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
@interface AudioPlayer : NSObject<FlutterStreamHandler>
|
@interface AudioPlayer : NSObject<FlutterStreamHandler>
|
||||||
|
|
||||||
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar playerId:(NSString*)idParam configuredSession:(BOOL)configuredSession;
|
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar playerId:(NSString*)idParam;
|
||||||
|
- (void)dispose;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -324,7 +324,6 @@ class AudioPlayer {
|
||||||
|
|
||||||
/// The current position of the player.
|
/// The current position of the player.
|
||||||
Duration get position {
|
Duration get position {
|
||||||
if (_disposed) return null;
|
|
||||||
if (playing && processingState == ProcessingState.ready) {
|
if (playing && processingState == ProcessingState.ready) {
|
||||||
final result = _playbackEvent.updatePosition +
|
final result = _playbackEvent.updatePosition +
|
||||||
(DateTime.now().difference(_playbackEvent.updateTime)) * speed;
|
(DateTime.now().difference(_playbackEvent.updateTime)) * speed;
|
||||||
|
@ -682,7 +681,13 @@ class AudioPlayer {
|
||||||
Future<void> dispose() async {
|
Future<void> dispose() async {
|
||||||
if (_disposed) return;
|
if (_disposed) return;
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
|
try {
|
||||||
|
await JustAudioPlatform.instance
|
||||||
|
.disposePlayer(DisposePlayerRequest(id: _id));
|
||||||
|
} catch (e) {
|
||||||
|
print("disposePlayer() not implemented. Falling back to dispose()");
|
||||||
await (await _platform).dispose(DisposeRequest());
|
await (await _platform).dispose(DisposeRequest());
|
||||||
|
}
|
||||||
_audioSource = null;
|
_audioSource = null;
|
||||||
_audioSources.values.forEach((s) => s._dispose());
|
_audioSources.values.forEach((s) => s._dispose());
|
||||||
_audioSources.clear();
|
_audioSources.clear();
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
@interface AudioPlayer : NSObject<FlutterStreamHandler>
|
@interface AudioPlayer : NSObject<FlutterStreamHandler>
|
||||||
|
|
||||||
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar playerId:(NSString*)idParam configuredSession:(BOOL)configuredSession;
|
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar playerId:(NSString*)idParam;
|
||||||
|
- (void)dispose;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,9 @@ environment:
|
||||||
flutter: ">=1.12.13+hotfix.5"
|
flutter: ">=1.12.13+hotfix.5"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
just_audio_platform_interface: ^1.0.0
|
# just_audio_platform_interface: ^1.0.0
|
||||||
|
just_audio_platform_interface:
|
||||||
|
path: ../just_audio_platform_interface
|
||||||
audio_session: ^0.0.7
|
audio_session: ^0.0.7
|
||||||
rxdart: ^0.24.1
|
rxdart: ^0.24.1
|
||||||
path: ^1.6.4
|
path: ^1.6.4
|
||||||
|
|
|
@ -41,6 +41,11 @@ abstract class JustAudioPlatform extends PlatformInterface {
|
||||||
Future<AudioPlayerPlatform> init(InitRequest request) {
|
Future<AudioPlayerPlatform> init(InitRequest request) {
|
||||||
throw UnimplementedError('init() has not been implemented.');
|
throw UnimplementedError('init() has not been implemented.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Disposes of a platform player.
|
||||||
|
Future<DisposePlayerResponse> disposePlayer(DisposePlayerRequest request) {
|
||||||
|
throw UnimplementedError('disposePlayer() has not been implemented.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A nested platform interface for communicating with a particular player
|
/// A nested platform interface for communicating with a particular player
|
||||||
|
@ -53,6 +58,10 @@ abstract class JustAudioPlatform extends PlatformInterface {
|
||||||
/// `implements` this interface will be broken by newly added
|
/// `implements` this interface will be broken by newly added
|
||||||
/// [AudioPlayerPlatform] methods.
|
/// [AudioPlayerPlatform] methods.
|
||||||
abstract class AudioPlayerPlatform {
|
abstract class AudioPlayerPlatform {
|
||||||
|
final String id;
|
||||||
|
|
||||||
|
AudioPlayerPlatform(this.id);
|
||||||
|
|
||||||
Stream<PlaybackEventMessage> get playbackEventMessageStream {
|
Stream<PlaybackEventMessage> get playbackEventMessageStream {
|
||||||
throw UnimplementedError(
|
throw UnimplementedError(
|
||||||
'playbackEventMessageStream has not been implemented.');
|
'playbackEventMessageStream has not been implemented.');
|
||||||
|
@ -103,6 +112,9 @@ abstract class AudioPlayerPlatform {
|
||||||
"setAndroidAudioAttributes() has not been implemented.");
|
"setAndroidAudioAttributes() has not been implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This method has been superceded by [JustAudioPlatform.disposePlayer].
|
||||||
|
/// For backward compatibility, this method will still be called as a
|
||||||
|
/// fallback if [JustAudioPlatform.disposePlayer] is not implemented.
|
||||||
Future<DisposeResponse> dispose(DisposeRequest request) {
|
Future<DisposeResponse> dispose(DisposeRequest request) {
|
||||||
throw UnimplementedError("dispose() has not been implemented.");
|
throw UnimplementedError("dispose() has not been implemented.");
|
||||||
}
|
}
|
||||||
|
@ -244,6 +256,21 @@ class InitRequest {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DisposePlayerRequest {
|
||||||
|
final String id;
|
||||||
|
|
||||||
|
DisposePlayerRequest({@required this.id});
|
||||||
|
|
||||||
|
Map<dynamic, dynamic> toMap() => {
|
||||||
|
'id': id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class DisposePlayerResponse {
|
||||||
|
static DisposePlayerResponse fromMap(Map<dynamic, dynamic> map) =>
|
||||||
|
DisposePlayerResponse();
|
||||||
|
}
|
||||||
|
|
||||||
class LoadRequest {
|
class LoadRequest {
|
||||||
final AudioSourceMessage audioSourceMessage;
|
final AudioSourceMessage audioSourceMessage;
|
||||||
|
|
||||||
|
|
|
@ -13,15 +13,22 @@ class MethodChannelJustAudio extends JustAudioPlatform {
|
||||||
await _mainChannel.invokeMethod('init', request.toMap());
|
await _mainChannel.invokeMethod('init', request.toMap());
|
||||||
return MethodChannelAudioPlayer(request.id);
|
return MethodChannelAudioPlayer(request.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<DisposePlayerResponse> disposePlayer(
|
||||||
|
DisposePlayerRequest request) async {
|
||||||
|
return DisposePlayerResponse.fromMap(
|
||||||
|
await _mainChannel.invokeMethod('disposePlayer', request.toMap()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An implementation of [AudioPlayerPlatform] that uses method channels.
|
/// An implementation of [AudioPlayerPlatform] that uses method channels.
|
||||||
class MethodChannelAudioPlayer extends AudioPlayerPlatform {
|
class MethodChannelAudioPlayer extends AudioPlayerPlatform {
|
||||||
final String id;
|
|
||||||
final MethodChannel _channel;
|
final MethodChannel _channel;
|
||||||
|
|
||||||
MethodChannelAudioPlayer(this.id)
|
MethodChannelAudioPlayer(String id)
|
||||||
: _channel = MethodChannel('com.ryanheise.just_audio.methods.$id');
|
: _channel = MethodChannel('com.ryanheise.just_audio.methods.$id'),
|
||||||
|
super(id);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<PlaybackEventMessage> get playbackEventMessageStream =>
|
Stream<PlaybackEventMessage> get playbackEventMessageStream =>
|
||||||
|
|
Loading…
Reference in New Issue