📄 qdvideoplayer.java
字号:
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.ImageItem;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.Spacer;
import javax.microedition.lcdui.StringItem;
import javax.microedition.media.Control;
import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;
import javax.microedition.media.PlayerListener;
import javax.microedition.media.control.GUIControl;
import javax.microedition.media.control.VideoControl;
/**
* Play Video/Capture in a Form using MMAPI
*
*/
public class QDVideoPlayer extends Form implements Runnable, CommandListener,
PlayerListener {
private static final String TITLE_TEXT = "MMAPI Video Player";
private Display parentDisplay;
private StringItem time;
private StringItem status;
private Item videoItem;
private ImageItem imageItem;
private final Command backCommand = new Command("Back", Command.BACK, 1);
private final Command playCommand = new Command("Play", Command.ITEM, 1);
private final Command snapCommand = new Command("Snapshot", Command.ITEM, 1);
private final Command pauseCommand = new Command("Pause", Command.ITEM, 10);
private static Player player = null;
private VideoControl vidc;
private static boolean isCapturePlayer;
private boolean suspended = false;
private boolean restartOnResume = false;
private long restartMediaTime;
private int currentRate = 100000;
int iii=0;
public QDVideoPlayer(Display parentDisplay) {
super(TITLE_TEXT);
this.parentDisplay = parentDisplay;
addCommand(backCommand);
addCommand(snapCommand);
setCommandListener(this);
}
/**
* Called by MIDlet after instantiating this object. Creates the player.
*/
public void open(String url) { // capture://video theCamera
System.out.println("QDVideoPlayer:open()");
try {
synchronized (this) {
if (player == null) {
player = Manager.createPlayer(url); // creating player for
// the url
player.addPlayerListener(this);
isCapturePlayer = url.startsWith("capture:");
}
}
player.realize();
// set to use_gui_primitive
if ((vidc = (VideoControl) player.getControl("VideoControl")) != null) {
videoItem = (Item) vidc.initDisplayMode(
VideoControl.USE_GUI_PRIMITIVE, null);
}
Control[] controls = player.getControls();
for (int i = 0; i < controls.length; i++) {
if (controls[i] instanceof GUIControl && controls[i] != vidc) {
append((Item) controls[i]);
}
}
status = new StringItem("Status: ", "");
status.setLayout(Item.LAYOUT_NEWLINE_AFTER);
append(status);
time = new StringItem("", "");
time.setLayout(Item.LAYOUT_NEWLINE_AFTER);
append(time);
player.prefetch();
if (videoItem != null) {
// addCommand(pauseCommand);
Spacer spacer = new Spacer(3, 10);
spacer.setLayout(Item.LAYOUT_NEWLINE_BEFORE);
append(spacer);
append(videoItem); // append the videoItem, if don't append, snapShot will get blank screen
}
} catch (Exception ex) {
error(ex);
ex.printStackTrace();
close();
}
}
/*
* Respond to commands, including back
*/
public void commandAction(Command c, Displayable s) {
if (s == this) {
if (c == backCommand) {
close();
parentDisplay.setCurrent(QDVideoTest.getList());
} else if (videoItem != null && c == snapCommand) {
doSnapshot();
} else if (videoItem != null && c == pauseCommand) {
removeCommand(pauseCommand);
addCommand(playCommand);
pause();
} else if (videoItem != null && c == playCommand) {
start();
removeCommand(playCommand);
addCommand(pauseCommand);
}
}
}
public void run() {
System.out.println("QDVideoPlayer:run()");
while (player != null) {
synchronized (this) {
doSnapshot();
updateStatus();
}
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {}
}// while
}
public void playerUpdate(Player plyr, String evt, Object evtData) {
if (evt == END_OF_MEDIA) { // loop around playing forever
try {
player.setMediaTime(0);
player.start();
} catch (MediaException me) {
System.err.println(me);
}
} else if (evt == STARTED || evt == STOPPED || evt == DURATION_UPDATED) {
updateStatus();
}
}
private synchronized void updateStatus() {
if (player == null)
return;
status.setText(((player.getState() == Player.STARTED) ? "Playing, "
: "Paused, ")
+ "Rate: " + (currentRate / 1000) + "%\n");
long k = player.getMediaTime();
long duration = player.getDuration();
time.setText("duration: " + duration + " Pos: " + (k / 1000000) + "."
+ ((k / 10000) % 100));
}
// general purpose error method, displays on screen as well to output
public void error(Exception e) {
Alert alert = new Alert("Error");
alert.setString(e.getMessage());
parentDisplay.setCurrent(alert);
e.printStackTrace();
}
public void error(String s) {
Alert alert = new Alert("Error");
alert.setString(s);
alert.setTimeout(2000);
parentDisplay.setCurrent(alert, this);
}
public void start() {
System.out.println("QDVideoPlayer:start()");
if (player == null)
return;
try {
player.start(); // without this will get black square
Thread t = new Thread(this);
t.start(); // 循环帧处理
} catch (Exception ex) {
System.err.println(ex);
error(ex);
close();
}
}
public void close() {
synchronized (this) {
pause();
if (player != null) {
player.close();
player = null;
}
}
// QDVideoTest.getInstance().nullPlayer();
}
public void pause() {
if (player != null) {
try {
player.stop();
} catch (MediaException me) {
System.err.println(me);
}
}
}
/**
* If the player was playing when the MIDlet was paused, then the player
* will be restarted here.
*/
public synchronized void startApp() {
suspended = false;
if (player != null && restartOnResume) {
try {
player.prefetch();
if (!isCapturePlayer) {
try {
player.setMediaTime(restartMediaTime);
} catch (MediaException me) {
System.err.println(me);
}
}
player.start();
} catch (MediaException me) {
System.err.println(me);
}
}
restartOnResume = false;
}
/**
* Deallocate the player and the display thread. Some VM's may stop players
* and threads on their own, but for consistent user experience, it's a good
* idea to explicitly stop and start resources such as player and threads.
*/
public synchronized void pauseApp() {
suspended = true;
if (player != null && player.getState() >= Player.STARTED) {
// player was playing, so stop it and release resources.
if (!isCapturePlayer) {
restartMediaTime = player.getMediaTime();
}
player.deallocate();
// make sure to restart upon resume
restartOnResume = true;
} else {
restartOnResume = false;
}
}
public synchronized void stopVideoPlayer() {
// stop & deallocate
player.deallocate();
}
/**
* Initiates the snapshot.
*/
private void doSnapshot() {
System.out.println("VideoPlayer:doSnapshot()");
new SnapshotThread().start();
}
/**
* Inner class Snapshot which is a thread. Performs image processing and
* then appends to this form.
*/
class SnapshotThread extends Thread {
public void run() {
try {
byte[] snap = vidc.getSnapshot("encoding=jpeg"); // use this
// for sun
// WTK
// emulator
// byte [] snap =
// vidc.getSnapshot("encoding=jpeg&width=100&height=100"); //use
// this for N93 real device
if (snap != null) {
Image im = Image.createImage(snap, 0, snap.length);
// start imageProcessing
int imgCols = im.getWidth();
int imgRows = im.getHeight();
int[] oneDPix = new int[imgCols * imgRows];
im.getRGB(oneDPix, 0, imgCols, 0, 0, imgCols, imgRows);
int[][][] threeDPix = convertToThreeDim(oneDPix, imgCols,
imgRows);
for(int k=31;--k>=0;) {
for (int j=imgRows;--j>=0;) {
for(int i=imgCols;--i>=0;) {
threeDPix[j][i][0]=255-threeDPix[j][i][0];
threeDPix[j][i][1]=255-threeDPix[j][i][1];
threeDPix[j][i][2]=255-threeDPix[j][i][2];
}
}
}
int[] snap2 = convertToOneDim(threeDPix, imgCols, imgRows);
im = Image.createRGBImage(snap2, imgCols, imgRows, false);
// end imageProcessing
if (imageItem == null) {
imageItem = new ImageItem("", im, 0, "");
append(imageItem);
} else {
imageItem.setImage(im);
}
}
} catch (MediaException me) {
error(me);
} catch (Exception e) {
error(e);
}
}
}// end class Snapshot which is a thread
// ------------ start image processing code -------------------
/**
* Convert the int array of image to a 3D array.
*/
public static int[][][] convertToThreeDim(int[] oneDPix, int imgCols,
int imgRows) {
// Create the new 3D array to be populated
// with color data.
int[][][] data = new int[imgRows][imgCols][4];
for (int row = 0; row < imgRows; row++) {
// Extract a row of pixel data into a
// temporary array of ints
int[] aRow = new int[imgCols];
for (int col = 0; col < imgCols; col++) {
int element = row * imgCols + col;
aRow[col] = oneDPix[element];
}// end for loop on col
// Move the data into the 3D array. Note
// the use of bitwise AND and bitwise right
// shift operations to mask all but the
// correct set of eight bits.
for (int col = 0; col < imgCols; col++) {
// Alpha data
data[row][col][0] = (aRow[col] >> 24) & 0xFF;
// Red data
data[row][col][1] = (aRow[col] >> 16) & 0xFF;
// Green data
data[row][col][2] = (aRow[col] >> 8) & 0xFF;
// Blue data
data[row][col][3] = (aRow[col]) & 0xFF;
}// end for loop on col
}// end for loop on row
return data;
}// end convertToThreeDim
// The purpose of this method is to convert the
// data in the 3D array of ints back into the
// 1d array of type int. This is the reverse
// of the method named convertToThreeDim.
public static int[] convertToOneDim(int[][][] data, int imgCols, int imgRows) {
// Create the 1D array of type int to be
// populated with pixel data, one int value
// per pixel, with four color and alpha bytes
// per int value.
int[] oneDPix = new int[imgCols * imgRows * 4];
// Move the data into the 1D array. Note the
// use of the bitwise OR operator and the
// bitwise left-shift operators to put the
// four 8-bit bytes into each int.
for (int row = 0, cnt = 0; row < imgRows; row++) {
for (int col = 0; col < imgCols; col++) {
oneDPix[cnt] = ((data[row][col][0] << 24) & 0xFF000000)
| ((data[row][col][1] << 16) & 0x00FF0000)
| ((data[row][col][2] << 8) & 0x0000FF00)
| ((data[row][col][3]) & 0x000000FF);
cnt++;
}// end for loop on col
}// end for loop on row
return oneDPix;
}// end convertToOneDim
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -