This commit is contained in:
adam-m 2012-12-27 13:51:31 -05:00
commit 798c7eaffe
3 changed files with 79 additions and 60 deletions

View File

@ -80,7 +80,7 @@ DataContentViewerArtifact.pageLabel.text=Result:
AdvancedConfigurationDialog.applyButton.text=OK AdvancedConfigurationDialog.applyButton.text=OK
DataContentViewerMedia.pauseButton.text=\u25ba DataContentViewerMedia.pauseButton.text=\u25ba
DataContentViewerMedia.progressLabel.text=00:00/00:00 DataContentViewerMedia.progressLabel.text=
DataContentViewerString.goToPageLabel.text=Go to Page: DataContentViewerString.goToPageLabel.text=Go to Page:
DataContentViewerString.goToPageTextField.text= DataContentViewerString.goToPageTextField.text=
DataContentViewerHex.goToPageTextField.text= DataContentViewerHex.goToPageTextField.text=

View File

@ -16,14 +16,13 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="videoPanel" alignment="0" max="32767" attributes="0"/> <Component id="videoPanel" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0"> <Group type="102" 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 min="-2" max="-2" attributes="0"/>
<Component id="progressSlider" pref="158" max="32767" attributes="0"/> <Component id="progressSlider" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="progressLabel" min="-2" max="-2" attributes="0"/> <Component id="progressLabel" min="-2" pref="104" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -34,7 +33,7 @@
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" max="-2" attributes="0"> <Group type="103" groupAlignment="1" max="-2" attributes="0">
<Component id="pauseButton" max="32767" attributes="0"/> <Component id="pauseButton" max="32767" attributes="0"/>
<Component id="progressSlider" max="32767" attributes="0"/> <Component id="progressSlider" max="-2" attributes="0"/>
<Component id="progressLabel" alignment="1" max="32767" attributes="0"/> <Component id="progressLabel" alignment="1" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
@ -66,7 +65,7 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="283" max="32767" attributes="0"/> <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
@ -83,6 +82,7 @@
</Component> </Component>
<Component class="javax.swing.JLabel" name="progressLabel"> <Component class="javax.swing.JLabel" name="progressLabel">
<Properties> <Properties>
<Property name="horizontalAlignment" type="int" value="4"/>
<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.progressLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/corecomponents/Bundle.properties" key="DataContentViewerMedia.progressLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>

View File

