Merge git://github.com/sleuthkit/autopsy

This commit is contained in:
dhurd 2012-09-12 12:38:19 -04:00
commit 24f0851e16
5 changed files with 239 additions and 143 deletions

View File

@ -1,4 +1,4 @@
<?xml version="1.1" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> <Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues> <AuxValues>
@ -20,7 +20,7 @@
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="pauseButton" min="-2" max="-2" attributes="0"/> <Component id="pauseButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="progressSlider" pref="160" max="32767" attributes="0"/> <Component id="progressSlider" pref="158" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="progressLabel" min="-2" max="-2" attributes="0"/> <Component id="progressLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
@ -32,10 +32,10 @@
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="1" attributes="0">
<Component id="videoPanel" max="32767" attributes="0"/> <Component id="videoPanel" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0"> <Group type="103" groupAlignment="1" max="-2" attributes="0">
<Component id="pauseButton" min="-2" max="-2" attributes="0"/> <Component id="pauseButton" max="32767" attributes="0"/>
<Component id="progressLabel" min="-2" max="-2" attributes="0"/> <Component id="progressSlider" max="32767" attributes="0"/>
<Component id="progressSlider" min="-2" max="-2" attributes="0"/> <Component id="progressLabel" alignment="1" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</Group> </Group>
@ -47,6 +47,15 @@
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerMedia.pauseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerMedia.pauseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[45, 23]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[45, 23]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[45, 23]"/>
</Property>
</Properties> </Properties>
<Events> <Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="pauseButtonActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="pauseButtonActionPerformed"/>
@ -68,6 +77,9 @@
</Layout> </Layout>
</Container> </Container>
<Component class="javax.swing.JSlider" name="progressSlider"> <Component class="javax.swing.JSlider" name="progressSlider">
<Properties>
<Property name="value" type="int" value="0"/>
</Properties>
</Component> </Component>
<Component class="javax.swing.JLabel" name="progressLabel"> <Component class="javax.swing.JLabel" name="progressLabel">
<Properties> <Properties>

View File

