在Codename One中开发音频播放器遇MediaManager问题求助
Codename One音频播放问题排查与解决建议
问题背景
我正在用Codename One将Java游戏移植到移动端,参考其他线程代码开发音频播放器时遇到诸多问题,核心集中在MediaManager的使用上。曾尝试将WAV格式音频转为MP3,以为是格式不被支持,但问题依旧。用几乎相同的方式读取游戏图片完全正常,本人编程经验有限,希望得到解决方向。
相关代码
AudioPlayer类代码
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(); } } }
实例化与调用代码
public AudioPlayer audioPlayer = new AudioPlayer(); //audio player public Game() { changeState(sceneNum); audioPlayer.playAudio(FileSystemStorage.getInstance().getAppHomePath() + "res/Sounds/fluffingADuck.wav"); // ... }
报错堆栈信息
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)
排查方向与解决建议
- 资源读取方式错误:FileSystemStorage访问的是设备文件系统,而项目内的资源文件(如res/Sounds下的音频)需要用
Display.getInstance().getResourceAsStream()读取,这也是图片能正常加载的原因——图片资源被框架自动处理了,而音频需要显式用资源流读取。 - MIME类型不匹配:代码中固定写了
"audio/mp3",但播放WAV时需要改为"audio/wav",即使转成MP3也要确认文件是标准MP3格式,避免转码不完整导致无法识别。 - 初始化时机过早:在Game构造函数中直接调用音频播放可能太早,MediaManager需要等Display完全初始化后才能正常工作。建议将播放逻辑放到
start()方法中,或者用Display.getInstance().callSerially()延迟执行。 - 资源打包配置:确认项目的资源打包规则是否包含了res/Sounds目录下的音频文件,避免资源未被打包到应用中。
修正后的示例代码
修改AudioPlayer的playAudio方法:
public void playAudio(String resourcePath) { try { if (MEDIA == null) { // 用getResourceAsStream读取项目内资源 InputStream is = Display.getInstance().getResourceAsStream(getClass(), "/" + resourcePath); // 根据实际音频格式设置MIME类型 MEDIA = MediaManager.createMedia(is, "audio/wav", () -> MEDIA = null); } if (MEDIA != null && !MEDIA.isPlaying()) { MEDIA.setVolume(100); MEDIA.play(); } } catch (IOException ioe) { ioe.printStackTrace(); } }
调用时简化路径:
audioPlayer.playAudio("res/Sounds/fluffingADuck.wav");
内容的提问来源于stack exchange,提问作者Stefan Cohn
相关产品推荐
相关产品推荐

