bluefireteam / ocarina Goto Github PK
View Code? Open in Web Editor NEWFlutter plugin to play local audio files
License: MIT License
Flutter plugin to play local audio files
License: MIT License
Expected behaviour
I want to play the asset audio with ocarina library without stoping background music (e.g. Spotify)
Actual behaviour
The background music is currently stoped and even does not restart after playing the audio from ocarina.
I am working on an app that requires me to layer audio files. Specifically: short audio snippets as well as a background music that can be toggled.
For the main audio snippets I use the audioplayers package. As it uses up to 50 different audio snippets and they have to be played in low latency and using the stayAwake
(which is lovely btw)
To get the background music as a seamless loop I came to this package, which works really well on my iOS simulator and my android phone. However when I test this on a physical iOS device the background audio stops as soon as the first audio snippet comes up. I can also get it to stop playing audio snippets and just the background music. However layering these 2 is impossible. One audio seems to duck the other one.
As a solution I'm open to using Ocarina for all sounds, but it seems to be targeted at just looping audio, rather than loading all sorts of different sounds.
Request to update this package to use null safety.
Migration Guide: https://dart.dev/null-safety/migration-guide
Users of this package are blocked from properly migrating their codebase to be null safe until this package is migrated.
Hi,
All was working fine yesterday until I updated flutter and android studio to latest versions.
Issues with ocarina are now causing app to fail in run for both debug and release modes. I'm using ocarina 0.0.3 for info.
Console is splitting out a bunch of redeclarations and then:
None of the following functions can be called with the arguments supplied:
public constructor AssetOcarinaPlayer(url: String, volume: Double, loop: Boolean, context: Context) defined in xyz.erick.ocarina.AssetOcarinaPlayer
public constructor AssetOcarinaPlayer(url: String, volume: Double, loop: Boolean, context: Context, flutterAssets: FlutterPlugin.FlutterAssets) defined in xyz.erick.ocarina.AssetOcarinaPlayer
What went wrong:
Execution failed for task ':ocarina:compileDebugKotlin'.
I know I've been loading assets and using ocarina methods correctly as been using the package since v0.0.1 with no issues to date, until this update.
Flagging and hopefully an easy fix.
Thanks
Hi there,
I could not see a way to detect whether the player was actually playing or not and need a way to pause and resume sounds. In Ocarina however if you play a sound and the sound ends if you pause and resume it the resume will replay the sound when it should not as it was not playing.
So it would be nice if either resume worked as it should and not restart the sound or a way to detect if the sound is actually still playing is made available.
Thanks
Alan
Recently (maybe with iOS 13.6), something has changed...when the phone is muted, Ocarina doesn't play any more. So users either think, the audio is broken, or complain about this change, because they would like audio during mediation, but the rest of the phone muted.
It would be really cool if there could be a variable to play audio anyway.
And thanks for this plugin, it works really well.
I have followed ocarina's official example from lib/main.dart:
_ElevatedButton(
child: Text("Play asset audio"),
onPressed: () async {
final player = OcarinaPlayer(
asset: 'storage/emulated/0/Quran.mp3', loop: _loop);
setState(() {
player = player;
});
}),
This snippet fails to load an MP3 file that exists in the described filesystem and can be played by YouTube Music Player locally .
Kindly, have a look .
Hi, first of all ๐ฅ its great about solving the annoying gape in the loop,
Can u plz add background notifications the the player with ability to control what buttons(play,pause,stop) I want to show?
Thank U :)
When using load()
method on Android, the app crashes with the following stacktrace:
Fatal Exception: java.lang.NoClassDefFoundError
Failed resolution of: Lcom/google/android/exoplayer2/source/ExtractorMediaSource;
xyz.erick.ocarina.AssetOcarinaPlayer.extractMediaSourceFromUri
Caused by java.lang.ClassNotFoundException
Didn't find class "com.google.android.exoplayer2.source.ExtractorMediaSource" on path: DexPathList[[zip file "/data/app/~~oMFEGBoML4tbSPBBEah5RQ==/app.gesso.android-vn5Sl0AXHKbWvevXMSpxQw==/base.apk"],nativeLibraryDirectories=[/data/app/~~oMFEGBoML4tbSPBBEah5RQ==/app.gesso.android-vn5Sl0AXHKbWvevXMSpxQw==/lib/x86, /data/app/~~oMFEGBoML4tbSPBBEah5RQ==/app.gesso.android-vn5Sl0AXHKbWvevXMSpxQw==/base.apk!/lib/x86, /system/lib, /system_ext/lib, /product/lib]]
dalvik.system.BaseDexClassLoader.findClass (BaseDexClassLoader.java:202)
java.lang.ClassLoader.loadClass (ClassLoader.java:312)
xyz.erick.ocarina.AssetOcarinaPlayer.extractMediaSourceFromUri (OcarinaPlugin.kt:131)
xyz.erick.ocarina.OcarinaPlayer.load (OcarinaPlugin.kt:89)
xyz.erick.ocarina.OcarinaPlugin.load (OcarinaPlugin.kt:209)
xyz.erick.ocarina.OcarinaPlugin.onMethodCall (OcarinaPlugin.kt:174)
io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage (MethodChannel.java:233)
io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart (DartMessenger.java:84)
io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage (FlutterJNI.java:822)
Seems like it may be caused by deprecation of ExtractorMediaSource
Hello, I was using your gapless sound plugin and wanted to know if this plugin also supports gapless looping sound? I had great results with previous plugin :)
Hi Erick - I'm trying to use the plugin you have written and cannot find a way to pass a single instance of the player with an asset already loaded to any widget in my tree (via lets say Provider).
If I try and create a simple class such as :
class CarinaPlayer {
final OcarinaPlayer carinaPlayer;
CarinaPlayer.fromCarinaPlayer(OcarinaPlayer player)
: carinaPlayer = player:
.. etc other methods that act on carinaPlayer
}
and use like this :
final player= OcarinaPlayer(asset: 'my asset file', loop: true);
await player.load();
var cp=CarinaPlayer.fromCarinaPlayer(player);
... and then we pass 'cp' to any widget in our tree etc ...
When I perform the lines above the player doesnt play , there are a few errors stating the that player needs to be initialised first and there is another strange error before this ''lateinit property context has not been initialized"
I tried to run the sample and this also doesnt work for me.
API Landroid/media/AudioTrack;->getLatency()I
72 occurrences identified. Only unique stack traces are shown.
StrictMode policy violation: android.os.strictmode.NonSdkApiUsedViolation: Landroid/media/AudioTrack;->getLatency()I
at android.os.StrictMode.lambda$static$1(StrictMode.java:407)
at android.os.-$$Lambda$StrictMode$lu9ekkHJ2HMz0jd3F8K8MnhenxQ.accept(Unknown Source:2)
at java.lang.Class.getDeclaredMethodInternal(Class.java)
at java.lang.Class.getPublicMethodRecursive(Class.java:2079)
at java.lang.Class.getMethod(Class.java:2066)
at java.lang.Class.getMethod(Class.java:1693)
at com.google.android.exoplayer2.audio.AudioTrackPositionTracker.<init>(AudioTrackPositionTracker.java:21)
at com.google.android.exoplayer2.audio.DefaultAudioSink.<init>(DefaultAudioSink.java:31)
at com.google.android.exoplayer2.audio.DefaultAudioSink.<init>(DefaultAudioSink.java:5)
at com.google.android.exoplayer2.audio.DefaultAudioSink.<init>(DefaultAudioSink.java:1)
at com.google.android.exoplayer2.DefaultRenderersFactory.a(DefaultRenderersFactory.java:20)
at com.google.android.exoplayer2.DefaultRenderersFactory.a(DefaultRenderersFactory.java:55)
at com.google.android.exoplayer2.SimpleExoPlayer.<init>(SimpleExoPlayer.java:81)
at com.google.android.exoplayer2.SimpleExoPlayer.<init>(SimpleExoPlayer.java:16)
at com.google.android.exoplayer2.SimpleExoPlayer$Builder.build(SimpleExoPlayer.java:28)
at xyz.erick.ocarina.OcarinaPlayer.load(OcarinaPlayer.java:7)
at xyz.erick.ocarina.OcarinaPlugin.onMethodCall(OcarinaPlugin.java:141)
at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:17)
at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:57)
at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:4)
at android.os.MessageQueue.nativePollOnce(MessageQueue.java)
at android.os.MessageQueue.next(MessageQueue.java:336)
at android.os.Looper.loop(Looper.java:174)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
StrictMode policy violation: android.os.strictmode.NonSdkApiUsedViolation: Landroid/media/AudioTrack;->getLatency()I
at android.os.StrictMode.lambda$static$1(StrictMode.java:428)
at android.os.-$$Lambda$StrictMode$lu9ekkHJ2HMz0jd3F8K8MnhenxQ.accept(Unknown Source:2)
at java.lang.Class.getDeclaredMethodInternal(Class.java)
at java.lang.Class.getPublicMethodRecursive(Class.java:2075)
at java.lang.Class.getMethod(Class.java:2063)
at java.lang.Class.getMethod(Class.java:1690)
at com.google.android.exoplayer2.audio.AudioTrackPositionTracker.<init>(AudioTrackPositionTracker.java:21)
at com.google.android.exoplayer2.audio.DefaultAudioSink.<init>(DefaultAudioSink.java:31)
at com.google.android.exoplayer2.audio.DefaultAudioSink.<init>(DefaultAudioSink.java:5)
at com.google.android.exoplayer2.audio.DefaultAudioSink.<init>(DefaultAudioSink.java:1)
at com.google.android.exoplayer2.DefaultRenderersFactory.a(DefaultRenderersFactory.java:20)
at com.google.android.exoplayer2.DefaultRenderersFactory.a(DefaultRenderersFactory.java:55)
at com.google.android.exoplayer2.SimpleExoPlayer.<init>(SimpleExoPlayer.java:81)
at com.google.android.exoplayer2.SimpleExoPlayer.<init>(SimpleExoPlayer.java:16)
at com.google.android.exoplayer2.SimpleExoPlayer$Builder.build(SimpleExoPlayer.java:28)
at xyz.erick.ocarina.OcarinaPlayer.load(OcarinaPlayer.java:7)
at xyz.erick.ocarina.OcarinaPlugin.onMethodCall(OcarinaPlugin.java:141)
at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:17)
at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:57)
at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:4)
at android.os.MessageQueue.nativePollOnce(MessageQueue.java)
at android.os.MessageQueue.next(MessageQueue.java:326)
at android.os.Looper.loop(Looper.java:160)
at android.app.ActivityThread.main(ActivityThread.java:6718)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Looks like the "volume" property doesn't affect the sound output on the device (tested on virtual and physic device).
Even when set to 0, the music keeps playing:
Future<OcarinaPlayer> play(Audio audio) async {
OcarinaPlayer op = OcarinaPlayer(
asset: DEFAULT_DIRECTORY + audio.file,
loop: audio.loop,
volume: 0);
await op.load();
await op.play;
return op;
}
Even calling updateVolume
doesn't do the trick
Unfortunately there are issues trying to run even the sample in Android.
E/flutter ( 4436): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: PlatformException(error, lateinit property context has not been initialized, null)
Hey Erick, thank you for this plugin. I can confirm so far testing in iOS it works perfectly and I have a gapless playback.
I use Ocarina in a custom AudioClass that has other functionality inbuilt. I would supply an asset to this custom class and call Ocarina methods to play/pause/resume accordingly.
To make better - would be great if :
1- You expose a method to check if the player is already loaded :
bool isLoaded(){
return (_id!=null);
}
This is required because no pause/play/resume etc method in Ocarina can be called unless the Player has been loaded and we need a way to instantiate and prepare Ocarina player if its used inside another class and the asset/filepath is supplied in the constructor of a custom class. ie.
class AudioLoop{
bool playMusic = false;
final String assetToPlay;
final OcarinaPlayer _audioPlayer;
AudioLoop({@required this.assetToPlay})
: _audioPlayer = OcarinaPlayer(asset: assetToPlay, loop: true) {
// Created but not loaded and you cannot call _audioPlayer.load() here
}
play({bool play: false}) async {
playMusic = play;
if (playMusic )
{
/// Would be better to have :
/// if (!_audioPlayer.isLoaded()){
///await _audioPlayer.load();
///}
await _audioPlayer.load();
_audioPlayer.play();
}
}
}
2- Unless you want to allow load() to be repeatably called, we optimise Load() so it checks if _id is null and only loads inits if this is the case :
Future<void> load() async {
if (_id!=null) return;
_id = await _channel.invokeMethod('load', {
'url': asset ?? filePath,
'volume': volume,
'loop': loop,
'isAsset': asset != null,
});
}
3- Add a dispose so we can cleanup resources
The sound is not playing. I am successfully able to get sound on iOS simulator, iPad Pro 2 and Android devices. I have completely reset my iPhone 7 just in case, but still no luck. I am also attaching the verbose log even though I see nothing suspicious there.
Is iPhone 7 actually supported at all? Anything else I should try to investigate this?
Add support for the Linux platform.
I know that all platforms are planned in the future, so this task issue more as a feature request as well as a way for people to follow later progress on the feature.
Excuse my extreme lack of GitHub etiquette, I'm sure this is the wrong way to go about this, but I made an update to the plugin that allows users to call position(), which functions in the same fashion as it does on audioPlayers, and also a "loops" parameter in the constructor that specifies how many loops the audioPlayer should go through.
Is this repo still active? Should I upload the files?
Hey,
I have downloaded and used Ocarina as you suggested and I can get local assets to play but when I pass it a local file it always fails with the following error:
NoSuchMethodError (NoSuchMethodError: The method 'play' was called on null.
Receiver: null
Tried calling: play())
Any idea what my issue may be, I am a newbie but I am definitely passing a valid local file path in the apps document directory. The Load file certainly does not complain either just the play command.
Thanks in advance
Alan
Add ocarina support for flutter web, and support all the current set of features supported on mobile.
Hi! there, Thank you for this plugin. I tried a lot of plugins but none of them support gapless loop. Finally tried ocarina and it worked. But I'm having a problem where I need whether the audio is playing or not. So is there any way I can get something like isPlaying?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.