@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.corecomponents;
import java.awt.Component; import java.awt.Component;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.CancellationException;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.swing.BoxLayout; import javax.swing.BoxLayout;
@ -45,18 +46,20 @@ import org.sleuthkit.datamodel.TskData;
* *
* @author dfickling * @author dfickling
*/ */
@ServiceProvider(service = DataContentViewer.class, position=5) @ServiceProvider(service = DataContentViewer.class, position = 5)
public class DataContentViewerMedia extends javax.swing.JPanel implements DataContentViewer { 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[] 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[] 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[] AUDIOS = new String[]{".mp3", ".wav", ".wma"};
private static final Logger logger = Logger.getLogger(DataContentViewerMedia.class.getName()); private static final Logger logger = Logger.getLogger(DataContentViewerMedia.class.getName());
private VideoComponent videoComponent; private VideoComponent videoComponent;
private PlayBin2 playbin2; private PlayBin2 playbin2;
private File currentFile; private File currentFile;
private long durationMillis = 0; private long durationMillis = 0;
private boolean autoTracking = false; // true if the slider is moving automatically private boolean autoTracking = false; // true if the slider is moving automatically
private final Object playbinLock = new Object(); // lock for synchronization of playbin2 player
/** /**
* Creates new form DataContentViewerVideo * Creates new form DataContentViewerVideo
*/ */
@ -68,19 +71,23 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
private void customizeComponents() { private void customizeComponents() {
Gst.init(); Gst.init();
progressSlider.addChangeListener(new ChangeListener() { 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
*/
@Override @Override
public void stateChanged(ChangeEvent e) { public void stateChanged(ChangeEvent e) {
int time = progressSlider.getValue(); int time = progressSlider.getValue();
if(playbin2 != null && !autoTracking) { synchronized (playbinLock) {
if (playbin2 != null && !autoTracking) {
State orig = playbin2.getState(); State orig = playbin2.getState();
playbin2.pause(); playbin2.pause();
playbin2.getState();
playbin2.seek(ClockTime.fromMillis(time)); playbin2.seek(ClockTime.fromMillis(time));
playbin2.setState(orig); playbin2.setState(orig);
} }
} }
}
}); });
} }
@ -99,6 +106,9 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
progressLabel = new javax.swing.JLabel(); progressLabel = new javax.swing.JLabel();
pauseButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerMedia.class, "DataContentViewerMedia.pauseButton.text")); // NOI18N pauseButton.setText(org.openide.util.NbBundle.getMessage(DataContentViewerMedia.class, "DataContentViewerMedia.pauseButton.text")); // NOI18N
pauseButton.setMaximumSize(new java.awt.Dimension(45, 23));
pauseButton.setMinimumSize(new java.awt.Dimension(45, 23));
pauseButton.setPreferredSize(new java.awt.Dimension(45, 23));
pauseButton.addActionListener(new java.awt.event.ActionListener() { pauseButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
pauseButtonActionPerformed(evt); pauseButtonActionPerformed(evt);
@ -116,6 +126,8 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
.addGap(0, 242, Short.MAX_VALUE) .addGap(0, 242, Short.MAX_VALUE)
); );
progressSlider.setValue(0);
progressLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerMedia.class, "DataContentViewerMedia.progressLabel.text")); // NOI18N progressLabel.setText(org.openide.util.NbBundle.getMessage(DataContentViewerMedia.class, "DataContentViewerMedia.progressLabel.text")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
@ -124,9 +136,9 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(videoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(videoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(pauseButton) .addComponent(pauseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, 160, Short.MAX_VALUE) .addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, 158, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(progressLabel) .addComponent(progressLabel)
.addContainerGap()) .addContainerGap())
@ -136,26 +148,30 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(videoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(videoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(pauseButton) .addComponent(pauseButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(progressLabel) .addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(progressSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addComponent(progressLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void pauseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pauseButtonActionPerformed private void pauseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pauseButtonActionPerformed
if(playbin2.getState().equals(State.PLAYING)){ synchronized (playbinLock) {
State state = playbin2.getState();
if (state.equals(State.PLAYING)) {
playbin2.pause(); playbin2.pause();
pauseButton.setText(""); pauseButton.setText("");
} else if(playbin2.getState().equals(State.PAUSED)) { playbin2.setState(State.PAUSED);
} else if (state.equals(State.PAUSED)) {
playbin2.play(); playbin2.play();
pauseButton.setText("||"); pauseButton.setText("||");
} else { playbin2.setState(State.PLAYING);
} else if (state.equals(State.READY)) {
ExtractMedia em = new ExtractMedia(currentFile, getJFile(currentFile)); ExtractMedia em = new ExtractMedia(currentFile, getJFile(currentFile));
em.execute(); em.execute();
} }
}
}//GEN-LAST:event_pauseButtonActionPerformed }//GEN-LAST:event_pauseButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton pauseButton; private javax.swing.JButton pauseButton;
private javax.swing.JLabel progressLabel; private javax.swing.JLabel progressLabel;
@ -165,32 +181,31 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
@Override @Override
public void setNode(Node selectedNode) { public void setNode(Node selectedNode) {
pauseButton.setText(""); reset();
if(selectedNode == null) {
setDataView(null);
return;
}
File file = selectedNode.getLookup().lookup(File.class);
setDataView(file);
if(file == null) {
return;
}
boolean isVidOrAud = containsExt(file.getName(), VIDEOS) || containsExt(file.getName(), AUDIOS);
pauseButton.setVisible(isVidOrAud);
progressLabel.setVisible(isVidOrAud);
progressSlider.setVisible(isVidOrAud);
}
private void setDataView(File file) {
if(file == null) {
setComponentsVisibility(false); setComponentsVisibility(false);
if (selectedNode == null) {
return; return;
} else {
setComponentsVisibility(true);
} }
this.currentFile = file;
File file = selectedNode.getLookup().lookup(File.class);
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)) {
setupVideo(file);
}
}
/**
* Initialize vars and display the image on the panel.
*
* @param file
*/
private void showImage(File file) {
java.io.File ioFile = getJFile(file); java.io.File ioFile = getJFile(file);
if (!ioFile.exists()) { if (!ioFile.exists()) {
try { try {
@ -199,10 +214,56 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
logger.log(Level.WARNING, "Error buffering file", ex); logger.log(Level.WARNING, "Error buffering file", ex);
} }
} }
videoComponent = new VideoComponent();
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) {
playbin2.setInputFile(ioFile); playbin2.setInputFile(ioFile);
playbin2.play(); 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) {
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) {
playbin2.setInputFile(ioFile);
playbin2.setState(State.READY);
}
setComponentsVisibility(true);
}
/** /**
* To set the visibility of specific components in this class. * To set the visibility of specific components in this class.
* *
@ -237,42 +298,31 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
@Override @Override
public void resetComponent() { public void resetComponent() {
// we don't want this to do anything
// because we already reset on each selected node
} }
private void resetVideo() { private void reset() {
if(playbin2 != null) { synchronized (playbinLock) {
if(playbin2.isPlaying()) { if (playbin2 != null) {
if (playbin2.isPlaying()) {
playbin2.stop(); playbin2.stop();
} }
playbin2.setState(State.NULL); playbin2.setState(State.NULL);
if(playbin2.getState() == State.NULL) { // try {
// Thread.sleep(20); // gstreamer needs to catch up
// } catch (InterruptedException ex) { }
if (playbin2.getState().equals(State.NULL)) {
playbin2.dispose(); playbin2.dispose();
} }
playbin2 = null; playbin2 = null;
} }
videoComponent = null; videoComponent = null;
playbin2 = new PlayBin2("VideoPlayer");
videoComponent = new VideoComponent();
playbin2.setVideoSink(videoComponent.getElement());
videoPanel.removeAll();
videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS));
videoPanel.add(videoComponent);
videoPanel.revalidate();
videoPanel.repaint();
}
private void stopVideo() {
if(playbin2 != null && playbin2.isPlaying()) {
playbin2.stop();
} }
} }
@Override @Override
public boolean isSupported(Node node) { public boolean isSupported(Node node) {
stopVideo();
if (node == null) { if (node == null) {
return false; return false;
} }
@ -286,14 +336,13 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
return false; return false;
} }
if(file.getSize() == 0) { if (file.getSize() == 0) {
return false; return false;
} }
String name = file.getName().toLowerCase(); 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)) {
resetVideo();
return true; return true;
} }
@ -302,7 +351,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
@Override @Override
public int isPreferred(Node node, boolean isSupported) { public int isPreferred(Node node, boolean isSupported) {
if(isSupported) { if (isSupported) {
return 7; return 7;
} else { } else {
return 0; return 0;
@ -334,17 +383,21 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
} }
/* Thread that extracts and plays a file */ /* Thread that extracts and plays a file */
private class ExtractMedia extends SwingWorker<Object,Void> { private class ExtractMedia extends SwingWorker<Object, Void> {
private ProgressHandle progress; private ProgressHandle progress;
boolean success = false; boolean success = false;
private File sFile; private File sFile;
private java.io.File jFile; 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.sFile = sFile;
this.jFile = jFile; this.jFile = jFile;
}; }
;
@Override @Override
protected Object doInBackground() throws Exception { protected Object doInBackground() throws Exception {
@ -357,9 +410,9 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
}); });
progressLabel.setText("Buffering..."); progressLabel.setText("Buffering...");
progress.start(); progress.start();
progress.switchToIndeterminate(); progress.switchToDeterminate(100);
try { try {
ContentUtils.writeToFile(sFile, jFile); ContentUtils.writeToFile(sFile, jFile, progress, this, true);
} catch (IOException ex) { } catch (IOException ex) {
logger.log(Level.WARNING, "Error buffering file", ex); logger.log(Level.WARNING, "Error buffering file", ex);
} }
@ -370,45 +423,70 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
/* clean up or start the worker threads */ /* clean up or start the worker threads */
@Override @Override
protected void done() { protected void done() {
try {
super.get(); //block and get all exceptions thrown while doInBackground()
} catch (CancellationException ex) {
logger.log(Level.INFO, "Media buffering was canceled.");
} catch (InterruptedException ex) {
logger.log(Level.INFO, "Media buffering was interrupted.");
} catch (Exception ex) {
logger.log(Level.SEVERE, "Fatal error during media buffering.", ex);
} finally {
progress.finish(); progress.finish();
if (success) { if (!this.isCancelled()) {
play(); play();
} }
} }
}
private void play() { private void play() {
if (jFile == null || !jFile.exists()) { if (jFile == null || !jFile.exists()) {
progressLabel.setText("Error buffering file"); progressLabel.setText("Error buffering file");
return; return;
} }
playbin2.setInputFile(jFile); ClockTime dur = null;
synchronized (playbinLock) {
playbin2.play(); // must play, then pause and get state to get duration. playbin2.play(); // must play, then pause and get state to get duration.
playbin2.pause(); playbin2.pause();
playbin2.getState(); playbin2.getState();
String duration = playbin2.queryDuration().toString(); dur = playbin2.queryDuration();
durationMillis = playbin2.queryDuration().toMillis(); }
progressSlider.setMaximum((int)durationMillis); duration = dur.toString();
durationMillis = dur.toMillis();
progressSlider.setMaximum((int) durationMillis);
progressSlider.setMinimum(0); progressSlider.setMinimum(0);
final String finalDuration; 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); finalDuration = duration.substring(3);
progressLabel.setText("00:00/" + duration); progressLabel.setText("00:00/" + duration);
} else { } else {
finalDuration = duration; finalDuration = duration;
progressLabel.setText("00:00:00/" + duration); progressLabel.setText("00:00:00/" + duration);
} }
synchronized (playbinLock) {
playbin2.play(); playbin2.play();
}
pauseButton.setText("||"); pauseButton.setText("||");
new Thread(new Runnable() { new Thread(new Runnable() {
private boolean isPlayBinReady() {
synchronized (playbinLock) {
return playbin2 != null && !playbin2.getState().equals(State.NULL);
}
}
@Override @Override
public void run() { public void run() {
long positionMillis = 0; long positionMillis = 0;
while (positionMillis < durationMillis while (positionMillis < durationMillis
&& playbin2 != null && isPlayBinReady() ) {
&& !playbin2.getState().equals(State.NULL)) { ClockTime pos = null;
String position = playbin2.queryPosition().toString(); synchronized (playbinLock) {
positionMillis = playbin2.queryPosition().toMillis(); pos = playbin2.queryPosition();
}
position = pos.toString();
positionMillis = pos.toMillis();
if (position.length() == 8) { if (position.length() == 8) {
position = position.substring(3); position = position.substring(3);
} }
@ -426,13 +504,22 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
} else { } else {
progressLabel.setText("00:00:00/" + finalDuration); progressLabel.setText("00:00:00/" + finalDuration);
} }
// If it reached the end
if (progressSlider.getValue() == progressSlider.getMaximum()) {
restartVideo();
}
}
public void restartVideo() {
synchronized (playbinLock) {
if (playbin2 != null) { if (playbin2 != null) {
playbin2.stop(); playbin2.stop();
playbin2.getState(); playbin2.setState(State.READY); // ready to be played again
}
}
pauseButton.setText(""); pauseButton.setText("");
progressSlider.setValue(0); progressSlider.setValue(0);
} }
}
}).start(); }).start();
} }
} }

