简体   繁体   English

javafxports如何调用android native Media Player

[英]javafxports how to call android native Media Player

As the javafxports Media is not yet implemented I'm looking to use the Android Native MediaPlayer instead. 由于尚未实现javafxports Media,因此我希望使用Android Native MediaPlayer。 Does anyone know how to do this. 有谁知道如何做到这一点。

If you have a look at the GoNative sample here ( docs and code ), you'll find a way to add Android native code to your JavaFX project. 如果您在此处查看GoNative示例( docscode ),您将找到一种将Android本机代码添加到JavaFX项目的方法。

This is a simple example of adding android.media.MediaPlayer to a JavaFX project using the Gluon plugin. 这是一个使用Gluon插件将android.media.MediaPlayer添加到JavaFX项目的简单示例。

Based on a Single View project, let's add first an interface with the required audio method signatures: 我们基于一个Single View项目,首先添加一个具有所需音频方法签名的接口:

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

Now in our View we can create the buttons to call those methods based on an instance of AndroidNativeAudio class that implements the NativeAudioService interface: 现在,在我们的视图中,我们可以基于实现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");
    }
}

Now, we create the native class under the Android folder. 现在,我们在Android文件夹下创建本机类。 It will make use of the android API. 它将利用android API。 It will try to find the audio file audio.mp3 that we have to place under the /src/android/assets folder: 它将尝试找到我们必须放置在/src/android/assets文件夹下的音频文件audio.mp3

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

Finally, we can deploy the project to an Android device running gradlew androidInstall . 最后,我们可以将项目部署到运行gradlew androidInstall的Android设备。

The native audio player was used in the following example: 在以下示例中使用了本机音频播放器:

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

Beside some prerequisites, the code looks like this: 除了一些先决条件外,代码如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM