package bce.client.player; import java.io.File; import java.io.IOException; import java.text.DecimalFormat; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.List; import org.eclipse.swt.widgets.ProgressBar; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.jboss.netty.channel.ChannelFuture; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import bce.client.requests.BCEFetchSizeRequest; import bce.client.requests.BCELoginRequest; import bce.client.requests.RTMPConnRequest; import bce.client.utils.BCEErrorCode; import bce.client.utils.BCEURLProvider; import bce.client.utils.SWTResourceManager; import bce.jni.utils.BCEUtils; public class BCEClient { private static final Logger logger = LoggerFactory.getLogger(BCEClient.class); protected String sessionId; protected BCEURLProvider provider; protected Player player; protected RTMPConnRequest rtmpRequest; protected String privateKeyFileName = null; protected String paramsFileName = null; protected StringBuffer localVideoName = null; protected String remoteVideoName = null; protected String userName = null; protected String password = null; protected boolean isLogin = false; protected boolean isCancel = false; protected double currentVideoSize; protected DecimalFormat format; protected Shell shell; private Display display; private Composite compositeUsr; private Composite compositePlay; private Composite compositeStatusBar; private Text txtUserName; private Text txtPassword; private Label lblLoginMsg; private Label lblStatus; private Label lblSeparator; private Label lblProgress; private CLabel lblImage; private Button btnLogin; private Button btnConnect; private Button btnDisconnect; private Button btnPlay; private Button btnStop; private Button btnChooseKey; private List playList; private ProgressBar progressBar; /** * Launch the application. * @param args */ public static void main(String[] args) { try { BCEClient window = new BCEClient(); window.open(); } catch (Exception e) { e.printStackTrace(); } } /** * Open the window. */ public void open() { provider = BCEURLProvider.getInstance(); player = Player.getInstance(); format = new DecimalFormat("#.00"); display = Display.getDefault(); createContents(); shell.open(); shell.layout(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } } /** * Create contents of the window. */ protected void createContents() { shell = new Shell(); shell.setSize(849, 590); shell.setText("BCE Client"); shell.addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent e) { if (rtmpRequest != null) { ChannelFuture future = rtmpRequest.getChannel().disconnect(); if (future.isSuccess()) future = rtmpRequest.getChannel().close(); if (future.isSuccess()) rtmpRequest.getBootstrap().getFactory().releaseExternalResources(); } isCancel = true; player.stop(); } }); compositeStatusBar = new Composite(shell, SWT.BORDER); compositeStatusBar.setBounds(10, 522, 620, 27); compositeUsr = new Composite(shell, SWT.BORDER); compositeUsr.setBounds(638, 10, 199, 539); final Color bkColor = new Color(null, 0x01, 0x01, 0x01); compositePlay = new Composite(shell, SWT.BORDER | SWT.EMBEDDED); compositePlay.setBounds(10, 10, 620, 506); compositePlay.setBackground(bkColor); lblLoginMsg = new Label(compositeUsr, SWT.RIGHT | SWT.BORDER); lblLoginMsg.setBounds(10, 10, 181, 23); lblLoginMsg.setText("Not Login"); txtUserName = new Text(compositeUsr, SWT.BORDER); txtUserName.setBounds(88, 39, 103, 29); txtUserName.setText(""); txtPassword = new Text(compositeUsr, SWT.BORDER | SWT.PASSWORD); txtPassword.setBounds(88, 74, 103, 29); txtPassword.setText(""); btnLogin = new Button(compositeUsr, SWT.PUSH); btnLogin.setBounds(104, 109, 87, 29); btnLogin.setText("Login"); btnLogin.addSelectionListener(new SelectionListener() { // @Override public void widgetSelected(SelectionEvent e) { if (isLogin) { lblStatus.setText("Info: you have logined!"); return; } if (txtUserName.getText() == null || txtUserName.getText().equals("")) { lblLoginMsg.setText("Null UserName"); return; } if (txtPassword.getText() == null || txtPassword.getText().equals("")) { lblLoginMsg.setText("Null password"); return; } lblStatus.setText("Info: Connecting ..."); BCELoginRequest request = new BCELoginRequest(new BCEHandler() { @Override public void handleResponse(byte[] responseData) throws IOException { String responseStr = new String(responseData, "UTF-8"); String[] data = responseStr.split(";"); if (Integer.parseInt(data[0]) == BCEErrorCode.USER_NAME_NOT_EXISTS) lblLoginMsg.setText("Wrong User Name"); if (Integer.parseInt(data[0]) == BCEErrorCode.PASSWORD_NOT_MATCH) lblLoginMsg.setText("Wrong Password"); if (Integer.parseInt(data[0]) == BCEErrorCode.LOGIN_CHECK_PASSED) { lblLoginMsg.setForeground(new Color(null, 255, 0, 0)); lblLoginMsg.setText("Welcome, " + data[1]); sessionId = "JSESSIONID=" + data[2]; String[] playlist = data[3].split(","); playList.removeAll(); for (int i = 0; i < playlist.length; i++) playList.add(playlist[i]); lblImage.setImage(new Image(Display.getDefault(), BCEClient.class.getResourceAsStream("/images/logo_user.png"))); userName = txtUserName.getText().trim(); password = txtUserName.getText().trim(); isLogin = true; lblStatus.setText("Info: Logined"); } } }, provider.getLoginURL(), sessionId, txtUserName.getText().trim(), txtPassword.getText().trim()); display.asyncExec(request); } @Override public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); btnDisconnect = new Button(compositeUsr, SWT.PUSH); btnDisconnect.setBounds(104, 144, 87, 29); btnDisconnect.setText("Disconnect"); btnDisconnect.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { isCancel = true; if (rtmpRequest == null) { lblStatus.setText("Info: Not connected!"); return; } ChannelFuture future = rtmpRequest.getChannel().disconnect(); future.awaitUninterruptibly(); if (future.isSuccess()) future = rtmpRequest.getChannel().close(); future.awaitUninterruptibly(); if (future.isSuccess()) rtmpRequest.getBootstrap().getFactory().releaseExternalResources(); lblStatus.setText("Info: Disconnected to Flazr"); } @Override public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); btnConnect = new Button(compositeUsr, SWT.PUSH); btnConnect.setBounds(10, 144, 90, 29); btnConnect.setText("Connect"); btnConnect.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { if (localVideoName == null) { lblStatus.setText("Info: please choose a video to play!"); return; } if (remoteVideoName == null) { lblStatus.setText("Info: please choose a video to play!"); return; } if (privateKeyFileName == null) { lblStatus.setText("Info: please choose private key file!"); return; } if (paramsFileName == null) { lblStatus.setText("Info: please choose params file!"); return; } lblStatus.setText("Info: Connecting to Flazr ..."); rtmpRequest = new RTMPConnRequest(new BCEHandler() { @Override public void handleResponse(byte[] responseData) throws IOException { String feedback = new String(responseData, "UTF-8"); lblStatus.setText(feedback); // 以下内容启动新线程处理进度条 final int min = progressBar.getMinimum(); final int max = progressBar.getMaximum(); isCancel = false; final File videoFile = new File(localVideoName.toString()); // 创建更新进度条的线程 Runnable runnable = new Runnable() { public void run() { for (int i = min; i < max; i = (int) ((videoFile.length() / currentVideoSize) * max)) { final int selection = i; try { Thread.sleep(100); } catch (InterruptedException e) { } if (isCancel) { break; } // 注意在更新进度条时加上了判断线程状态的条件 shell.getDisplay().asyncExec(new Runnable() { public void run() { if (progressBar.isDisposed()) return; progressBar.setSelection(selection); // 如果此时取消了线程,将进度条设置为初始状态 if (isCancel) { progressBar.setSelection(0); } } }); // 如果此时取消了线程,结束该循环,这个线程也就结束了,并重置线程状态 if (isCancel) { break; } } logger.info("quit progress bar thread ..."); } }; Thread pbThread = new Thread(runnable); pbThread.start(); } }, "127.0.0.1", 1935, localVideoName.toString(), true, remoteVideoName, 1, privateKeyFileName, paramsFileName); display.asyncExec(rtmpRequest); } @Override public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); btnPlay = new Button(compositeUsr, SWT.PUSH); btnPlay.setBounds(10, 179, 90, 29); btnPlay.setText("Play"); btnPlay.setEnabled(false); /** btnPlay.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { if (localVideoName == null) { lblStatus.setText("Info: no video chosen!"); return; } try { lblStatus.setText("Currently playing: " + localVideoName.toString().substring(localVideoName.lastIndexOf("/") + 1)); player.start(localVideoName.toString(), compositePlay.handle); } catch (IOException e1) { e1.printStackTrace(); } } @Override public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); */ btnStop = new Button(compositeUsr, SWT.PUSH); btnStop.setBounds(104, 179, 87, 29); btnStop.setText("Stop"); btnStop.setEnabled(false); /** btnStop.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { player.stop(); lblStatus.setText("Info: player stopped"); } @Override public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); */ btnChooseKey = new Button(compositeUsr, SWT.PUSH); btnChooseKey.setBounds(10, 109, 90, 29); btnChooseKey.setText("Setting"); btnChooseKey.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { FileDialog privateKeyDlg = new FileDialog(shell, SWT.OPEN); privateKeyDlg.setText("Select Private Key"); privateKeyDlg.setFilterPath("~"); privateKeyDlg.setFilterExtensions(new String[] {"*.key"}); privateKeyFileName = privateKeyDlg.open(); logger.info("chosen privateKey file, name: {}", privateKeyFileName); FileDialog paramsDlg = new FileDialog(shell, SWT.OPEN); paramsDlg.setText("Select Private Key"); paramsDlg.setFilterPath("~"); paramsDlg.setFilterExtensions(new String[] {"*.param"}); paramsFileName = paramsDlg.open(); logger.info("chosen curve params file, name: {}", paramsFileName); } @Override public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); playList = new List(compositeUsr, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); playList.setBounds(10, 214, 181, 313); playList.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { final String videoName = playList.getItem(playList.getSelectionIndex()).split("-")[0]; BCEFetchSizeRequest request = new BCEFetchSizeRequest(new BCEHandler() { @Override public void handleResponse(byte[] responseData) throws IOException { currentVideoSize = BCEUtils.bytesToLong(responseData); playList.setItem(playList.getSelectionIndex(), videoName + "-Size: " + format.format((currentVideoSize / (1024 * 1000))) + "MB"); } }, provider.getLoginURL(), sessionId, videoName); display.asyncExec(request); localVideoName = new StringBuffer().append("/tmp/").append(videoName); remoteVideoName = videoName; lblStatus.setText("Info: " + videoName + " chosen"); } @Override public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); progressBar = new ProgressBar(compositeStatusBar, SWT.HORIZONTAL | SWT.SMOOTH); progressBar.setBounds(362, 5, 253, 16); progressBar.setMaximum(100); progressBar.setMinimum(0); lblStatus = new Label(compositeStatusBar, SWT.NONE); lblStatus.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED)); lblStatus.setBounds(8, 4, 258, 18); lblStatus.setText("Info: no info now"); lblSeparator = new Label(compositeStatusBar, SWT.SEPARATOR | SWT.VERTICAL); lblSeparator.setBounds(272, 5, 8, 16); lblProgress = new Label(compositeStatusBar, SWT.NONE); lblProgress.setBounds(286, 4, 70, 18); lblProgress.setText("Progress:"); lblImage = new CLabel(compositeUsr, SWT.CENTER); lblImage.setBounds(10, 39, 76, 64); lblImage.setImage(new Image(Display.getDefault(), BCEClient.class.getResourceAsStream("/images/logo.png"))); } }