View File

@ -77,12 +77,7 @@ public class HashDbIngestModule implements IngestModuleAbstractFile {
return instance; return instance;
} }
/**
* notification from manager that brand new processing should be initiated.
* Module loads its configuration and performs initialization
*
* @param services handle to the manager to postMessage() to
*/
@Override @Override
public void init(IngestModuleInit initContext) { public void init(IngestModuleInit initContext) {
services = IngestServices.getDefault(); services = IngestServices.getDefault();
@ -127,10 +122,7 @@ public class HashDbIngestModule implements IngestModuleAbstractFile {
} }
} }
/**
* notification from manager that there is no more content to process and all work is done.
* Module performs any clean-up, notifies viewers and may also write results to the black-board
*/
@Override @Override
public void complete() { public void complete() {
StringBuilder detailsSb = new StringBuilder(); StringBuilder detailsSb = new StringBuilder();

View File

@ -41,9 +41,13 @@ public interface IngestModuleAbstract {
}; };
/** /**
* Notification from manager that brand new ingest should be initiated. * Notification from manager that brand new ingest should be initiated..
* Module loads its configuration and performs initialization * Module loads its configuration and performs initialization.
* Invoked once per new worker thread, per ingest * Invoked once per new worker thread, per ingest.
* In this method initialize always IngestServices handle
* using IngestServices.getDefault() lazy-loading approach.
* NEVER initialize IngestServices handle in the member declaration, because it might result
* in multiple instances of the singleton -- different class loaders are used in different modules.
* @param initContext context used to initialize some modules * @param initContext context used to initialize some modules
*/ */
public void init(IngestModuleInit initContext); public void init(IngestModuleInit initContext);

View File

@ -1,4 +1,4 @@
3.0.0b5 (August 30, 2012) 3.0.0b5 (September 12, 2012)
Funded by US Army Intelligence Center of Excellence (USAICoE): Funded by US Army Intelligence Center of Excellence (USAICoE):
New features: New features:
@ -21,6 +21,7 @@ Bugfixes:
- Directory tree now shows which directories have no children before user clicks. - Directory tree now shows which directories have no children before user clicks.
- Fixed bug when recent cases would not get updated. - Fixed bug when recent cases would not get updated.
- Fixed a bug when sometimes a case would get deleted. - Fixed a bug when sometimes a case would get deleted.
- Fixed occasional Media View crashes.
3.0.0b4 (June 29, 2012) 3.0.0b4 (June 29, 2012)
Funded by US Army Intelligence Center of Excellence (USAICoE): Funded by US Army Intelligence Center of Excellence (USAICoE):