diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerMedia.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerMedia.java index c8490a14de..2ed1a3fdc6 100644 --- a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerMedia.java +++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerMedia.java @@ -46,20 +46,20 @@ import org.sleuthkit.datamodel.TskData; * * @author dfickling */ -@ServiceProvider(service = DataContentViewer.class, position=5) +@ServiceProvider(service = DataContentViewer.class, position = 5) public class DataContentViewerMedia extends javax.swing.JPanel implements DataContentViewer { - private static final String[] IMAGES = new String[]{ ".jpg", ".jpeg", ".png", ".gif", ".jpe", ".bmp"}; - private static final String[] VIDEOS = new String[]{ ".mov", ".m4v", ".flv", ".mp4", ".3gp", ".avi", ".mpg", ".mpeg"}; - private static final String[] AUDIOS = new String[]{ ".mp3", ".wav", ".wma"}; + private static final String[] IMAGES = new String[]{".jpg", ".jpeg", ".png", ".gif", ".jpe", ".bmp"}; + private static final String[] VIDEOS = new String[]{".mov", ".m4v", ".flv", ".mp4", ".3gp", ".avi", ".mpg", ".mpeg"}; + private static final String[] AUDIOS = new String[]{".mp3", ".wav", ".wma"}; private static final Logger logger = Logger.getLogger(DataContentViewerMedia.class.getName()); - private VideoComponent videoComponent; + private VideoComponent videoComponent; private PlayBin2 playbin2; private File currentFile; private long durationMillis = 0; private boolean autoTracking = false; // true if the slider is moving automatically - private final Object playbinLock = new Object(); // lock for synchronization - + private final Object playbinLock = new Object(); // lock for synchronization of playbin2 player + /** * Creates new form DataContentViewerVideo */ @@ -67,21 +67,20 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo initComponents(); customizeComponents(); } - + private void customizeComponents() { Gst.init(); progressSlider.addChangeListener(new ChangeListener() { - /** * Should always try to synchronize any call to - * progressSlider.setValue() to avoid a different thread - * changing playbin while stateChanged() is processing + * progressSlider.setValue() to avoid a different thread changing + * playbin while stateChanged() is processing */ @Override public void stateChanged(ChangeEvent e) { int time = progressSlider.getValue(); - synchronized(playbinLock) { - if(playbin2 != null && !autoTracking) { + synchronized (playbinLock) { + if (playbin2 != null && !autoTracking) { State orig = playbin2.getState(); playbin2.pause(); playbin2.seek(ClockTime.fromMillis(time)); @@ -89,7 +88,6 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo } } } - }); } @@ -158,22 +156,22 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo }// //GEN-END:initComponents private void pauseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pauseButtonActionPerformed - synchronized(playbinLock) { - if(playbin2.getState().equals(State.PLAYING)){ + synchronized (playbinLock) { + State state = playbin2.getState(); + if (state.equals(State.PLAYING)) { playbin2.pause(); pauseButton.setText("►"); playbin2.setState(State.PAUSED); - } else if(playbin2.getState().equals(State.PAUSED)) { + } else if (state.equals(State.PAUSED)) { playbin2.play(); pauseButton.setText("||"); playbin2.setState(State.PLAYING); - } else if(playbin2.getState().equals(State.READY)) { + } else if (state.equals(State.READY)) { ExtractMedia em = new ExtractMedia(currentFile, getJFile(currentFile)); em.execute(); } } }//GEN-LAST:event_pauseButtonActionPerformed - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton pauseButton; private javax.swing.JLabel progressLabel; @@ -185,22 +183,27 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo public void setNode(Node selectedNode) { reset(); setComponentsVisibility(false); - if(selectedNode == null) { return; } - + if (selectedNode == null) { + return; + } + File file = selectedNode.getLookup().lookup(File.class); - if(file == null) { return; } - + if (file == null) { + return; + } + currentFile = file; - if(containsExt(file.getName(), IMAGES)) { + if (containsExt(file.getName(), IMAGES)) { showImage(file); - } else if(containsExt(file.getName(), VIDEOS) || containsExt(file.getName(), AUDIOS)) { + } else if (containsExt(file.getName(), VIDEOS) || containsExt(file.getName(), AUDIOS)) { setupVideo(file); } } - + /** * Initialize vars and display the image on the panel. - * @param file + * + * @param file */ private void showImage(File file) { java.io.File ioFile = getJFile(file); @@ -211,59 +214,60 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo logger.log(Level.WARNING, "Error buffering file", ex); } } - + videoComponent = new VideoComponent(); - synchronized(playbinLock) { + synchronized (playbinLock) { playbin2 = new PlayBin2("ImageViewer"); playbin2.setVideoSink(videoComponent.getElement()); } - + videoPanel.removeAll(); videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS)); videoPanel.add(videoComponent); videoPanel.revalidate(); videoPanel.repaint(); - - synchronized(playbinLock) { + + synchronized (playbinLock) { playbin2.setInputFile(ioFile); playbin2.play(); } videoPanel.setVisible(true); } - + /** * Initialize all the necessary vars to play a video/audio file. + * * @param file the File to play */ private void setupVideo(File file) { java.io.File ioFile = getJFile(file); - + pauseButton.setText("►"); progressSlider.setValue(0); - + videoComponent = new VideoComponent(); - synchronized(playbinLock) { + synchronized (playbinLock) { playbin2 = new PlayBin2("VideoPlayer"); playbin2.setVideoSink(videoComponent.getElement()); } - + videoPanel.removeAll(); videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS)); videoPanel.add(videoComponent); videoPanel.revalidate(); videoPanel.repaint(); - - synchronized(playbinLock) { + + synchronized (playbinLock) { playbin2.setInputFile(ioFile); playbin2.setState(State.READY); } setComponentsVisibility(true); } - + /** * To set the visibility of specific components in this class. * - * @param isVisible whether to show or hide the specific components + * @param isVisible whether to show or hide the specific components */ private void setComponentsVisibility(boolean isVisible) { pauseButton.setVisible(isVisible); @@ -297,18 +301,18 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo // we don't want this to do anything // because we already reset on each selected node } - + private void reset() { - synchronized(playbinLock) { - if(playbin2 != null) { - if(playbin2.isPlaying()) { + synchronized (playbinLock) { + if (playbin2 != null) { + if (playbin2.isPlaying()) { playbin2.stop(); } playbin2.setState(State.NULL); // try { // Thread.sleep(20); // gstreamer needs to catch up // } catch (InterruptedException ex) { } - if(playbin2.getState().equals(State.NULL)) { + if (playbin2.getState().equals(State.NULL)) { playbin2.dispose(); } playbin2 = null; @@ -331,29 +335,29 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo if (File.dirFlagToValue(file.getDir_flags()).equals(TskData.TSK_FS_NAME_FLAG_ENUM.TSK_FS_NAME_FLAG_UNALLOC.toString())) { return false; } - - if(file.getSize() == 0) { + + if (file.getSize() == 0) { return false; } String name = file.getName().toLowerCase(); - - if(containsExt(name, IMAGES) || containsExt(name, AUDIOS) || containsExt(name, VIDEOS)) { + + if (containsExt(name, IMAGES) || containsExt(name, AUDIOS) || containsExt(name, VIDEOS)) { return true; } - + return false; } @Override public int isPreferred(Node node, boolean isSupported) { - if(isSupported) { + if (isSupported) { return 7; } else { return 0; } } - + private static boolean containsExt(String name, String[] exts) { int extStart = name.lastIndexOf("."); String ext = ""; @@ -362,7 +366,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo } return Arrays.asList(exts).contains(ext); } - + private java.io.File getJFile(File file) { // Get the temp folder path of the case String tempPath = Case.getCurrentCase().getTempDirectory(); @@ -377,9 +381,9 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo java.io.File tempFile = new java.io.File(tempPath); return tempFile; } - + /* Thread that extracts and plays a file */ - private class ExtractMedia extends SwingWorker { + private class ExtractMedia extends SwingWorker { private ProgressHandle progress; boolean success = false; @@ -387,11 +391,13 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo private java.io.File jFile; String duration; String position; - - ExtractMedia(org.sleuthkit.datamodel.File sFile, java.io.File jFile){ + + ExtractMedia(org.sleuthkit.datamodel.File sFile, java.io.File jFile) { this.sFile = sFile; this.jFile = jFile; - }; + } + + ; @Override protected Object doInBackground() throws Exception { @@ -438,39 +444,49 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo progressLabel.setText("Error buffering file"); return; } - synchronized(playbinLock) { + ClockTime dur = null; + synchronized (playbinLock) { playbin2.play(); // must play, then pause and get state to get duration. playbin2.pause(); playbin2.getState(); - duration = playbin2.queryDuration().toString(); - durationMillis = playbin2.queryDuration().toMillis(); + dur = playbin2.queryDuration(); } - progressSlider.setMaximum((int)durationMillis); + duration = dur.toString(); + durationMillis = dur.toMillis(); + + progressSlider.setMaximum((int) durationMillis); progressSlider.setMinimum(0); final String finalDuration; - if(duration.length() == 8 && duration.substring(0,3).equals("00:")) { + if (duration.length() == 8 && duration.substring(0, 3).equals("00:")) { finalDuration = duration.substring(3); progressLabel.setText("00:00/" + duration); } else { finalDuration = duration; progressLabel.setText("00:00:00/" + duration); } - synchronized(playbinLock) { + synchronized (playbinLock) { playbin2.play(); } pauseButton.setText("||"); new Thread(new Runnable() { + private boolean isPlayBinReady() { + synchronized (playbinLock) { + return playbin2 != null && playbin2.getState().equals(State.NULL); + } + } @Override public void run() { long positionMillis = 0; while (positionMillis < durationMillis - && playbin2 != null - && !playbin2.getState().equals(State.NULL)) { - synchronized(playbinLock) { - position = playbin2.queryPosition().toString(); - positionMillis = playbin2.queryPosition().toMillis(); - } + && isPlayBinReady() ) { + ClockTime pos = null; + synchronized (playbinLock) { + pos = playbin2.queryPosition(); + } + position = pos.toString(); + positionMillis = pos.toMillis(); + if (position.length() == 8) { position = position.substring(3); } @@ -480,7 +496,8 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo autoTracking = false; try { Thread.sleep(20); - } catch (InterruptedException ex) { } + } catch (InterruptedException ex) { + } } if (finalDuration.length() == 5) { progressLabel.setText("00:00/" + finalDuration); @@ -488,13 +505,13 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo progressLabel.setText("00:00:00/" + finalDuration); } // If it reached the end - if(progressSlider.getValue() == progressSlider.getMaximum()) { + if (progressSlider.getValue() == progressSlider.getMaximum()) { restartVideo(); } } - + public void restartVideo() { - synchronized(playbinLock) { + synchronized (playbinLock) { if (playbin2 != null) { playbin2.stop(); playbin2.setState(State.READY); // ready to be played again