001: /*
002: * Copyright (c) 2007, Sun Microsystems, Inc.
003: *
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * * Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: * * Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in
014: * the documentation and/or other materials provided with the
015: * distribution.
016: * * Neither the name of Sun Microsystems, Inc. nor the names of its
017: * contributors may be used to endorse or promote products derived
018: * from this software without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
023: * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
024: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032: package example.mmademo;
033:
034: import javax.microedition.midlet.*;
035: import javax.microedition.lcdui.*;
036: import javax.microedition.media.*;
037: import javax.microedition.media.control.*;
038: import java.io.*;
039:
040: /**
041: * Play Video/Capture in a Form using MMAPI
042: *
043: */
044: public class VideoPlayer extends Form implements Runnable,
045: CommandListener, PlayerListener {
046:
047: private static final String TITLE_TEXT = "MMAPI Video Player";
048:
049: private static Player player = null;
050: private static boolean isCapturePlayer;
051:
052: private static Image logo = null;
053: private int idx = 0;
054: private Display parentDisplay;
055: private long duration;
056: private final Command backCommand = new Command("Back",
057: Command.BACK, 1);
058: private final Command playCommand = new Command("Play",
059: Command.ITEM, 1);
060: private final Command snapCommand = new Command("Snapshot",
061: Command.ITEM, 1);
062: private final Command pauseCommand = new Command("Pause",
063: Command.ITEM, 10);
064: private Item videoItem;
065: private StringItem status;
066: private StringItem audioStatus;
067: private StringItem time;
068: private VolumeControl vc;
069: private RateControl rc;
070: private Thread th;
071: private int currentVolume;
072: private boolean muted;
073: private int currentRate = 100000;
074: private VideoControl vidc;
075:
076: // pause/resume support
077: private boolean suspended = false;
078: private boolean restartOnResume = false;
079: private long restartMediaTime;
080:
081: public VideoPlayer(Display parentDisplay) {
082: super (TITLE_TEXT);
083: this .idx = 0;
084: this .parentDisplay = parentDisplay;
085: initialize();
086: }
087:
088: void initialize() {
089: addCommand(backCommand);
090: addCommand(snapCommand);
091: setCommandListener(this );
092:
093: try {
094: if (logo == null)
095: logo = Image.createImage("/icons/logo.png");
096: } catch (Exception ex) {
097: logo = null;
098: }
099: if (logo == null)
100: System.out.println("can not load logo.png");
101:
102: }
103:
104: /*
105: * Respond to commands, including back
106: */
107: public void commandAction(Command c, Displayable s) {
108: //try {
109: if (s == this ) {
110: if (c == backCommand) {
111: close();
112: parentDisplay.setCurrent(VideoTest.getList());
113: } else if (videoItem != null && c == snapCommand) {
114: doSnapshot();
115: } else if (videoItem == null && c == pauseCommand) {
116: removeCommand(pauseCommand);
117: addCommand(playCommand);
118: pause();
119: } else if (videoItem == null && c == playCommand) {
120: start();
121: removeCommand(playCommand);
122: addCommand(pauseCommand);
123: }
124: }
125: //} catch (Exception e) {
126: // System.out.println("DEBUG: GOT EXCEPTION in VideoPlayer.commandAction("+c.toString()+","+s.toString()+")!");
127: // e.printStackTrace();
128: //}
129: }
130:
131: public void run() {
132: //try {
133: while (player != null) {
134:
135: // sleep 200 millis. If suspended,
136: // sleep until MIDlet is restarted
137: do {
138: try {
139: Thread.sleep(200);
140: } catch (InterruptedException ie) {
141: }
142: } while (player != null && suspended);
143:
144: synchronized (this ) {
145: if (player == null)
146: return;
147: if (vc != null) {
148: if (vc.getLevel() != currentVolume
149: || vc.isMuted() != muted) {
150: muted = vc.isMuted();
151: currentVolume = vc.getLevel();
152: audioStatus.setText("Volume: " + currentVolume
153: + "% " + (muted ? " (muted)" : ""));
154: }
155: }
156: if (rc != null) {
157: if (rc.getRate() != currentRate) {
158: currentRate = rc.getRate();
159: updateStatus();
160: }
161: }
162: long k = player.getMediaTime();
163: time.setText("Pos: " + (k / 1000000) + "."
164: + ((k / 10000) % 100));
165: }
166: }
167: //} catch (Exception e) {
168: // System.out.println("DEBUG: GOT EXCEPTION in VideoPlayer.run()!");
169: // e.printStackTrace();
170: //}
171: }
172:
173: public void open(String url) {
174: try {
175: synchronized (this ) {
176: if (player == null) {
177: if (url.startsWith("resource:")) {
178: InputStream ins = getClass()
179: .getResourceAsStream(url.substring(9));
180: String ct = Utils.guessContentType(url);
181: player = Manager.createPlayer(ins, ct);
182: } else {
183: player = Manager.createPlayer(url);
184: }
185: player.addPlayerListener(this );
186: isCapturePlayer = url.startsWith("capture:");
187: }
188: }
189: player.realize();
190: if ((vidc = (VideoControl) player
191: .getControl("VideoControl")) != null) {
192: videoItem = (Item) vidc.initDisplayMode(
193: VideoControl.USE_GUI_PRIMITIVE, null);
194: //vidc.setDisplaySize(240, 140);
195: } else if (logo != null) {
196: append(new ImageItem("", logo, ImageItem.LAYOUT_CENTER,
197: ""));
198: }
199: Control[] controls = player.getControls();
200:
201: for (int i = 0; i < controls.length; i++) {
202: if (controls[i] instanceof GUIControl
203: && controls[i] != vidc) {
204: append((Item) controls[i]);
205: }
206: if (controls[i] instanceof VolumeControl) {
207: vc = (VolumeControl) controls[i];
208: }
209: if (controls[i] instanceof RateControl) {
210: rc = (RateControl) controls[i];
211: }
212: }
213: status = new StringItem("Status: ", "");
214: status.setLayout(Item.LAYOUT_NEWLINE_AFTER);
215: append(status);
216: if (vc != null) {
217: audioStatus = new StringItem("", "Volume:");
218: audioStatus.setLayout(Item.LAYOUT_NEWLINE_AFTER);
219: append(audioStatus);
220: }
221: time = new StringItem("", "");
222: time.setLayout(Item.LAYOUT_NEWLINE_AFTER);
223: append(time);
224: player.prefetch();
225: if (videoItem == null)
226: addCommand(pauseCommand);
227: else {
228: Spacer spacer = new Spacer(3, 10);
229: spacer.setLayout(Item.LAYOUT_NEWLINE_BEFORE);
230: append(spacer);
231: append(videoItem);
232: }
233: Thread t = new Thread(this );
234: t.start();
235: } catch (Exception me) {
236: System.err.println(me);
237: close();
238: }
239: }
240:
241: public void start() {
242: if (player == null)
243: return;
244: try {
245: duration = player.getDuration();
246: player.start();
247: } catch (Exception ex) {
248: System.err.println(ex);
249: close();
250: }
251: }
252:
253: public void close() {
254: synchronized (this ) {
255: pause();
256: if (player != null) {
257: player.close();
258: player = null;
259: }
260: }
261: VideoTest.getInstance().nullPlayer();
262: }
263:
264: public void pause() {
265: if (player != null) {
266: try {
267: player.stop();
268: } catch (MediaException me) {
269: System.err.println(me);
270: }
271: }
272: }
273:
274: private synchronized void updateStatus() {
275: if (player == null)
276: return;
277: status
278: .setText(((player.getState() == Player.STARTED) ? "Playing, "
279: : "Paused, ")
280: + "Rate: " + (currentRate / 1000) + "%\n");
281: }
282:
283: public void playerUpdate(Player plyr, String evt, Object evtData) {
284: //try {
285: if (evt == END_OF_MEDIA) {
286: try {
287: player.setMediaTime(0);
288: player.start();
289: } catch (MediaException me) {
290: System.err.println(me);
291: }
292: } else if (evt == STARTED || evt == STOPPED) {
293: updateStatus();
294: }
295: //} catch (Exception e) {
296: // System.out.println("DEBUG: GOT EXCEPTION in VideoPlayer.playerUpdate("+evt.toString()+")!");
297: // e.printStackTrace();
298: //}
299: }
300:
301: private void doSnapshot() {
302: new SnapshotThread().start();
303: }
304:
305: class SnapshotThread extends Thread {
306: public void run() {
307: try {
308: byte[] snap = vidc.getSnapshot("encoding=jpeg");
309: if (snap != null) {
310: Image im = Image.createImage(snap, 0, snap.length);
311: ImageItem imi = new ImageItem("", im, 0, "");
312: append(imi);
313: }
314: } catch (MediaException me) {
315: System.err.println(me);
316: //} catch (Exception e) {
317: // System.out.println("DEBUG: GOT EXCEPTION in VideoPlayer.SnapshotThread.run()!");
318: // e.printStackTrace();
319: }
320: }
321: }
322:
323: public synchronized void stopVideoPlayer() {
324: // stop & deallocate
325: player.deallocate();
326: }
327:
328: /**
329: * Deallocate the player and the display thread.
330: * Some VM's may stop players and threads
331: * on their own, but for consistent user
332: * experience, it's a good idea to explicitly
333: * stop and start resources such as player
334: * and threads.
335: */
336: public synchronized void pauseApp() {
337: suspended = true;
338: if (player != null && player.getState() >= Player.STARTED) {
339: // player was playing, so stop it and release resources.
340: if (!isCapturePlayer) {
341: restartMediaTime = player.getMediaTime();
342: }
343: try {
344: player.stop();
345: } catch (MediaException me) {
346: // me.printStackTrace();
347: // fall through
348: }
349:
350: // make sure to restart upon resume
351: restartOnResume = true;
352: } else {
353: restartOnResume = false;
354: }
355: }
356:
357: /**
358: * If the player was playing when the MIDlet was paused,
359: * then the player will be restarted here.
360: */
361: public synchronized void startApp() {
362: suspended = false;
363: if (player != null && restartOnResume) {
364: try {
365: if (!isCapturePlayer) {
366: try {
367: player.setMediaTime(restartMediaTime);
368: } catch (MediaException me) {
369: System.err.println(me);
370: }
371: }
372: player.start();
373: } catch (MediaException me) {
374: System.err.println(me);
375: }
376: }
377: restartOnResume = false;
378: }
379: }
|