javafxports如何调用android本地媒体播放器

由于javafxports媒体尚未实现,我正在寻找使用Android本机MediaPlayer来代替。 有谁知道如何做到这一点。

如果你看一下这里的GoNative示例( 文档和代码 ),你会发现一种方法来添加Android本地代码到你的JavaFX项目。

这是一个简单的例子,通过使用Gluon插件将android.media.MediaPlayer添加到JavaFX项目中。

基于Single View项目,我们首先添加一个带有所需audio方法签名的接口:

 public interface NativeAudioService { void play(); void pause(); void resume(); void stop(); } 

现在在我们的视图中,我们可以创buildbutton来调用那些基于实现NativeAudioService接口的AndroidNativeAudio类的实例的方法:

 public class BasicView extends View { private NativeAudioService service; private boolean pause; public BasicView(String name) { super(name); try { service = (NativeAudioService) Class.forName("com.gluonhq.nativeaudio.AndroidNativeAudio").newInstance(); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) { System.out.println("Error " + ex); } if (service != null) { final HBox hBox = new HBox(10, MaterialDesignIcon.PLAY_ARROW.button(e -> service.play()), MaterialDesignIcon.PAUSE.button(e -> { if (!pause) { service.pause(); pause = true; } else { service.resume(); pause = false; } }), MaterialDesignIcon.STOP.button(e -> service.stop())); hBox.setAlignment(Pos.CENTER); setCenter(new StackPane(hBox)); } else { setCenter(new StackPane(new Label("Only for Android"))); } } @Override protected void updateAppBar(AppBar appBar) { appBar.setNavIcon(MaterialDesignIcon.MUSIC_NOTE.button()); appBar.setTitleText("Native Audio"); } } 

现在,我们在Android文件夹下创build本地类。 它会利用android API。 它会尝试findaudio文件audio.mp3 ,我们必须放置在/src/android/assets文件夹下:

 package com.gluonhq.nativeaudio; import android.content.res.AssetFileDescriptor; import android.media.AudioManager; import android.media.MediaPlayer; import java.io.IOException; import javafxports.android.FXActivity; public class AndroidNativeAudio implements NativeAudioService { private MediaPlayer mp; private int currentPosition; public AndroidNativeAudio() { } @Override public void play() { currentPosition = 0; try { if (mp != null) { stop(); } mp = new MediaPlayer(); AssetFileDescriptor afd = FXActivity.getInstance().getAssets().openFd("audio.mp3"); mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); mp.setAudioStreamType(AudioManager.STREAM_RING); mp.setOnCompletionListener(mp -> stop()); mp.prepare(); mp.start(); } catch (IOException e) { System.out.println("Error playing audio resource " + e); } } @Override public void stop() { if (mp != null) { if (mp.isPlaying()) { mp.stop(); } mp.release(); mp = null; } } @Override public void pause() { if (mp != null) { mp.pause(); currentPosition = mp.getCurrentPosition(); } } @Override public void resume() { if (mp != null) { mp.start(); mp.seekTo(currentPosition); } } } 

最后,我们可以将项目部署到运行gradlew androidInstall的Android设备上。

在以下示例中使用了本地audio播放器:

https://gist.github.com/bgmf/d87a2bac0a5623f359637a3da334f980

除了一些先决条件,代码如下所示:

 package my.application; import my.application.Constants; import javafx.beans.property.ReadOnlyObjectProperty; import javafx.beans.property.ReadOnlyObjectWrapper; import org.robovm.apple.avfoundation.AVAudioPlayer; import org.robovm.apple.foundation.NSErrorException; import org.robovm.apple.foundation.NSURL; import org.robovm.apple.foundation.NSURLScheme; import java.io.File; import java.util.logging.Level; import java.util.logging.Logger; public class NativeAudioServiceIOS extends PathHelperIOS implements NativeAudioService { private static final Logger LOG = Logger.getLogger(NativeAudioServiceIOS.class.getName()); private static final String DIR_NAME = Constants.OBJECTS_BASE_PATH; private final ReadOnlyObjectWrapper<Status> status = new ReadOnlyObjectWrapper<>(this, "status", Status.STOP); private String filename = null; private AVAudioPlayer player = null; public NativeAudioServiceIOS() { super(); } @Override public void init(String filename) throws NativeServiceException { this.filename = filename.startsWith("/") ? filename.substring(1) : filename; LOG.warning("Called with file: " + filename); status.set(Status.STOP); try { if(!filename.startsWith("/")) filename = "/" + filename; File fullfile = new File(pathBase.getAbsolutePath() + filename); if(fullfile.exists()) { NSURL fullurl = new NSURL(NSURLScheme.File, "", fullfile.getAbsolutePath()); LOG.log(Level.SEVERE, "Loading URL: " + fullurl); // Create audio player object and initialize with URL to sound player = new AVAudioPlayer(fullurl); LOG.log(Level.SEVERE, "Player initialized: " + player); status.set(Status.STOP); } else { LOG.log(Level.WARNING, String.format("Audiofile doesn't exist: %s (%s / %s)", fullfile.getAbsolutePath(), pathBase.getAbsolutePath(), filename)); player = null; status.set(Status.ERROR); } } catch(NSErrorException error) { LOG.log(Level.SEVERE, "Audio Setup Failed: " + error.toString(), error); status.set(Status.ERROR); } } @Override public void play() throws NativeServiceException { if(player == null) return; player.play(); status.set(Status.PLAY); } @Override public void pause() throws NativeServiceException { if(player == null) return; player.pause(); status.set(Status.PAUSE); } @Override public void resume() throws NativeServiceException { if(player == null) return; player.play(); status.set(Status.PLAY); } @Override public void stop() throws NativeServiceException { if(player == null) return; player.stop(); player.setCurrentTime(0.0); status.set(Status.STOP); } @Override public ReadOnlyObjectProperty<Status> statusProperty() { return status.getReadOnlyProperty(); } @Override public Status getStatus() { return status.get(); } }