Making audio player in Codename One

84 views Asked by At

I am porting a java game to mobile using Codename One, and have been trying to make an audio player with the framework using code from another thread. I'm running into lots of trouble doing so, mainly with using the MediaManager. Here is the code:

package com.example.audio;
import java.io.IOException;
import java.io.InputStream;

import com.codename1.io.FileSystemStorage;
import com.codename1.media.Media;
import com.codename1.media.MediaManager;
import com.codename1.ui.Display;

public class AudioPlayer {
    private Media MEDIA = null;
    public void playAudio(String fileName) {
        try {
            if (MEDIA == null) {
                InputStream is = FileSystemStorage.getInstance().openInputStream(fileName);
                MEDIA = MediaManager.createMedia(is, "audio/mp3", new Runnable() {
                    @Override
                    public void run() {
                        MEDIA = null;
                    }
                });
            }
            if (MEDIA != null && MEDIA.isPlaying() == false) {
                MEDIA.setVolume(100);
                MEDIA.play();
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
}

Class where AudioPlayer is instantiated:

public AudioPlayer audioPlayer = new AudioPlayer(); //audio player 

public Game() {
    changeState(sceneNum);
    audioPlayer.playAudio(FileSystemStorage.getInstance().getAppHomePath() + "res/Sounds/fluffingADuck.wav");
...

This is what the stack trace gives me

java.io.IOException
    at com.codename1.impl.javase.JavaSEPort.createMedia(JavaSEPort.java:9535)
    at com.codename1.ui.Display.createMedia(Display.java:3705)
    at com.codename1.media.MediaManager.createMedia(MediaManager.java:306)
    at com.example.audio.AudioPlayer.playAudio(AudioPlayer.java:16)
    at com.example.myapp.Game.<init>(Game.java:32)
    at com.example.myapp.Game.getGame(Game.java:41)
    at com.example.myapp.MyApp.runApp(MyApp.java:14)
    at com.codename1.system.Lifecycle.start(Lifecycle.java:129)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at com.codename1.impl.javase.Executor$3$2.run(Executor.java:340)
    at com.codename1.ui.Display.executeSerialCall(Display.java:1395)
    at com.codename1.ui.Display.processSerialCalls(Display.java:1379)
    at com.codename1.ui.Display.mainEDTLoop(Display.java:1166)
    at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
    at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)

Here is what the folder that holds the sounds looks like: My folder set up

I converted one of the sounds to mp3 because I thought maybe wav wasn't recognized by CN1 but that did not fix the issue either. I use pretty much the same method to retrieve images for the game and that works fine. Not sure what to do, if someone could point me in the right direction or give any assistance it would mean a lot. I'm still a bit of a noob at programming. Here is the github repo if anyone would want to take a look as well: https://github.com/stefancohn/DuckWorldMobile

1

There are 1 answers

4
Shai Almog On

It seems you're confusing FileSystemStorage with resources. Those are separate concepts. Resources like your sounds, get packaged into your application as part of the final bundle (e.g. jar) and are available to you on the device using an API to fetch the resources.

FileSystemStorage accesses the file system available on the device. Here you first need to write or create the file in some way in order for it to be available for you.

There are additional problems:

  • Your resources are in a hierarchy. This isn't supported by Codename One since some packaging systems (iOS) behave somewhat differently. So you can't nest the files and need to put them all in one directory.

  • You named the directory res instead of resources.

  • It needs to be under main next to the java and css directory

To clarify, the file fluffingADuck.wav must be in common/src/main/resources/fluffingADuck.wav for the following code to work.

Now you need to fix the code to use resources which is actually pretty simple:

audioPlayer.playAudio("/fluffingADuck.wav");

Notice the / in the beginning. It's intentional.

Then all you need to do is change the InputStream line to:

InputStream is = CN.getResourceAsStream(fileName);