Git Product home page Git Product logo

audio_service's People

Contributors

addie9000 avatar aleexbt avatar alexandergottlieb avatar aurimas-fertilemind avatar chengyuhui avatar defsub avatar dgempler avatar hacker1024 avatar itog avatar julianscheel avatar keaganhilliard avatar mohamedabdallah-14 avatar nt4f04und avatar raywalz avatar rohansohonee avatar ruchit-7span avatar ruchit2759 avatar ryanheise avatar sametsahin10 avatar sauceee avatar siqwin avatar snaeji avatar snipd-mikel avatar speaking-in-code avatar stevenosse avatar stonega avatar subhash279 avatar suragch avatar theskyblockman avatar yringler avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

audio_service's Issues

Rating support

Currently, there's no support at all for setting or retrieving ratings. I'm going to start working on this now, and I'll send a pull request when I'm done.

Fatal Exception

hi, i was trying to add your plugin to a new project in order to run the example, and i have this error:
(i modified the manifest and adding the MainApplication file)

D/AndroidRuntime( 5855): Shutting down VM
E/AndroidRuntime( 5855): FATAL EXCEPTION: main
E/AndroidRuntime( 5855): Process: com.ryanheise.audioserviceexample, PID: 5855
E/AndroidRuntime( 5855): java.lang.NullPointerException: Attempt to invoke interface method 'void io.flutter.plugin.common.PluginRegistry$PluginRegistrantCallback.registerWith(io.flutter.plugin.common.PluginRegistry)' on a null object reference
E/AndroidRuntime( 5855): at com.ryanheise.audioservice.AudioServicePlugin$ClientHandler$3.onPlay(AudioServicePlugin.java:218)
E/AndroidRuntime( 5855): at com.ryanheise.audioservice.AudioService$MediaSessionCallback$1.run(AudioService.java:396)
E/AndroidRuntime( 5855): at com.ryanheise.audioservice.AudioService$MediaSessionCallback.play(AudioService.java:411)
E/AndroidRuntime( 5855): at com.ryanheise.audioservice.AudioService$MediaSessionCallback.onPlay(AudioService.java:394)
E/AndroidRuntime( 5855): at android.support.v4.media.session.MediaSessionCompat$Callback$StubApi21.onPlay(MediaSessionCompat.java:1259)
E/AndroidRuntime( 5855): at android.support.v4.media.session.MediaSessionCompatApi21$CallbackProxy.onPlay(MediaSessionCompatApi21.java:194)
E/AndroidRuntime( 5855): at android.media.session.MediaSession$CallbackMessageHandler.handleMessage(MediaSession.java:1407)
E/AndroidRuntime( 5855): at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime( 5855): at android.os.Looper.loop(Looper.java:164)
E/AndroidRuntime( 5855): at android.app.ActivityThread.main(ActivityThread.java:6494)
E/AndroidRuntime( 5855): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 5855): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
E/AndroidRuntime( 5855): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

i cannot run the example,i can run it only openning the plugin project itself (but obviously that is not the way), what am i doing wrong?

Hot restart MissingPluginException

Describe the bug
After hot restart plugin stops working:

E/flutter (22566): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: MissingPluginException(No implementation found for method connect on channel ryanheise.com/audioService)
E/flutter (22566): #0      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:300:7)
E/flutter (22566): <asynchronous suspension>
E/flutter (22566): #1      AudioService.connect (package:audio_service/audio_service.dart:398:20)
E/flutter (22566): <asynchronous suspension>
E/flutter (22566): #2      _MyAppState.connect (package:audio_service_example/main.dart:64:24)
E/flutter (22566): <asynchronous suspension>
E/flutter (22566): #3      _MyAppState.initState (package:audio_service_example/main.dart:39:5)
E/flutter (22566): #4      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3846:58)
E/flutter (22566): #5      ComponentElement.mount (package:flutter/src/widgets/framework.dart:3711:5)
E/flutter (22566): #6      Element.inflateWidget (package:flutter/src/widgets/framework.dart:2956:14)
E/flutter (22566): #7      Element.updateChild (package:flutter/src/widgets/framework.dart:2759:12)
E/flutter (22566): #8      RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:933:16)
E/flutter (22566): #9      RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:904:5)
E/flutter (22566): #10     RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> (package:flutter/src/widgets/binding.dart:850:17)
E/flutter (22566): #11     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2253:19)
E/flutter (22566): #12     RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:849:13)
E/flutter (22566): #13     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart
:736:7)
E/flutter (22566): #14     runApp (package:flutter/src/widgets/binding.dart:780:7)
E/flutter (22566): #15     main (package:audio_service_example/main.dart:24:16)
E/flutter (22566): #16     _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:189:25)
E/flutter (22566): #17     _rootRun (dart:async/zone.dart:1124:13)
E/flutter (22566): #18     _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter (22566): #19     _runZoned (dart:async/zone.dart:1516:10)
E/flutter (22566): #20     runZoned (dart:async/zone.dart:1500:12)
E/flutter (22566): #21     _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:180:5)
E/flutter (22566): #22     _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:300:19)

To Reproduce
Steps to reproduce the behavior:

  1. flutter run on example in repo
  2. Start playing
  3. trigger hot restart (not reload)
  4. look in console

Expected behavior
Plugin keep working

Runtime Environment (please complete the following information):

  • Device: Samsung Galaxy 7, Pixel 2 Emulator

Flutter SDK version

[√] Flutter (Channel stable, v1.2.1, on Microsoft Windows [Version 10.0.17134.706], locale ru-RU)
[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[√] Android Studio (version 3.4)

Image loading blocks the main thread

Describe the bug
The main thread is blocked when the plugin loads a new image for the notification.

To Reproduce
This can be observed easily if you turn off wifi/mobile data and add a new MediaItem. The network request takes a while to time out, and the app is unresponsive while it does.

Expected behavior
The image loading should be entirely asynchronous.

Runtime Environment (please complete the following information):

  • Device: Xiaomi POCOPHONE F1
  • Android version: 9.0 (Pixel Experience CAF ROM)

Toggling bluetooth makes the app crash

Stacktrace:

java.lang.IllegalStateException: onLoadChildren must call detach() or sendResult() before returning for package=com.android.bluetooth id=root
        at android.service.media.MediaBrowserService.performLoadChildren(MediaBrowserService.java:708)
        at android.service.media.MediaBrowserService.addSubscription(MediaBrowserService.java:638)
        at android.service.media.MediaBrowserService.access$500(MediaBrowserService.java:78)
        at android.service.media.MediaBrowserService$ServiceBinder$3.run(MediaBrowserService.java:298)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6718)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:495)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Play button doesn't respond after pressing pause in lock screen

