android javafx android-mediaplayer javafxports

javafxports cómo llamar a Media Player nativo de Android



android-mediaplayer (2)

Si echas un vistazo al ejemplo de GoNative aquí ( documentos y código ), encontrarás una forma de agregar código nativo Android a tu proyecto JavaFX.

Este es un ejemplo simple de agregar android.media.MediaPlayer a un proyecto JavaFX usando el plugin Gluon.

Basado en un proyecto de Vista única, agreguemos primero una interfaz con las firmas de método de audio requeridas:

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

Ahora en nuestra vista podemos crear los botones para llamar a esos métodos en función de una instancia de AndroidNativeAudio clase AndroidNativeAudio que implementa la interfaz NativeAudioService :

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"); } }

Ahora, creamos la clase nativa en la carpeta de Android. Hará uso de la API de Android. audio.mp3 encontrar el archivo de audio audio.mp3 que tenemos que colocar debajo de la carpeta /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); } } }

Finalmente, podemos implementar el proyecto en un dispositivo Android con gradlew androidInstall .

Como los medios de comunicación javafxports todavía no están implementados, estoy buscando utilizar el MediaPlayer nativo de Android. Alguien sabe como hacer esto.


El reproductor de audio nativo se usó en el siguiente ejemplo:

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

Además de algunos prerrequisitos, el código se ve así:

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(); } }