package ca.uvic.chisel.videoplayer.test.views; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.InvocationTargetException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.part.ViewPart; import ca.uvic.chisel.video.widget.AbstractVideoPlayer; import ca.uvic.chisel.video.widget.AnnotatedProgress; import ca.uvic.chisel.video.widget.ProgressAnnotation; import ca.uvic.chisel.video.widget.VideoEvent; import ca.uvic.chisel.video.widget.VideoListener; import ca.uvic.chisel.video.widget.internal.BrowserVideoPlayer; import ca.uvic.chisel.videoplayer.test.IVideoPlayerPart; import ca.uvic.chisel.videoplayer.test.TestPlayer; /** * This sample class demonstrates how to plug-in a new * workbench view. The view shows data obtained from the * model. The sample creates a dummy model on the fly, * but a real implementation would connect to the model * available either in this or another plug-in (e.g. the workspace). * The view is connected to the model using a content provider. * <p> * The view uses a label provider to define how model * objects should be presented in the view. Each * view can present the same model objects using * different labels and icons, if needed. Alternatively, * a single label provider can be shared between views * in order to ensure that objects of the same type are * presented in the same way everywhere. * <p> */ public class VideoPlayerView extends ViewPart implements IVideoPlayerPart { private class StreamGobbler extends Thread { private InputStream in; private PrintWriter writer; StreamGobbler(InputStream in, OutputStream out) { super("Reading Input"); this.in = in; this.writer = (out != null) ? new PrintWriter(out) : null; } StreamGobbler(InputStream in, PrintWriter out) { super("Reading Input"); this.in = in; this.writer = out; } @Override public void run() { try { BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String line; while ((line = reader.readLine())!=null) { if (writer != null) { writer.println(line); } } } catch (IOException e) {} } } /** * The ID of the view as specified by the extension. */ public static final String ID = "ca.uvic.chisel.videoplayer.test.views.VideoPlayerView"; class BrowserVideoListener implements VideoListener { @Override public void videoUpdate(VideoEvent event) { long loaded = 0; switch (event.type) { case VideoEvent.VIDEO_LOAD_PROGRESS: loadedProgress.setOffset(0); loadedProgress.setLength(event.getSource().getLoadProgress()); break; case VideoEvent.VIDEO_LOADED: loadedProgress.setOffset(0); loadedProgress.setLength(event.getSource().getLength()); break; case VideoEvent.VIDEO_READY: loaded = event.getSource().getLoadProgress(); if (loaded != loadedProgress.getLength()) { loadedProgress.setLength(loaded); } playerBar.setMaximum(event.getSource().getLength()); break; case VideoEvent.VIDEO_PLAYHEAD: loaded = event.getSource().getLoadProgress(); if (loaded != loadedProgress.getLength()) { loadedProgress.setLength(loaded); } playerBar.setSelectedMaximum(event.getSource().getTime()); break; case VideoEvent.VIDEO_STARTED: case VideoEvent.VIDEO_PAUSED: case VideoEvent.VIDEO_STOPPED: updateButtons(); break; } } } private BrowserVideoPlayer videoPlayer; private AnnotatedProgress playerBar; private ProgressAnnotation loadedProgress; private Button play; /** * The constructor. */ public VideoPlayerView() { } private void updateButtons() { ImageRegistry reg = TestPlayer.getDefault().getImageRegistry(); if (getVideoPlayer().isPlaying()) { play.setImage(reg.get(TestPlayer.ICON_PAUSE)); play.setToolTipText("Pause"); play.setSelection(true); } else if (getVideoPlayer().isPaused() || getVideoPlayer().isStopped()){ play.setImage(reg.get(TestPlayer.ICON_PLAY)); play.setToolTipText("Play"); } } /** * This is a callback that will allow us * to create the viewer and initialize it. */ public void createPartControl(Composite parent) { Composite page = new Composite(parent, SWT.NONE); page.setLayout(new GridLayout(4, false)); GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); data.horizontalSpan = 4; this.videoPlayer = new BrowserVideoPlayer(page, SWT.NONE); videoPlayer.setLayoutData(data); play = new Button(page, SWT.TOGGLE); play.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { Button b = (Button) e.widget; ImageRegistry reg = TestPlayer.getDefault().getImageRegistry(); if (b.getSelection()) { videoPlayer.play(); } else { videoPlayer.pause(); } } }); ImageRegistry reg = TestPlayer.getDefault().getImageRegistry(); play.setImage(reg.get(TestPlayer.ICON_PLAY)); play.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); Button stop = new Button(page, SWT.PUSH); stop.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { ImageRegistry reg = TestPlayer.getDefault().getImageRegistry(); videoPlayer.stop(); play.setSelection(false); play.setImage(reg.get(TestPlayer.ICON_PLAY)); play.setToolTipText("Play"); } }); stop.setToolTipText("Stop"); stop.setImage(reg.get(TestPlayer.ICON_STOP)); stop.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); videoPlayer.addVideoListener(new BrowserVideoListener()); playerBar = new AnnotatedProgress(page, SWT.NONE); playerBar.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY)); loadedProgress = new ProgressAnnotation(playerBar); loadedProgress.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_DARK_YELLOW)); data = new GridData(SWT.FILL, SWT.FILL, true, false); data.heightHint = 10; playerBar.setLayoutData(data); makeActions(); hookContextMenu(); hookDoubleClickAction(); contributeToActionBars(); } private void hookContextMenu() { MenuManager menuMgr = new MenuManager("#PopupMenu"); menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(new IMenuListener() { public void menuAboutToShow(IMenuManager manager) { VideoPlayerView.this.fillContextMenu(manager); } }); } private void contributeToActionBars() { IActionBars bars = getViewSite().getActionBars(); fillLocalPullDown(bars.getMenuManager()); fillLocalToolBar(bars.getToolBarManager()); } private void fillLocalPullDown(IMenuManager manager) { } private void fillContextMenu(IMenuManager manager) { // Other plug-ins can contribute there actions here manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); } private void fillLocalToolBar(IToolBarManager manager) { Action openAction = new Action() { @Override public void run() { FileDialog dialog = new FileDialog(getSite().getShell(), SWT.OPEN); Runtime rt = Runtime.getRuntime(); String[] extensions = new String[] {"*.flv"}; try { Process process = rt.exec("ffmpeg -version"); new StreamGobbler(process.getInputStream(), System.out).start(); new StreamGobbler(process.getErrorStream(), System.err).start(); int err = process.waitFor(); if (err == 0) { extensions = new String[] {"*.flv", "*.avi", "*.wmv", "*.m4v", "*.mp4"}; } } catch (IOException e) { } catch (InterruptedException e) { Thread.interrupted(); } dialog.setFilterExtensions(extensions); String filename = dialog.open(); if (filename != null && !filename.isEmpty()) { File file = new File(filename); final File[] transcoder = new File[] {file}; if (file.isFile()) { int dot = file.getName().lastIndexOf('.'); if (dot > 0 && dot < file.getName().length()-1) { String extension = file.getName().substring(dot+1); if (!extension.toLowerCase().equals("flv")) { ProgressMonitorDialog progress = new ProgressMonitorDialog(getSite().getShell()); try { progress.run(true, false, new IRunnableWithProgress() { @Override public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { IPath output = TestPlayer.getDefault().getStateLocation(); File file = transcoder[0]; int dot = file.getName().lastIndexOf('.'); String fname = file.getName().substring(0, dot) + ".flv"; output = output.append(fname); if (output.toFile().exists()) { output.toFile().delete(); } String command = "ffmpeg -i \"" + file.getAbsolutePath() + "\" \"" + output.toOSString() + "\""; Process process = Runtime.getRuntime().exec(command); StringWriter errorString = new StringWriter(); PrintWriter err = new PrintWriter(new StringWriter()) { public void println(String s) { super.print(s); }; }; PrintWriter out = new PrintWriter(errorString); new StreamGobbler(process.getInputStream(), out).start(); new StreamGobbler(process.getErrorStream(), err).start(); int error = 0; error = process.waitFor(); if (error == 0) { transcoder[0] = output.toFile(); } else { MessageDialog.openError( getSite().getShell(), "Error Transcoding Video", "ffmpeg error " + error + ". Unable to transcode video for playback."); System.err.println(errorString.toString()); } } catch (Exception e) { throw new InvocationTargetException(e); } } }); } catch (InvocationTargetException e1) { } catch (InterruptedException e1) { } } } file = transcoder[0]; videoPlayer.load(file.getAbsolutePath()); } } } }; openAction.setText("Open file..."); manager.add(openAction); } private void makeActions() { } private void hookDoubleClickAction() { } /** * Passing the focus request to the viewer's control. */ public void setFocus() { } public AbstractVideoPlayer getVideoPlayer() { return videoPlayer; } }