When in lock screen mode i can press the pause button and the music pauses, then the notification on the lock screen changes to "<- play ->" but my notification should be showing only "play stop". If you unlock the screen you see the notification with the right set of buttons and can play pause etc...

To Reproduce
Steps to reproduce the behavior:

Bug:

  1. Start playing
  2. Go to lock screen
  3. Press pause button
  4. Press play button (not working)
    Workaround:
  5. Go to notifications
  6. Press play button (works)

Expected behaviour:
Should start playing and show right controls after pause

Screenshots
Notification:
0
Lock screen:
1
Lock screen after pressing pause, play doesn't respond:
2
Notification as it is:
3
Notification after pressing play:
4

Runtime Environment (please complete the following information):

  • Device: Samsung Galaxy S8 - SM G950
  • Android version: 9.0

Flutter SDK version
Flutter 1.2.1

Flutter doctor:
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.2.1, on Mac OS X 10.14.2 18C54, locale en-GB)
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] iOS toolchain - develop for iOS devices (Xcode 10.1)
[✓] Android Studio (version 3.3)
[✓] IntelliJ IDEA Community Edition (version 2018.2.4)
[✓] VS Code (version 1.32.3)
[✓] Connected device (2 available)

• No issues found!

Btw this plugin is a great contribution to Flutter, good work!
This is also an issue that Spotify had recently after some android updates.

Dual Audio Players?

I'm new to Flutter and I'm doing some research to see if it's in a state to build a music streaming app. I was trying the AudioPlayers library the other day and was impressed with how easy it was to use.

I'm now trying to get this service running, but I had some questions about an advanced configuration involving multiple media players. Specifically I want to make a gapless playback feature by using a second audioplayer instance to cache songs from a server while the current audioplayer instance is playing. Then when the song is finished, the audioplayers can be swapped seamlessly.

It looks like this is doable from what I can tell, but I wanted to see if there's any roadblocks.

Error handling in background isolate

I am having a bit of trouble figuring out how to do error handling within the background isolate.

My background task can throw some exceptions when trying to stream audio, and I would like to handle those exceptions in the UI side of things, so the user can be properly informed of what happened.
In case that the app is not opened, I would like to handle these exceptions when the the user opens the app, so probably when AudioService.connect is called again.

I had hoped to use custom actions to get this information across, but since I can only have custom actions go from the UI isolate to the background isolate, and not the other way around, I am not entirely sure how to approach this.

Any help would be greatly appreciated!

AudioServiceBackground onAudioPositionChanged property

Is your feature request related to a problem? Please describe.
A question. I want to show a play position counter. I thought there was onAudioPositionChanged property which I can define to call a function to update my playbackState, but there is not. I used to do a "onAudioPositionChanged.listen" like the "audioplayers" plugin.

Describe the solution you'd like
A onAudioPositionChanged call back property that I can define, if I was in the right direction.

Describe alternatives you've considered
None.

Additional context
(I have used scoped model and moved playbackState to the model, so as to save the play state between page navigation.)

Prefetch art URIs

At the moment (as far as I can tell), the art is only fetched when the song starts playing.
It'd be better if the plugin prefetched art for items in the queue, so there's no delay in showing the art in the notification.

AndroidX and audioplayer

@ryanheise I see that the new version is now on AndroidX. Before I upgrade, I have a question about how this affects the usage of the audioplayer plugin. I was not able to find any mention of androidx in the audioplayer github repo, which makes me think it is not supported.

If you're able to provide some clarification on this, I would greatly appreciate it.

Thanks.

iOS Support

I'm creating this issue to keep track of an iOS implementation. I myself am an Android developer, and I'd love to see an iOS developer contribute.

Notify on stop

This is my app's UI:

As you can see, I have a control bar at the bottom on any screen. If I press stop in the notification, I have no way to know to hide this bar.

I propose we make a stream that sends some special object (or just a boolean) when the service is started and stopped, so we can be notified.

Error in Execute

I'm trying to use the plugin in my project. I put 2 files: MainApplication.java and edited AndroidManifest.xml, exatly to the written in Tutorial, but I got this error:

Built build/app/outputs/apk/debug/app-debug.apk.
Syncing files to device Android SDK built for x86...
W/info.radiobasi( 5384): Accessing hidden field Landroid/service/media/MediaBrowserService$Result;->mFlags:I (light greylist, reflection)
D/AndroidRuntime( 5384): Shutting down VM
E/AndroidRuntime( 5384): FATAL EXCEPTION: main
E/AndroidRuntime( 5384): Process: br.com.tecnocampinfo.radiobasic, PID: 5384
E/AndroidRuntime( 5384): java.lang.IllegalStateException: No pluginRegistrantCallback has been set. Make sure you call AudioServicePlugin.setPluginRegistrantCallback(this) from your application's onCreate.
E/AndroidRuntime( 5384): 	at com.ryanheise.audioservice.AudioServicePlugin$ClientHandler$3.onPlay(AudioServicePlugin.java:224)
E/AndroidRuntime( 5384): 	at com.ryanheise.audioservice.AudioService$MediaSessionCallback$1.run(AudioService.java:446)
E/AndroidRuntime( 5384): 	at com.ryanheise.audioservice.AudioService$MediaSessionCallback.play(AudioService.java:461)
E/AndroidRuntime( 5384): 	at com.ryanheise.audioservice.AudioService$MediaSessionCallback.onPlay(AudioService.java:444)
E/AndroidRuntime( 5384): 	at android.support.v4.media.session.MediaSessionCompat$Callback$StubApi21.onPlay(MediaSessionCompat.java:1259)
E/AndroidRuntime( 5384): 	at android.support.v4.media.session.MediaSessionCompatApi21$CallbackProxy.onPlay(MediaSessionCompatApi21.java:194)
E/AndroidRuntime( 5384): 	at android.media.session.MediaSession$CallbackMessageHandler.handleMessage(MediaSession.java:1486)
E/AndroidRuntime( 5384): 	at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime( 5384): 	at android.os.Looper.loop(Looper.java:193)
E/AndroidRuntime( 5384): 	at android.app.ActivityThread.main(ActivityThread.java:6669)
E/AndroidRuntime( 5384): 	at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 5384): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
E/AndroidRuntime( 5384): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
I/Process ( 5384): Sending signal. PID: 5384 SIG: 9
Lost connection to device.

I use the Simulator, Android 9. Who can help me? Please? =D

Open application from notification

Is it possible to open application by tapping on the main notification body (like most Android players do, for example, Google Play Music)?

Codec exception when artUri is defined for MediaItem

Hello.

In my app I have cover art files stored for each album, they're accessible via url, for example:
http://antennaria.rocks/music/artwork/ecovillage/sacred_world_1d00e34d24e43b4b9bfc1c241f45300a_250x250.jpg

Trying to use setMediaItem(item) method with artUri set to such url (actually, any url I've tried) results in the following exception:

D/AndroidRuntime( 9000): Shutting down VM
E/AndroidRuntime( 9000): FATAL EXCEPTION: main
E/AndroidRuntime( 9000): Process: com.antennaria.gimpobox, PID: 9000
E/AndroidRuntime( 9000): java.lang.IllegalArgumentException: Unsupported value: http://antennaria.rocks/music/artwork/ecovillage/sacred_world_1d00e34d24e43b4b9bfc1c241f45300a_250x250.jpg
E/AndroidRuntime( 9000): 	at io.flutter.plugin.common.StandardMessageCodec.writeValue(StandardMessageCodec.java:293)
E/AndroidRuntime( 9000): 	at io.flutter.plugin.common.StandardMessageCodec.writeValue(StandardMessageCodec.java:290)
E/AndroidRuntime( 9000): 	at io.flutter.plugin.common.StandardMessageCodec.writeValue(StandardMessageCodec.java:282)
E/AndroidRuntime( 9000): 	at io.flutter.plugin.common.StandardMethodCodec.encodeMethodCall(StandardMethodCodec.java:36)
E/AndroidRuntime( 9000): 	at io.flutter.plugin.common.MethodChannel.invokeMethod(MethodChannel.java:83)
E/AndroidRuntime( 9000): 	at io.flutter.plugin.common.MethodChannel.invokeMethod(MethodChannel.java:70)
E/AndroidRuntime( 9000): 	at com.ryanheise.audioservice.AudioServicePlugin$ClientHandler.invokeMethod(AudioServicePlugin.java:417)
E/AndroidRuntime( 9000): 	at com.ryanheise.audioservice.AudioServicePlugin$ClientHandler$1.onMetadataChanged(AudioServicePlugin.java:71)
E/AndroidRuntime( 9000): 	at android.support.v4.media.session.MediaControllerCompat$Callback$StubApi21.onMetadataChanged(MediaControllerCompat.java:832)
E/AndroidRuntime( 9000): 	at android.support.v4.media.session.MediaControllerCompatApi21$CallbackProxy.onMetadataChanged(MediaControllerCompatApi21.java:297)
E/AndroidRuntime( 9000): 	at android.media.session.MediaController$MessageHandler.handleMessage(MediaController.java:1089)
E/AndroidRuntime( 9000): 	at android.os.Handler.dispatchMessage(Handler.java:108)
E/AndroidRuntime( 9000): 	at android.os.Looper.loop(Looper.java:166)
E/AndroidRuntime( 9000): 	at android.app.ActivityThread.main(ActivityThread.java:7425)
E/AndroidRuntime( 9000): 	at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 9000): 	at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
E/AndroidRuntime( 9000): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
I/Process ( 9000): Sending signal. PID: 9000 SIG: 9
Lost connection to device.

To be sure that url is valid I've used Uri.encodeFull() but no avail. Also I've tried to put hard-coded urls to various images from the internet to no avail as well.

Did you try artUri functionality by yourself? Did it work at all? What I do wrong?

Fail to run when simply modify the example code.

I am new in flutter and try to make a simple radio app, please help to solve the problem below.
Thank you.

Describe the bug
Fail to play stream when I just simply modify the example code, to make it click different's button to play different's online stream.

To Reproduce
click button 'AudioPlayer1' it will use Uri1 as stream source to play.
click button 'AudioPlayer2' it will use Uri2 as stream source to play.

Expected behavior
To play Uri1 / Uri2 audio stream.

Flutter SDK version
[√] Flutter (Channel beta, v1.4.9-hotfix.1, on Microsoft Windows [Version 10.0.17763.437], locale en-US)
• Flutter version 1.4.9-hotfix.1 at C:\flutter
• Framework revision 88fa7ea403 (11 days ago), 2019-04-11 14:01:46 -0700
• Engine revision 4737fc5cd8
• Dart version 2.2.1 (build 2.2.1-dev.4.1 None)

[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
• Android SDK at C:\ProgramData\AndroidStudio
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-28, build-tools 28.0.3
• ANDROID_HOME = C:\ProgramData\AndroidStudio
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)
• All Android licenses accepted.

[√] Android Studio (version 3.4)
• Android Studio at C:\Program Files\Android\Android Studio
• Flutter plugin version 34.0.2
• Dart plugin version 183.5901
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)

[!] IntelliJ IDEA Community Edition (version 2019.1)
• IntelliJ at C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2019.1
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.
• For information about installing plugins, see
https://flutter.io/intellij-setup/#installing-the-plugins

[√] VS Code, 64-bit edition (version 1.33.1)
• VS Code at C:\Program Files\Microsoft VS Code
• Flutter extension version 2.25.1

[√] Connected device (1 available)
• Android SDK built for x86 • emulator-5554 • android-x86 • Android 9 (API 28) (emulator)

** Code: **
import 'package:audioplayer/audioplayer.dart';
import 'package:flutter/material.dart';
import 'dart:async';

import 'package:audio_service/audio_service.dart';

MediaControl playControl = MediaControl(
androidIcon: 'drawable/ic_action_play_arrow',
label: 'Play',
action: MediaAction.play,
);
MediaControl pauseControl = MediaControl(
androidIcon: 'drawable/ic_action_pause',
label: 'Pause',
action: MediaAction.pause,
);
MediaControl stopControl = MediaControl(
androidIcon: 'drawable/ic_action_stop',
label: 'Stop',
action: MediaAction.stop,
);

String streamUri = '';
const Uri1 = 'https://5b2959fe11444.streamlock.net/radio/am1430.stream/playlist.m3u8';
const Uri2 = 'https://stmw.rthk.hk/vod/_definst_/rthkweb/smil:sub_spots__5c244fc5e3463.smil/manifest.m3u8';

void main() => runApp(new MyApp());

class MyApp extends StatefulWidget {
@OverRide
_MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State with WidgetsBindingObserver {
PlaybackState _state;
StreamSubscription _playbackStateSubscription;

@OverRide
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
connect();
}

@OverRide
void dispose() {
disconnect();
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}

@OverRide
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.resumed:
connect();
break;
case AppLifecycleState.paused:
disconnect();
break;
default:
break;
}
}

void connect() async {
await AudioService.connect();
if (_playbackStateSubscription == null) {
_playbackStateSubscription = AudioService.playbackStateStream
.listen((PlaybackState playbackState) {
setState(() {
_state = playbackState;
});
});
}
}

void disconnect() {
if (_playbackStateSubscription != null) {
_playbackStateSubscription.cancel();
_playbackStateSubscription = null;
}
AudioService.disconnect();
}

@OverRide
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: const Text('Audio Service Demo'),
),
body: new Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: _state?.basicState == BasicPlaybackState.playing
? [pauseButton(), stopButton()]
: _state?.basicState == BasicPlaybackState.paused
? [playButton(), stopButton()]
: [startButton('AudioPlayer1', _backgroundAudioPlayerTask, Uri1), startButton('AudioPlayer2', _backgroundAudioPlayerTask, Uri2)],
),
),
),
);
}

RaisedButton startButton(String label, Function backgroundTask, String Uri) {
streamUri = Uri;
return RaisedButton(
child: Text(label),
onPressed: () {
AudioService.start(
backgroundTask: backgroundTask,
resumeOnClick: true,
androidNotificationChannelName: 'Audio Service Demo',
notificationColor: 0xFF2196f3,
androidNotificationIcon: 'mipmap/ic_launcher',
);
},
);
}

IconButton playButton() => IconButton(
icon: Icon(Icons.play_arrow),
iconSize: 64.0,
onPressed: AudioService.play,
);

IconButton pauseButton() => IconButton(
icon: Icon(Icons.pause),
iconSize: 64.0,
onPressed: AudioService.pause,
);

IconButton stopButton() => IconButton(
icon: Icon(Icons.stop),
iconSize: 64.0,
onPressed: AudioService.stop,
);
}

void _backgroundAudioPlayerTask() async {
CustomAudioPlayer player = CustomAudioPlayer();
AudioServiceBackground.run(
onStart: player.run,
onPlay: player.play,
onPause: player.pause,
onStop: player.stop,
onClick: (MediaButton button) => player.playPause(),
);
}

class CustomAudioPlayer {
AudioPlayer _audioPlayer = new AudioPlayer();
Completer _completer = Completer();

Future run() async {
MediaItem mediaItem = MediaItem(
id: 'audio_1',
album: 'Sample Album',
title: 'Sample Title',
artist: 'Sample Artist');

AudioServiceBackground.setMediaItem(mediaItem);

var playerStateSubscription = _audioPlayer.onPlayerStateChanged
    .where((state) => state == AudioPlayerState.COMPLETED)
    .listen((state) {
  stop();
});
play();
await _completer.future;
playerStateSubscription.cancel();

}

void playPause() {
if (AudioServiceBackground.state.basicState == BasicPlaybackState.playing)
pause();
else
play();
}

void play() {
_audioPlayer.play(streamUri);
AudioServiceBackground.setState(
controls: [pauseControl, stopControl],
basicState: BasicPlaybackState.playing,
);
}

void pause() {
_audioPlayer.pause();
AudioServiceBackground.setState(
controls: [playControl, stopControl],
basicState: BasicPlaybackState.paused,
);
}

void stop() {
_audioPlayer.stop();
AudioServiceBackground.setState(
controls: [],
basicState: BasicPlaybackState.stopped,
);
_completer.complete();
}
}

Issue canceling stream subscription

I'm having an issue with the new stream apis, where setState is being called after my widget is disposed. I can't work out what I've done wrong.

Relevant code:

  void connect() async {
    AudioService.connect();
    playbackStateSubscription?.cancel();
    playbackStateSubscription = AudioService.playbackStateStream.listen((PlaybackState playbackState) {
      setState(() {
        _playbackState = playbackState;
        print(playbackState);
      });
    });
  }

  void stopListening() {
    playbackStateSubscription?.cancel();
    playbackStateSubscription = null;
  }

  @override
  void initState() {
    super.initState();
    connect();
  }

  @override
  void dispose() {
    stopListening();
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.resumed:
        connect();
        break;
      case AppLifecycleState.paused:
        stopListening();
        AudioService.disconnect();
        break;
      default:
        break;
    }
  }

Await execution of custom action

As media items do not seem to contain any information about what to play (such as a streaming URL), I am trying to provide the background task with this information using the AudioService.customAction function.
After this, I would like to initiate playing with AudioService.play, roughly as such:

Map<String, String> sources = { 'mediaId': 'exampleUrl' }; 
await AudioService.customAction('addMediaSources', sources);
await AudioService.play();

However, it seems so that sometimes the onPlay callback in the background task is called before the onCustomAction callback completes. Because of this, there is yet no source to play from by the time the onPlay callback is called.
When adding a bit of a delay between the customAction and play calls, everything functions as normal.

It seems that the future returned by customAction can complete before the actual completion of the callback. Is it possible to change this behaviour, or is there maybe some other way I can wait for the custom action to complete before moving on?

Updating media item with same id not possible

When AudioServiceBackground.setMediaItem is called twice in a row for a MediaItem with the same id, the changes to the media item in the second call are not reflected in the item coming out of AudioService.currentMediaItemStream. Instead, the media item from the first call is output another time.

When the id differs between the first and second call, it does behave as expected.

I run into this issue when attempting to update the duration. In my situation when the onPlay callback is called, the media item is set with setMediaItem, but the duration is still unknown as the item is being streamed. As soon as the duration is known by the audio player, I copy the MediaItem with the new duration included and call AudioServiceBackground.setMediaItem once again. However, as the MediaItem id is still the same, AudioService.currentMediaItemStream does not provide the new duration.

register.activity() must not null

I have setup the plugin but when try to play app force close.
i have setup from example provided and using same audio plugin also.

