javafxports如何调用android原生Media Player

时间:2016-07-17 09:11:39

标签: android javafx android-mediaplayer javafxports

由于javafxports Media尚未实现,我希望使用Android Native MediaPlayer。有谁知道怎么做。

2 个答案:

答案 0 :(得分:5)

如果您查看GoNative示例heredocscode),您将找到一种方法将Android本机代码添加到JavaFX项目中。< / p>

这是使用Gluon插件将public partial class Form1 : Form { static ConcurrentQueue<Image> buffer = new ConcurrentQueue<Image>(); static Random r = new Random(); public Form1() { InitializeComponent(); backgroundWorker1.RunWorkerAsync(); // this is already a great performance win ... DoubleBuffered = true; } private void Form1_Paint(object sender, PaintEventArgs e) { Image img =null; // get from buffer .. if (!buffer.TryDequeue(out img)) { // nothing available // direct random for (var x = 0; x < e.ClipRectangle.Width; x++) { for (var y = 0; y < e.ClipRectangle.Height; y++) { using (var pen = new Pen(new SolidBrush(Color.FromArgb(r.Next(255), r.Next(255), r.Next(255))))) { e.Graphics.DrawRectangle(pen, x, y, 1, 1); } } } } else { // otherwise Draw the prepared image e.Graphics.DrawImage(img,0,0); Trace.WriteLine(buffer.Count); img.Dispose(); } } private void button1_Click(object sender, EventArgs e) { // force a repaint of the Form Invalidate(); } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { // as long as the form is not disposed while (!IsDisposed) { // we keep 60 images in memory if (buffer.Count < 60) { // bitmap var bmp = new Bitmap(this.Width, this.Height); var img = Graphics.FromImage(bmp); // draw for (int i = 0; i < 3600; i++) { using (var pen = new Pen(new SolidBrush(Color.FromArgb(r.Next(255), r.Next(255), r.Next(255))))) { img.DrawRectangle(pen, r.Next(Width),r.Next(Height), r.Next(Width), r.Next(Height)); } } // store the drawing in the buffer buffer.Enqueue(bmp); } else { // simple and naive way to give other threads a bit of room Thread.Sleep(0); } } } } 添加到JavaFX项目的简单示例。

基于Single View项目,我们首先添加一个带有所需音频方法签名的界面:

android.media.MediaPlayer

现在,在我们的视图中,我们可以创建按钮,根据实现public interface NativeAudioService { void play(); void pause(); void resume(); void stop(); } 接口的AndroidNativeAudio类实例调用这些方法:

NativeAudioService

现在,我们在Android文件夹下创建本机类。它将使用android API。它会尝试找到我们必须放在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"); } } 文件夹下的音频文件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); } } }

的Android设备

答案 1 :(得分:1)

以下示例中使用了原生音频播放器:

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