@ -61,6 +61,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
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 private final Object playbinLock = new Object(); // lock for synchronization of playbin2 player
private VideoProgressWorker videoProgressWorker; private VideoProgressWorker videoProgressWorker;
private int totalHours, totalMinutes, totalSeconds;
/** /**
* Creates new form DataContentViewerVideo * Creates new form DataContentViewerVideo
@ -72,6 +73,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
private void customizeComponents() { private void customizeComponents() {
Gst.init(); Gst.init();
progressSlider.setEnabled(false); // disable slider; enable after user plays vid
progressSlider.addChangeListener(new ChangeListener() { progressSlider.addChangeListener(new ChangeListener() {
/** /**
* Should always try to synchronize any call to * Should always try to synchronize any call to
@ -121,7 +123,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
videoPanel.setLayout(videoPanelLayout); videoPanel.setLayout(videoPanelLayout);
videoPanelLayout.setHorizontalGroup( videoPanelLayout.setHorizontalGroup(
videoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) videoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 283, Short.MAX_VALUE) .addGap(0, 0, Short.MAX_VALUE)
); );
videoPanelLayout.setVerticalGroup( videoPanelLayout.setVerticalGroup(
videoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) videoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -130,6 +132,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
progressSlider.setValue(0); progressSlider.setValue(0);
progressLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
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);
@ -140,10 +143,9 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(pauseButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .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, 158, Short.MAX_VALUE) .addComponent(progressSlider, 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)
.addComponent(progressLabel) .addComponent(progressLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap())
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -152,7 +154,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(pauseButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(pauseButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_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))) .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
@ -315,7 +317,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
progressLabel.setText(" "); progressLabel.setText("");
} }
}); });
synchronized (playbinLock) { synchronized (playbinLock) {
@ -418,7 +420,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
return ExtractMedia.this.cancel(true); return ExtractMedia.this.cancel(true);
} }
}); });
progressLabel.setText("Buffering..."); progressLabel.setText("Buffering... ");
progress.start(); progress.start();
progress.switchToDeterminate(100); progress.switchToDeterminate(100);
try { try {
@ -464,19 +466,20 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
duration = dur.toString(); duration = dur.toString();
durationMillis = dur.toMillis(); durationMillis = dur.toMillis();
// pick out the total hours, minutes, seconds
long durationSeconds = (int)durationMillis / 1000;
totalHours = (int) durationSeconds / 3600;
durationSeconds -= totalHours * 3600;
totalMinutes = (int) durationSeconds / 60;
durationSeconds -= totalMinutes * 60;
totalSeconds = (int) durationSeconds;
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
progressSlider.setMaximum((int) durationMillis); progressSlider.setMaximum((int) durationMillis);
progressSlider.setMinimum(0); progressSlider.setMinimum(0);
final String finalDuration;
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(); playbin2.play();
} }
@ -490,13 +493,18 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
private class VideoProgressWorker extends SwingWorker<Object, Object> { private class VideoProgressWorker extends SwingWorker<Object, Object> {
private String durationFormat = "%02d:%02d:%02d/%02d:%02d:%02d ";
private long millisElapsed = 0;
private final long INTER_FRAME_PERIOD_MS = 20;
private final long END_TIME_MARGIN_MS = 50;
private boolean isPlayBinReady() { private boolean isPlayBinReady() {
synchronized (playbinLock) { synchronized (playbinLock) {
return playbin2 != null && !playbin2.getState().equals(State.NULL); return playbin2 != null && !playbin2.getState().equals(State.NULL);
} }
} }
public void restartVideo() { public void resetVideo() {
synchronized (playbinLock) { synchronized (playbinLock) {
if (playbin2 != null) { if (playbin2 != null) {
playbin2.stop(); playbin2.stop();
@ -505,54 +513,65 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
} }
pauseButton.setText(""); pauseButton.setText("");
progressSlider.setValue(0); progressSlider.setValue(0);
String durationStr = String.format(durationFormat, 0, 0, 0,
totalHours, totalMinutes, totalSeconds);
progressLabel.setText(durationStr);
}
/**
* @return true while millisElapsed is greater than END_TIME_MARGIN_MS
* from durationMillis. This is used to indicate when the video has ended
* because for some videos the time elapsed never becomes equal to the
* reported duration of the video.
*/
private boolean hasNotEnded() {
return (durationMillis - millisElapsed) > END_TIME_MARGIN_MS;
} }
@Override @Override
protected Object doInBackground() throws Exception { protected Object doInBackground() throws Exception {
long positionMillis = 0;
String finalDuration = ""; // enable the slider
while (positionMillis < durationMillis progressSlider.setEnabled(true);
&& isPlayBinReady() && !isCancelled()) {
ClockTime pos = null; int elapsedHours = -1, elapsedMinutes = -1, elapsedSeconds = -1;
ClockTime pos = null;
while (hasNotEnded() && isPlayBinReady() && !isCancelled()) {
synchronized (playbinLock) { synchronized (playbinLock) {
pos = playbin2.queryPosition(); pos = playbin2.queryPosition();
} }
String position = pos.toString(); millisElapsed = pos.toMillis();
positionMillis = pos.toMillis();
if (position.length() == 8) { // pick out the elapsed hours, minutes, seconds
position = position.substring(3); long secondsElapsed = millisElapsed / 1000;
} elapsedHours = (int) secondsElapsed / 3600;
secondsElapsed -= elapsedHours * 3600;
String duration = playbin2.queryDuration().toString(); elapsedMinutes = (int) secondsElapsed / 60;
if (duration.length() == 8 && duration.substring(0, 3).equals("00:")) { secondsElapsed -= elapsedMinutes * 60;
finalDuration = duration.substring(3); elapsedSeconds = (int) secondsElapsed;
progressLabel.setText("00:00/" + duration);
} else { String durationStr = String.format(durationFormat,
finalDuration = duration; elapsedHours, elapsedMinutes, elapsedSeconds,
progressLabel.setText("00:00:00/" + duration); totalHours, totalMinutes, totalSeconds);
}
progressLabel.setText(durationStr);
progressLabel.setText(position + "/" + finalDuration);
autoTracking = true; autoTracking = true;
progressSlider.setValue((int) positionMillis); progressSlider.setValue((int) millisElapsed);
autoTracking = false; autoTracking = false;
try { try {
Thread.sleep(20); Thread.sleep(INTER_FRAME_PERIOD_MS);
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
throw ex; break;
} }
} }
if (finalDuration.length() == 5) { // disable the slider
progressLabel.setText("00:00/" + finalDuration); progressSlider.setEnabled(false);
} else {
progressLabel.setText("00:00:00/" + finalDuration); resetVideo();
}
// If it reached the end
if (progressSlider.getValue() == progressSlider.getMaximum()) {
restartVideo();
}
return null; return null;
} }