java.lang.IllegalStateException: registrar.activity() must not be null
at com.fuyumi.flutterstatusbarcolor.flutterstatusbarcolor.FlutterStatusbarcolorPlugin$Companion.registerWith(FlutterStatusbarcolorPlugin.kt:18)
at com.fuyumi.flutterstatusbarcolor.flutterstatusbarcolor.FlutterStatusbarcolorPlugin.registerWith(Unknown Source:2)
at io.flutter.plugins.GeneratedPluginRegistrant.registerWith(GeneratedPluginRegistrant.java:34)
at com.thebridges.thebridgesapp.MainApplication.registerWith(MainApplication.java:17)
at com.ryanheise.audioservice.AudioServicePlugin$ClientHandler$4.onPlay(AudioServicePlugin.java:258)
at com.ryanheise.audioservice.AudioService$MediaSessionCallback$1.run(AudioService.java:525)
at com.ryanheise.audioservice.AudioService$MediaSessionCallback.play(AudioService.java:541)
at com.ryanheise.audioservice.AudioService$MediaSessionCallback.onPlay(AudioService.java:523)
at android.support.v4.media.session.MediaSessionCompat$Callback$StubApi21.onPlay(MediaSessionCompat.java:1259)
at android.support.v4.media.session.MediaSessionCompatApi21$CallbackProxy.onPlay(MediaSessionCompatApi21.java:194)
at android.media.session.MediaSession$CallbackMessageHandler.handleMessage(MediaSession.java:1416)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)

Flutter doctor

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, v1.2.1, on Mac OS X 10.13.6 17G65, locale en-IN)
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] iOS toolchain - develop for iOS devices (Xcode 10.1)
[✓] Android Studio (version 3.3)

Error to use this plugin together to google_maps_flutter

I know It is no problem with audio_service, but I don't know who ask. I try use this plugin together to google_maps_flutter: ^0.0.3+3, but I obtened this error:

W/info.radiobasi( 7357): Accessing hidden field Landroid/service/media/MediaBrowserService$Result;->mFlags:I (light greylist, reflection)
D/AndroidRuntime( 7357): Shutting down VM
E/AndroidRuntime( 7357): FATAL EXCEPTION: main
E/AndroidRuntime( 7357): Process: br.com.tecnocampinfo.radiobasic, PID: 7357
E/AndroidRuntime( 7357): java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
E/AndroidRuntime( 7357): 	at io.flutter.plugins.googlemaps.GoogleMapsPlugin.<init>(GoogleMapsPlugin.java:90)

Anyone can help me? I tried to search and modify the code in the plugin, but I do not had a good result.
Thanks for everything, Your plugin guaranteed one job to sustent my family =)

Get metadata from audio task

Is your feature request related to a problem? Please describe.
I'm building a Pandora client. In a nutshell, Pandora lets you have different stations, with different kinds of music chosen for you on each one. In my UI, I need to access the playing station's name and id.

Describe the solution you'd like
IIRC, Android lets you save simple data like strings and integers in a bundle in the MediaSession itself. We can create functions in the AudioServiceBackground and AudioService classes to set/get the data respectively. Perhepas we could go even futher than the Android API and use streams as well.

Describe alternatives you've considered
Right now, I'm using the genre field in the playing MediaItem to hold this data, by storing it in the format id||stationName. This is a bad solution because the station name could (although it is unlikely) have a double pipe in it. I've though of some other solutions:

  • Shared preferences can be used, but that's a lot of unnecessary IO for something that doesn't need to be written to the disk.
  • This could be implemented with SendPorts, but it would be very cumbersome, with a lot of boilerplate.
  • A separate plugin could be made, using platform channels to save and retrieve data to and from memory on the native side, but this feels like it's over complicating the problem.

NullPointerException when running setMediaItem

When the background service is running and playing an item, if I call AudioService.stop(), then play() on a new item, I call the AudioServiceBackground.setMediaItem() method and get the following error:

03:58:49.305 90 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): Failed to handle method call
03:58:49.305 91 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String[] java.lang.String.split(java.lang.String)' on a null object reference
03:58:49.305 92 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): 	at com.ryanheise.audioservice.AudioService.getResourceId(AudioService.java:136)
03:58:49.305 93 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): 	at com.ryanheise.audioservice.AudioService.buildNotification(AudioService.java:188)
03:58:49.305 94 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): 	at com.ryanheise.audioservice.AudioService.updateNotification(AudioService.java:285)
03:58:49.305 95 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): 	at com.ryanheise.audioservice.AudioService.setMetadata(AudioService.java:398)
03:58:49.305 96 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): 	at com.ryanheise.audioservice.AudioServicePlugin$BackgroundHandler.onMethodCall(AudioServicePlugin.java:543)
03:58:49.305 97 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:201)
03:58:49.305 98 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): 	at io.flutter.view.FlutterNativeView$PlatformMessageHandlerImpl.handleMessageFromDart(FlutterNativeView.java:188)
03:58:49.305 99 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): 	at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:202)
03:58:49.305 100 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): 	at android.os.MessageQueue.nativePollOnce(Native Method)
03:58:49.305 101 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): 	at android.os.MessageQueue.next(MessageQueue.java:326)
03:58:49.305 102 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): 	at android.os.Looper.loop(Looper.java:160)
03:58:49.305 103 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): 	at android.app.ActivityThread.main(ActivityThread.java:6680)
03:58:49.305 104 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): 	at java.lang.reflect.Method.invoke(Native Method)
03:58:49.305 105 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
03:58:49.305 106 info flutter.tools E/MethodChannel#ryanheise.com/audioServiceBackground(31568): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Any help or ideas on what could be wrong would be greatly appreciated.

AudioService.connect should be mentioned in the README

EDIT: See this comment.

Nothing happens when I run this code:

AudioService.start(
  backgroundTask: audioTask,
  notificationChannelName: "Media",
);

No notification is shown, and the service is not shown as a running service in the developer settings. This code, however, still prints true:

AudioService.running.then((bool running) {
  print(running);
});

Further, when I call AudioService.play(), I get an exception thrown from the JVM:

Attempt to invoke virtual method 'android.support.v4.media.session.MediaControllerCompat$TransportControls android.support.v4.media.session.MediaControllerCompat.getTransportControls()' on a null object reference.

I don't know if this is a bug, but "registered" is never printed with this code in my application class:

public class MainApplication : FlutterApplication(), PluginRegistry.PluginRegistrantCallback {
    override fun onCreate() {
        super.onCreate()
        println("onCreate!!!")
        AudioServicePlugin.setPluginRegistrantCallback(this)
    }

    override fun registerWith(registry: PluginRegistry) {
        println("registered!!!")
        GeneratedPluginRegistrant.registerWith(registry)
    }
}

The androidNotificationChannelName not be change the notification

I'm using the androidNotificationChannelName: but nothing happening in the notification.

AudioService.connect();
AudioService.start(
  backgroundTask: _backgroundAudioPlayerTask,
  resumeOnClick: true,
  androidNotificationChannelName: 'ABC Rádio',
  notificationColor: 0x5E6263,
  androidNotificationIcon: 'mipmap/radio',
);

