« 前一篇:《一个陌生女人的来信》
后一篇:J2ME最佳实践 »

Mobile Media API(MMAPI) @ 3/27/2006

技术类
MMAPI是JSR 135: Mobile Media API提供的一套规范的播放和录制音频或视频接口。

MMAPI框架:(from: developers.sun.com)


Manager类(javax.microedition.media.Manager),用于创建各种不同类型的Players,获得各种支持协议和内容格式,播放简单的曲调等。

Manager根据createPlayer函数的参数创建一个Data Source对象,由该对象完成对媒体数据的传输工作,并从数据中获取该媒体的数据内容类型,然后根据这个媒体数据类型创建相应的Player对象,如果Manager无法确定DataSource的内容类型,它将抛出一个MediaException异常:
// public static Player Manager.createPlayer(String locator) throws IOException, MediaException
// public static Player Manager.createPlayer(DataSource source) throws IOException, MediaException
// public static Player Manager.createPlayer(InputStream stream, String type) throws IOException, MediaException
try {
    Player p = Manager.createPlayer("http://webserver/music.mp3");
    p.setLoopCount(5);
    p.start();
} catch (IOException ioe) {
} catch (MediaException me) {
}

获取手机支持的协议和媒体类型:
// static java.lang.String[] Manager.getSupportedProtocols(java.lang.String content_type)
// static java.lang.String[] Manager.getSupportedContentTypes(java.lang.String protocol)

播放简单声调:
// static void playTone(int note, int duration, int volume)
try {
    Manager.playTone(ToneControl.C4, 5000 /* millisec */, 100 /* max vol */);
    // ToneControl.C4 中音C
    // ToneControl.SILENCE 不发声
} catch (MediaException e) {
}


MMAPI使用Player来处理媒体数据内容。Player是javax.microedition.media.Player接口的实现实例,它从Data Source中读取媒体数据、解析和解码数据以及识别媒体输出设备和传送媒体数据到输出设备等。

Player提供了一套方法去控制媒体的重放和同步:
Player.start():重放媒体流。
Player.stop():停止媒体流。
Player.setMediaTime(long now):设置媒体时间。
Player.close():关闭媒体流并释放资源。
Player.getState():获取Player的当前状态:


详细重放控制:
static final long SECS_TO_MICROSECS = 1000000L;
Player p;
VolumeControl vc;
try {
    p = Manager.createPlayer("http://webserver/music.mp3");
    p.realize();
    // Set a listener.
    p.addPlayerListener(new Listener());
    // Grab volume control for the player.
    // Set Volume to max.
    vc = (VolumeControl)p.getControl("VolumeControl");
    if (vc != null) {
        vc.setLevel(100);
    }
    // Set a start time.
    p.setMediaTime(5 * SECS_TO_MICROSECS);
    // Guarantee that the player can start with the smallest latency.
    p.prefetch();
    // Non-blocking start
    p.start();
} catch (IOException ioe) {
} catch (MediaException me) {
}

class Listener implements PlayerListener {
    public void playerUpdate(Player p, String event, Object eventData) {
        if (event == END_OF_MEDIA || event == STOPPED_AT_TIME) {
            System.out.println("Done processing");
            try {
                p.setMediaTime(5 * SECS_TO_MICROSECS);
                p.start();
            } catch (MediaException me) {
            }
        }
    }
}

播放RMS内存储的数据:
RecordStore rs;
int recordID;
// code to set up the record store.
try {
    InputStream is = new ByteArrayInputStream(rs.getRecord(recordID));
    Player p = Manager.createPlayer(is, "audio/X-wav");
    p.start();
} catch (IOException ioe) {
} catch (MediaException me) {
}

播放Jar文件中存储的媒体:
/** Notice that in MIDP 2.0, the wav format is mandatory only */
/** in the case that the device supports sampled audio.      */
try {
    InputStream is = getClass().getResourceAsStream("audio.wav");
    Player p = Manager.createPlayer(is, "audio/X-wav");
    p.start();
} catch (IOException ioe) {
} catch (MediaException me) {
}

不同Player的同步:
Player p1, p2;

try {
    p1 = Manager.createPlayer("http://webserver/tune.mid");
    p1.realize();
    p2 = Manager.createPlayer("http://webserver/movie.mpg");
    p2.realize();
    p2.setTimeBase(p1.getTimeBase());
    p1.prefetch();
    p2.prefetch();
    p1.start();
    p2.start();
} catch (IOException ioe) {
} catch (MediaException me) {
}