captura de tela de 2019-01-06 22-31-54

Anyone can help me? =D

Sloppy notification layout

Hello, thanks for the great plugin. It's not the easiest one to use but potential is enormous. Now I am in the process of rewriting my custom player to use your plugin and will file the issues on the way :-)

The first one may looks minor but anyway maybe it is easy to fix. Notification layout is a bit sloppy: Track / Album information is displayed right under the Notification Channel / Icon row without any padding which looks a bit ugly. In comparison, several standard notifications are displayed more accurate. Please see attached screenshot to spot the difference.

image

[Help] Getting Started with this library

Hello everyone,
I'm creating an application that requires background audio and I came across this library. The problem is that I don't understand how everything works together. Reading the example didn't help me a lot and I don't want to copy paste and adjust things since I will maintain it later. I will leave a brief example of how I coded that part.

I'm already using AudioPlayer library to play audio and I'm trying to use it with this library.
This library plays audio or just help the AudioPlayer play even if locked?
Sorry if I'm a bit annoying, I'm new to flutter and those libraries too

The problem with that problem is that nothing happens, no error no audio.

Frontend widget:

void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.resumed:
        AudioService.connect();
        break;
      case AppLifecycleState.paused:
        AudioService.disconnect();
        break;
      default:
        break;
    }
}

new IconButton(
              onPressed: () => state == AudioPlayerState.PLAYING ? pause() : play(urlAudio),
              iconSize: 26.0,
              icon: state == AudioPlayerState.PLAYING ? new Icon(Icons.pause) : new Icon(Icons.play_arrow),
              color: Colors.cyan)

play(String URL) {
    urlAudio = URL;
    AudioService.play();
}

Background Audio Worker:

    AudioServiceBackground.run(
      onStart: () async {
        // do i need to do something here?
      },
      onPlay: () async {
        if(_songs != null && _songs.length > 0) {
          if(isPlaying) {
            await super.stop();
          }

          if(_songs.length > _indexSong) {
            _indexSong = _indexSong;
            await super.play(_songs[_indexSong], isLocal: false);
          } else {
            _indexSong = 0;
            await super.play(_songs[0], isLocal: false);
          }
        }
      },
      onPause: () async {
        if(state == AudioPlayerState.PLAYING) {
          await super.pause();
        }
      },
      onStop: () {
        // Your custom dart code to stop audio playback.
      },
      onClick: (MediaButton button) {
        // Your custom dart code to handle a media button click.
      }
    );
  }

Compatibility with other plugins

I am using the flutter_inappbrowser plugin in my project, as well as audioservice.

If I open a browser view before ever starting the audio service, all is okay, but if I start the audio service, then open the browser, the app crashes with the error:

08:54:03.581 145 info flutter.tools E/AndroidRuntime(31364): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference

The call stack stops around here:

08:54:03.583 148 info flutter.tools E/AndroidRuntime(31364): 	at com.pichillilorenzo.flutter_inappbrowser.InAppBrowserActivity.show(InAppBrowserActivity.java:309)
08:54:03.583 149 info flutter.tools E/AndroidRuntime(31364): 	at com.pichillilorenzo.flutter_inappbrowser.InAppBrowserActivity.prepareView(InAppBrowserActivity.java:98)
08:54:03.583 150 info flutter.tools E/AndroidRuntime(31364): 	at com.pichillilorenzo.flutter_inappbrowser.InAppBrowserActivity.onCreate(InAppBrowserActivity.java:69)

I suspect this could be related to audioservice requiring a custom MainApplication class, but I don't have much Android development experience, so any insight/help would be much appreciated.

browser plugin: https://github.com/pichillilorenzo/flutter_inappbrowser

dynamic audio file path in backgroundTask

The example has a hardcoded audio file URL, and since the backgroundTask callback is in an isolate, I am unable to pass the correct URL to the AudioPlayer.

How can I pass a dynamic file path to the audio player in the BackgroundTask callback?

I was thinking to use isolate ports in the backgroundTask, but not sure if thats the correct way, or if it would even work (im new to flutter/dart)

Thanks.

AndroidX support

Fail to update the example project to Gradle 4.6 and Android Studio Gradle plugin 3.2.0.

NullPointerException thrown on start release build

When launching a release APK with this plugin, the app crashes on start.
It works fine when debugging normally with Android Studio & IntelliJ.
This too happens to the example app included.

Steps to reproduce:

  1. flutter build apk --release
  2. flutter install
  3. Launch the app

The following exception is thrown:

01-06 01:39:35.691 21844 21844 D AndroidRuntime: Shutting down VM
01-06 01:39:25.272 21788 21788 E AndroidRuntime: FATAL EXCEPTION: main
01-06 01:39:25.272 21788 21788 E AndroidRuntime: Process: com.ryanheise.audioserviceexample, PID: 21788
01-06 01:39:25.272 21788 21788 E AndroidRuntime: java.lang.NullPointerException: Attempt to invoke interface method 'void io.flutter.plugin.common.MethodChannel$Result.success(java.lang.Object)' on a null object reference
01-06 01:39:25.272 21788 21788 E AndroidRuntime:        at com.ryanheise.audioservice.AudioServicePlugin$ClientHandler.sendConnectResult(AudioServicePlugin.java:148)
01-06 01:39:25.272 21788 21788 E AndroidRuntime:        at com.ryanheise.audioservice.AudioServicePlugin$ClientHandler.access$500(AudioServicePlugin.java:69)
01-06 01:39:25.272 21788 21788 E AndroidRuntime:        at com.ryanheise.audioservice.AudioServicePlugin$ClientHandler$3.onConnected(AudioServicePlugin.java:122)
01-06 01:39:25.272 21788 21788 E AndroidRuntime:        at android.support.v4.media.MediaBrowserCompat$ConnectionCallback$StubApi21.onConnected(MediaBrowserCompat.java:651)
01-06 01:39:25.272 21788 21788 E AndroidRuntime:        at android.support.v4.media.MediaBrowserCompatApi21$ConnectionCallbackProxy.onConnected(MediaBrowserCompatApi21.java:102)
01-06 01:39:25.272 21788 21788 E AndroidRuntime:        at android.media.browse.MediaBrowser$6.run(MediaBrowser.java:603)
01-06 01:39:25.272 21788 21788 E AndroidRuntime:        at android.os.Handler.handleCallback(Handler.java:873)
01-06 01:39:25.272 21788 21788 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:99)
01-06 01:39:25.272 21788 21788 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:193)
01-06 01:39:25.272 21788 21788 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:6863)
01-06 01:39:25.272 21788 21788 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
01-06 01:39:25.272 21788 21788 E AndroidRuntime:        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
01-06 01:39:25.272 21788 21788 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Help needed! how to pass URL fetched from an API

Please, I'm new to flutter and I'm building a music app, I found your plugin helpful and I'm fetching songs from an API and I need to pass URL so that when the music is playing, it will also show in the notification panel, but I have not been able to do so.

This is what i want to do:

class CustomAudioPlayer {
streamUri = url.link;
AudioPlayer _audioPlayer = new AudioPlayer();
Completer _completer = Completer();

Future run() async {
MediaItem mediaItem = MediaItem(
id: '',
album: '',
title: url.title,
artist: url.artist
);

AudioServiceBackground.setMediaItem(mediaItem);

var playerStateSubscription = _audioPlayer.onPlayerStateChanged
    .where((state) => state == AudioPlayerState.COMPLETED)
    .listen((state) {
  stop();
});
play();
await _completer.future;
playerStateSubscription.cancel();

}

void playPause() {
if (AudioServiceBackground.state.basicState == BasicPlaybackState.playing)
pause();
else
play();
}

void play() {
_audioPlayer.play(streamUri);
AudioServiceBackground.setState(
controls: [pauseControl, stopControl],
basicState: BasicPlaybackState.playing,
);
}

void pause() {
_audioPlayer.pause();
AudioServiceBackground.setState(
controls: [playControl, stopControl],
basicState: BasicPlaybackState.paused,
);
}

void stop() {
_audioPlayer.stop();
AudioServiceBackground.setState(
controls: [],
basicState: BasicPlaybackState.stopped,
);
_completer.complete();
}
}

Option to keep the notification non-dismissable when paused?

I know the Android docs say to make the notification dismissable when the audio's paused, but I find this annoying because it's too easy to stop the service with the "clear all" button in the notification tray. I prefer to have a stop action in my notification.

It'd be great have an option to keep the notification non-dismissable when the audio's paused.

AudioService.addToQueue generates exception: "This session doesn't support queue management operations".

Hello!

While experimenting with this plugin, I ran into the issue that whenever I call AudioService.addQueueItem, the following exception is thrown:

E/MethodChannel#ryanheise.com/audioService(11872): Failed to handle method call
E/MethodChannel#ryanheise.com/audioService(11872): java.lang.UnsupportedOperationException: This session doesn't support queue management operations
E/MethodChannel#ryanheise.com/audioService(11872): 	at android.support.v4.media.session.MediaControllerCompat$MediaControllerImplApi21.addQueueItem(MediaControllerCompat.java:1988)
E/MethodChannel#ryanheise.com/audioService(11872): 	at android.support.v4.media.session.MediaControllerCompat.addQueueItem(MediaControllerCompat.java:316)
E/MethodChannel#ryanheise.com/audioService(11872): 	at com.ryanheise.audioservice.AudioServicePlugin$ClientHandler.onMethodCall(AudioServicePlugin.java:316)
E/MethodChannel#ryanheise.com/audioService(11872): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:200)
E/MethodChannel#ryanheise.com/audioService(11872): 	at io.flutter.view.FlutterNativeView.handlePlatformMessage(FlutterNativeView.java:163)
E/MethodChannel#ryanheise.com/audioService(11872): 	at android.os.MessageQueue.nativePollOnce(Native Method)
E/MethodChannel#ryanheise.com/audioService(11872): 	at android.os.MessageQueue.next(MessageQueue.java:326)
E/MethodChannel#ryanheise.com/audioService(11872): 	at android.os.Looper.loop(Looper.java:160)
E/MethodChannel#ryanheise.com/audioService(11872): 	at android.app.ActivityThread.main(ActivityThread.java:6863)
E/MethodChannel#ryanheise.com/audioService(11872): 	at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#ryanheise.com/audioService(11872): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
E/MethodChannel#ryanheise.com/audioService(11872): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

This error was produced with the following code, based off the example in this repo:
https://gist.github.com/BeMacized/5ccc11f43c4b18bd1e40a1e539082721

Any idea what might cause this?

Unable (did not figured out) how to get duration and position of currently played track

Hello.

While main audio management work is now handled in background task I am curious how the launching app should know about played track duration and (most important) current position (to display seek bar).

AudioPlayer plugin which I use for actual playing provides convenient streams / properties to get all this information but how to pass this information back from background task is a question. As far as I understand it's now impossible because the only hooks you can made into background task are those in the AudioService.connect() method and all of them are unsuitable for the task. After discovering this I hoped that I will be able to utilize custom action functionality you provide but this turned out to be custom action FROM AudioService to background task and not in the opposite direction.

Of course I can hack the system with some kind of communication solution (like using Shared Preferences or even file system) but this looks inefficient and smelly....

What do you think? Best regards!

Using flutter_radio

I have some problems to use audioplayer and found the flutter_radio. This plugin solve my problems, but don't work fine in audio_service.

I adapted the Exemple Code for use flutter_radio

@override
  void initState() {
    super.initState();
    AudioService.connect();
    AudioService.start(
      backgroundTask: _backgroundAudioPlayerTask,
      resumeOnClick: true,
      androidNotificationChannelName: 'ABC Rádio',
      notificationColor: 0x5E6263,
      androidNotificationIcon: 'mipmap/radio',
    );
  }

and

void _backgroundAudioPlayerTask() async {
  CustomAudioPlayer player = CustomAudioPlayer();
  AudioServiceBackground.run(
    onStart: player.run,
    onPlay: player.play,
    onPause: player.pause,
    onStop: player.stop,
    onClick: (MediaButton button) => player.playPause(),
  );
}

class CustomAudioPlayer {
  
  bool _playing;

  Future<void> run() async {
    MediaItem mediaItem = MediaItem(
        id: 'audio_1', album: 'ABC Radio', title: 'A rádio que não cansa vc');
    AudioServiceBackground.setMediaItem(mediaItem);
    audioStart();
    play();
  }

  Future<void> audioStart() async {
    await FlutterRadio.audioStart();
    print('Audio Start OK');
  }

  void playPause() {
    if (_playing)
      pause();
    else
      play();
  }

  void play() {
    FlutterRadio.play(url: streamUrl);
    _playing = true;
    AudioServiceBackground.setState(
        controls: [pauseControl, stopControl],
        basicState: BasicPlaybackState.playing);
    buttonState = !buttonState;
  }