MMAPI还提供了一个或多个Controls来调整player的行为,可以在player从媒体转换数据的时候从player实例取得并且使用Controls。我们可以通过Player中提供的一些特殊的Controls访问一些特殊的媒体类型。Controls由javax.microedition.media.Control接口实现。

实现MIDI重放控制:
Player p;
TempoControl tc;

try {
    p = Manager.createPlayer("http://webserver/tune.mid");
    p.realize();
    // Grab the tempo control.
    tc = (TempoControl)p.getControl("TempoControl");
    tc.setTempo(120000); // 120 beats/min
    p.start();
} catch (IOException ioe) {
} catch (MediaException me) {
}

视频重放功能实现:
Player p;
VideoControl vc;

try {
    p = Manager.createPlayer("http://webserver/movie.mpg");
    p.realize();
    // Grab the video control and set it to the current display.
    vc = (VideoControl)p.getControl("VideoControl");
    if (vc != null) {
        Form form = new Form("video");
        form.append((Item)vc.initDisplayMode(vc.USE_GUI_PRIMITIVE, null));
        Display.getDisplay(midlet).setCurrent(form);
    }
    p.start();
} catch (IOException ioe) {
} catch (MediaException me) {
}

产生单音序列:
byte tempo = 30; // set tempo to 120 bpm
byte d = 8;      // eighth-note

byte C4 = ToneControl.C4;;
byte D4 = (byte)(C4 + 2); // a whole step
byte E4 = (byte)(C4 + 4); // a major third
byte G4 = (byte)(C4 + 7); // a fifth
byte rest = ToneControl.SILENCE; // rest

byte[] mySequence = {
    ToneControl.VERSION, 1,  // version 1
    ToneControl.TEMPO, tempo, // set tempo
    ToneControl.BLOCK_START, 0,  // start define "A" section
    E4,d, D4,d, C4,d, E4,d,      // content of "A" section
    E4,d, E4,d, E4,d, rest,d,         
    ToneControl.BLOCK_END, 0,    // end define "A" section
    ToneControl.PLAY_BLOCK, 0,    // play "A" section
    D4,d, D4,d, D4,d, rest,d,    // play "B" section
    E4,d, G4,d, G4,d, rest,d,
    ToneControl.PLAY_BLOCK, 0,    // repeat "A" section
    D4,d, D4,d, E4,d, D4,d, C4,d  // play "C" section
};

try{
    Player p = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);
    p.realize();
    ToneControl c = (ToneControl)p.getControl("ToneControl");
    c.setSequence(mySequence);
    p.start();
} catch (IOException ioe) {
} catch (MediaException me) {
}

语音捕获和录音功能的实现:
try {
    // Create a DataSource that captures live audio.
    Player p = Manager.createPlayer("capture://audio");
    p.realize();
    // Get the RecordControl, set the record location, and
    // start the Player and record for 5 seconds.
    RecordControl rc = (RecordControl)p.getControl("RecordControl");
    rc.setRecordLocation("file:/tmp/audio.wav");
    rc.startRecord();
    p.start();
    Thread.currentThread().sleep(5000);
    p.stop();
    rc.stopRecord();
    rc.commit();
} catch (IOException ioe) {
} catch (MediaException me) {
} catch (InterruptedException e) {
}

实现摄像功能:
Player p;
VideoControl vc;

// initialize camera
try {
    p = Manager.createPlayer("capture://video");
    p.realize();
    //Grab the video control and set it to the current display.
    vc = (VideoControl)(p.getControl("VideoControl"));
    if(videoControl != null) {
        vc.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, this);
        // show camera
        p.start();
        vc.setVisible(true);
        // now take a picture
      byte[] pngImage = vc.getSnapshot(null);
      Image image = Image.createImage(pngImage, 0, pngImage.length);
    }
} catch(IOException ioe) {
} catch(MediaException me) {
} catch(SecurityException se) {
} finally {
    if(player != null) {
        player.close();
        player = null;
    }
    videoControl = null;
}
发布于 3/27/2006 23:07:55 | 评论:3
julia @ 4/7/2006 17:38:09
错误同学开始研究mobile的咚咚了?
吴雨 @ 4/9/2006 2:33:06
从吴雨同学的表现看来,是这样子di~
<匿名人士> @ 2/3/2007 12:07:17
hi i want code for getting continous value from microphone using
j2me pls send code to my mail id


pamadhan@mepcoeng.ac.in

看帖要回帖...

categories
archives
links
statistics
  • 网志数:1170
  • 评论数:2013