  void pause() {
    FlutterRadio.playOrPause(url: streamUrl);
    AudioServiceBackground.setState(
        controls: [playControl, stopControl],
        basicState: BasicPlaybackState.paused);
  }

  void stop() {
    FlutterRadio.playOrPause(url: streamUrl);
    AudioServiceBackground.setState(
        controls: [], basicState: BasicPlaybackState.stopped);
    buttonState = !buttonState;
  }
}

The audio start normally in initState, the notification start, but not fixed, closing fast after starter. The audio continue playing normally.

The log in the starter app is:

I/ExoPlayerImpl(30320): Init abad60d [ExoPlayerLib/2.8.2] [ASUS_Z012D, ASUS_Z012DC, asus, 26]
D/EventBus(30320): No subscribers registered for event class java.lang.String
D/EventBus(30320): No subscribers registered for event class org.greenrobot.eventbus.NoSubscriberEvent
D/EventBus(30320): No subscribers registered for event class java.lang.String
D/EventBus(30320): No subscribers registered for event class org.greenrobot.eventbus.NoSubscriberEvent
D/NetworkSecurityConfig(30320): No Network Security Config specified, using platform default
I/DpmTcmClient(30320): RegisterTcmMonitor from: com.android.okhttp.TcmIdleTimerMonitor
W/VideoCapabilities(30320): Unrecognized profile 2130706433 for video/avc
W/VideoCapabilities(30320): Unrecognized profile 2130706434 for video/avc

The project repository is here: https://github.com/thyagoluciano/flutter_radio

Why can I do to work the flutter_radio in audio_service?

[Example] Pass data to backgroundAudioPlayerTask

Good getlocaltime()!

I'm struggling to pass any data to _backgroundAudioPlayerTask function (according to this example https://github.com/ryanheise/audio_service/blob/master/example/lib/main.dart). I want to pass URL to play.

var res = AudioService.start(
  backgroundTask: () async {
    // I modified CustomAudioPlayer also
    CustomAudioPlayer player = CustomAudioPlayer("HERE IS MY URL");
    AudioServiceBackground.run(
      onStart: player.run,
      onPlay: player.play,
      onPause: player.pause,
      onStop: player.stop,
      onClick: (MediaButton button) => player.playPause(),
    );
  },
  // omited
);

But it doesn't work. It returns instance of Future<bool> which resolves to false:

I/flutter (19613): Instance of 'Future<bool>'
I/flutter (19613): false

I also was trying to do something like this:

Function play(String url) {
  void handler() async {
    CustomAudioPlayer player = CustomAudioPlayer(url);
    AudioServiceBackground.run(
      onStart: player.run,
      onPlay: player.play,
      onPause: player.pause,
      onStop: player.stop,
      onClick: (MediaButton button) => player.playPause(),
    );
  }
  return handler;
}

Error:

E/flutter (20407): [ERROR:flutter/shell/common/shell.cc(184)] Dart Error: Unhandled exception:
E/flutter (20407): NoSuchMethodError: No top-level getter 'handler' declared.
E/flutter (20407): Receiver: top-level
E/flutter (20407): Tried calling: handler
E/flutter (20407): #0      NoSuchMethodError._throwNew (dart:core/runtime/liberrors_patch.dart:212:5)
E/flutter (20407): [ERROR:flutter/shell/common/engine.cc(178)] Could not run the isolate.
E/flutter (20407): [ERROR:flutter/shell/common/engine.cc(119)] Engine not prepare and launch isolate.
E/flutter (20407): [ERROR:flutter/shell/platform/android/android_shell_holder.cc(167)] Could not launch engine in configuration.

Can you help me please, what I'm doing wrong?

p.s: I'm new to dart and flutter, so maybe I'm doing something really stupid :)

Unable to build iOS app

Here is the logs of the build
`Launching lib/main.dart on iPhone Xʀ in debug mode...
Running pod install...
CocoaPods' output:

Preparing

Analyzing dependencies

Inspecting targets to integrate
  Using `ARCHS` setting to build architectures of target `Pods-Runner`: (``)

Finding Podfile changes
  A audio_service
  A audioplayer
  - Flutter
  - flutter_downloader
  - package_info
  - path_provider
  - url_launcher

Fetching external sources
-> Fetching podspec for `Flutter` from `.symlinks/flutter/ios`
-> Fetching podspec for `audio_service` from `.symlinks/plugins/audio_service/ios`
[!] No podspec found for `audio_service` in `.symlinks/plugins/audio_service/ios`

/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/external_sources/path_source.rb:14:in `block in fetch'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/user_interface.rb:85:in `titled_section'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/external_sources/path_source.rb:11:in `fetch'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/installer/analyzer.rb:697:in `fetch_external_source'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/installer/analyzer.rb:673:in `block (2 levels) in fetch_external_sources'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/installer/analyzer.rb:672:in `each'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/installer/analyzer.rb:672:in `block in fetch_external_sources'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/user_interface.rb:64:in `section'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/installer/analyzer.rb:671:in `fetch_external_sources'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/installer/analyzer.rb:85:in `analyze'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/installer.rb:243:in `analyze'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/installer.rb:154:in `block in resolve_dependencies'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/user_interface.rb:64:in `section'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/installer.rb:153:in `resolve_dependencies'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/installer.rb:116:in `install!'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/command/install.rb:41:in `run'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/claide-1.0.2/lib/claide/command.rb:334:in `run'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/lib/cocoapods/command.rb:52:in `run'
/usr/local/Cellar/cocoapods/1.5.3/libexec/gems/cocoapods-1.5.3/bin/pod:55:in `<top (required)>'
/usr/local/Cellar/cocoapods/1.5.3/libexec/bin/pod:22:in `load'
/usr/local/Cellar/cocoapods/1.5.3/libexec/bin/pod:22:in `<main>'

Error output from CocoaPods:

[!] Automatically assigning platform `ios` with version `10.0` on target `Runner` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.

Error running pod install
Error launching application on iPhone Xʀ.
`

Start Audioservice on "initState"

I want start the notification in app initialization, but don't play anything. I try, in the example, put this code in "initState":

@override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); connect(); AudioService.start( backgroundTask: _backgroundAudioPlayerTask, resumeOnClick: true, notificationChannelName: 'Audio Service Demo', notificationColor: 0xFF2196f3, androidNotificationIcon: 'mipmap/ic_launcher', ); }

But don't working. Anyone can help me? =D

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.