From b7cc97c7696fa32759f94cef8c8b3d6e9fae604f Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Tue, 8 Oct 2019 16:14:19 -0400 Subject: [PATCH 1/6] Initial changes --- .../contentviewers/MediaPlayerPanel.java | 88 +++++++++++++------ 1 file changed, 63 insertions(+), 25 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index 5e0c85e807..b25d41d1c9 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -53,6 +53,7 @@ import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.TskData; import javafx.embed.swing.JFXPanel; import javax.swing.event.ChangeListener; +import org.freedesktop.gstreamer.Clock; import org.freedesktop.gstreamer.GstException; /** @@ -179,6 +180,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //Update progress bar and time label during video playback private final Timer timer = new Timer(75, new VideoPanelUpdater()); private static final int PROGRESS_SLIDER_SIZE = 2000; + private static final int SKIP_IN_SECONDS = 30; private ExtractMedia extractMediaWorker; @@ -307,8 +309,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie if (gstPlayBin != null) { gstPlayBin.stop(); gstPlayBin.getBus().disconnect(endOfStreamListener); - gstPlayBin.getBus().disconnect(endOfStreamListener); - gstPlayBin.getBus().disconnect(endOfStreamListener); + gstPlayBin.getBus().disconnect(stateChangeListener); + gstPlayBin.getBus().disconnect(errorListener); gstPlayBin.dispose(); fxAppSink.clear(); gstPlayBin = null; @@ -533,6 +535,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie progressLabel = new javax.swing.JLabel(); VolumeIcon = new javax.swing.JLabel(); audioSlider = new javax.swing.JSlider(); + fastForwardButton = new javax.swing.JButton(); + rewindButton = new javax.swing.JButton(); javax.swing.GroupLayout videoPanelLayout = new javax.swing.GroupLayout(videoPanel); videoPanel.setLayout(videoPanelLayout); @@ -542,7 +546,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie ); videoPanelLayout.setVerticalGroup( videoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 259, Short.MAX_VALUE) + .addGap(0, 257, Short.MAX_VALUE) ); progressSlider.setValue(0); @@ -568,12 +572,20 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie audioSlider.setMajorTickSpacing(10); audioSlider.setMaximum(50); audioSlider.setMinorTickSpacing(5); - audioSlider.setPaintTicks(true); audioSlider.setToolTipText(org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.audioSlider.toolTipText")); // NOI18N audioSlider.setValue(25); audioSlider.setMinimumSize(new java.awt.Dimension(200, 21)); audioSlider.setPreferredSize(new java.awt.Dimension(200, 21)); + org.openide.awt.Mnemonics.setLocalizedText(fastForwardButton, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.fastForwardButton.text")); // NOI18N + fastForwardButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + fastForwardButtonActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(rewindButton, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.rewindButton.text")); // NOI18N + javax.swing.GroupLayout controlPanelLayout = new javax.swing.GroupLayout(controlPanel); controlPanel.setLayout(controlPanelLayout); controlPanelLayout.setHorizontalGroup( @@ -582,34 +594,42 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie .addContainerGap() .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(controlPanelLayout.createSequentialGroup() + .addComponent(infoLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 246, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 73, Short.MAX_VALUE) + .addComponent(rewindButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(playButton, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, 680, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(progressLabel)) - .addGroup(controlPanelLayout.createSequentialGroup() - .addComponent(infoLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGap(18, 18, 18) - .addComponent(VolumeIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(2, 2, 2) - .addComponent(audioSlider, javax.swing.GroupLayout.PREFERRED_SIZE, 229, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(fastForwardButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 191, Short.MAX_VALUE) + .addComponent(VolumeIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(audioSlider, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addComponent(progressLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); controlPanelLayout.setVerticalGroup( controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(controlPanelLayout.createSequentialGroup() + .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(progressLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)) .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(progressLabel, 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(playButton)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(audioSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(VolumeIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(infoLabel))) - .addGap(13, 13, 13)) + .addGroup(controlPanelLayout.createSequentialGroup() + .addGap(17, 17, 17) + .addComponent(infoLabel)) + .addGroup(controlPanelLayout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(VolumeIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(playButton) + .addComponent(fastForwardButton) + .addComponent(rewindButton)) + .addComponent(audioSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap(13, Short.MAX_VALUE)) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -636,15 +656,33 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie } }//GEN-LAST:event_playButtonActionPerformed + private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed + long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); + Clock playbinClock = gstPlayBin.getClock(); + long currentTime = playbinClock.getTime(); + //Skip 30 seconds. + long skipAhead = TimeUnit.SECONDS.convert(SKIP_IN_SECONDS, TimeUnit.NANOSECONDS); + //Ensure new video position is within bounds + long newTime = Math.max(currentTime + skipAhead, duration); + gstPlayBin.seek(newTime, TimeUnit.NANOSECONDS); + //0 <= newTimePercent <= 1.0 + double newTimePercent = ((double)newTime)/duration; + //0 <= newProgressSliderPos <= PROGRESS_SLIDER_SIZE + int newProgressSliderPos = (int)(PROGRESS_SLIDER_SIZE * newTimePercent); + progressSlider.setValue(newProgressSliderPos); + }//GEN-LAST:event_fastForwardButtonActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel VolumeIcon; private javax.swing.JSlider audioSlider; private javax.swing.JPanel controlPanel; + private javax.swing.JButton fastForwardButton; private javax.swing.JLabel infoLabel; private javax.swing.JButton playButton; private javax.swing.JLabel progressLabel; private javax.swing.JSlider progressSlider; + private javax.swing.JButton rewindButton; private javax.swing.JPanel videoPanel; // End of variables declaration//GEN-END:variables } From b3aaf99c72c5cd75abd9a3a0237986a3a20666f2 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 9 Oct 2019 15:22:32 -0400 Subject: [PATCH 2/6] Incremental improvements --- .../contentviewers/MediaPlayerPanel.form | 186 ++++++++++------- .../contentviewers/MediaPlayerPanel.java | 191 +++++++++++------- 2 files changed, 230 insertions(+), 147 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form index 880528e787..c1c04e24c2 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form @@ -1,6 +1,6 @@ -
+ @@ -41,7 +41,7 @@ - + @@ -51,47 +51,33 @@ - - + + - - - - - + + + + + - - - - - - - - + - - - - - - + + + + - - - - - - - - - + + + + @@ -112,8 +98,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -122,48 +202,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index 2ba5548724..06ce6f785d 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -53,7 +53,6 @@ import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.TskData; import javafx.embed.swing.JFXPanel; import javax.swing.event.ChangeListener; -import org.freedesktop.gstreamer.Clock; import org.freedesktop.gstreamer.GstException; /** @@ -242,12 +241,14 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie endOfStreamListener = new Bus.EOS() { @Override public void endOfStream(GstObject go) { - gstPlayBin.seek(ClockTime.ZERO); - progressSlider.setValue(0); + playButton.setText("►"); + System.out.println(gstPlayBin.getState()); + //gstPlayBin.seek(ClockTime.ZERO); + //progressSlider.setValue(0); /** * Keep the video from automatically playing */ - Gst.getExecutor().submit(() -> gstPlayBin.pause()); + //Gst.getExecutor().submit(() -> gstPlayBin.pause()); } }; } @@ -390,19 +391,13 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie return Bundle.MediaPlayerPanel_unknownTime(); } - double millis = ns / 1000000.0; - double seconds; - if (ceiling) { - seconds = Math.ceil(millis / 1000); - } else { - seconds = millis / 1000; - } - double hours = seconds / 3600; - seconds -= (int) hours * 3600; - double minutes = seconds / 60; - seconds -= (int) minutes * 60; + long seconds = TimeUnit.SECONDS.convert(ns, TimeUnit.NANOSECONDS); + long hours = TimeUnit.HOURS.convert(seconds, TimeUnit.SECONDS); + seconds -= TimeUnit.SECONDS.convert(hours, TimeUnit.HOURS); + long minutes = TimeUnit.MINUTES.convert(seconds, TimeUnit.SECONDS); + seconds -= TimeUnit.SECONDS.convert(minutes, TimeUnit.MINUTES); - return String.format(Bundle.MediaPlayerPanel_timeFormat(), (int) hours, (int) minutes, (int) seconds); + return String.format(Bundle.MediaPlayerPanel_timeFormat(), hours, minutes, seconds); } /** @@ -526,17 +521,19 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; videoPanel = new javax.swing.JPanel(); controlPanel = new javax.swing.JPanel(); progressSlider = new javax.swing.JSlider(); - infoLabel = new javax.swing.JLabel(); - playButton = new javax.swing.JButton(); progressLabel = new javax.swing.JLabel(); - VolumeIcon = new javax.swing.JLabel(); - audioSlider = new javax.swing.JSlider(); + jPanel1 = new javax.swing.JPanel(); + playButton = new javax.swing.JButton(); fastForwardButton = new javax.swing.JButton(); rewindButton = new javax.swing.JButton(); + VolumeIcon = new javax.swing.JLabel(); + audioSlider = new javax.swing.JSlider(); + infoLabel = new javax.swing.JLabel(); javax.swing.GroupLayout videoPanelLayout = new javax.swing.GroupLayout(videoPanel); videoPanel.setLayout(videoPanelLayout); @@ -546,7 +543,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie ); videoPanelLayout.setVerticalGroup( videoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 257, Short.MAX_VALUE) + .addGap(0, 124, Short.MAX_VALUE) ); progressSlider.setValue(0); @@ -555,8 +552,9 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie progressSlider.setMinimumSize(new java.awt.Dimension(36, 21)); progressSlider.setPreferredSize(new java.awt.Dimension(200, 21)); - org.openide.awt.Mnemonics.setLocalizedText(infoLabel, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.infoLabel.text")); // NOI18N - infoLabel.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); + org.openide.awt.Mnemonics.setLocalizedText(progressLabel, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.progressLabel.text")); // NOI18N + + jPanel1.setLayout(new java.awt.GridBagLayout()); org.openide.awt.Mnemonics.setLocalizedText(playButton, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.playButton.text")); // NOI18N playButton.addActionListener(new java.awt.event.ActionListener() { @@ -564,10 +562,50 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie playButtonActionPerformed(evt); } }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 0; + gridBagConstraints.ipadx = 21; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(5, 6, 0, 0); + jPanel1.add(playButton, gridBagConstraints); - org.openide.awt.Mnemonics.setLocalizedText(progressLabel, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.progressLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(fastForwardButton, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.fastForwardButton.text")); // NOI18N + fastForwardButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + fastForwardButtonActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(5, 6, 0, 0); + jPanel1.add(fastForwardButton, gridBagConstraints); + + org.openide.awt.Mnemonics.setLocalizedText(rewindButton, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.rewindButton.text")); // NOI18N + rewindButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + rewindButtonActionPerformed(evt); + } + }); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(5, 0, 1, 0); + jPanel1.add(rewindButton, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(VolumeIcon, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.VolumeIcon.text")); // NOI18N + VolumeIcon.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 0; + gridBagConstraints.ipadx = 8; + gridBagConstraints.ipady = 7; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(6, 6, 0, 0); + jPanel1.add(VolumeIcon, gridBagConstraints); audioSlider.setMajorTickSpacing(10); audioSlider.setMaximum(50); @@ -576,60 +614,45 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie audioSlider.setValue(25); audioSlider.setMinimumSize(new java.awt.Dimension(200, 21)); audioSlider.setPreferredSize(new java.awt.Dimension(200, 21)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 0; + gridBagConstraints.ipadx = -116; + gridBagConstraints.ipady = 7; + gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new java.awt.Insets(3, 1, 0, 10); + jPanel1.add(audioSlider, gridBagConstraints); - org.openide.awt.Mnemonics.setLocalizedText(fastForwardButton, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.fastForwardButton.text")); // NOI18N - fastForwardButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - fastForwardButtonActionPerformed(evt); - } - }); - - org.openide.awt.Mnemonics.setLocalizedText(rewindButton, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.rewindButton.text")); // NOI18N + infoLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + org.openide.awt.Mnemonics.setLocalizedText(infoLabel, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.infoLabel.text")); // NOI18N + infoLabel.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR)); javax.swing.GroupLayout controlPanelLayout = new javax.swing.GroupLayout(controlPanel); controlPanel.setLayout(controlPanelLayout); controlPanelLayout.setHorizontalGroup( controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, controlPanelLayout.createSequentialGroup() + .addGroup(controlPanelLayout.createSequentialGroup() .addContainerGap() .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(controlPanelLayout.createSequentialGroup() - .addComponent(infoLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 246, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 73, Short.MAX_VALUE) - .addComponent(rewindButton) + .addComponent(infoLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 1090, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, controlPanelLayout.createSequentialGroup() + .addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(playButton, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(fastForwardButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 191, Short.MAX_VALUE) - .addComponent(VolumeIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(audioSlider, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) - .addComponent(progressLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(progressLabel))) .addContainerGap()) ); controlPanelLayout.setVerticalGroup( controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(controlPanelLayout.createSequentialGroup() + .addGap(0, 0, 0) .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(progressLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE)) - .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(controlPanelLayout.createSequentialGroup() - .addGap(17, 17, 17) - .addComponent(infoLabel)) - .addGroup(controlPanelLayout.createSequentialGroup() - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(VolumeIcon, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(playButton) - .addComponent(fastForwardButton) - .addComponent(rewindButton)) - .addComponent(audioSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) - .addContainerGap(13, Short.MAX_VALUE)) + .addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(infoLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 28, Short.MAX_VALUE)) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -648,6 +671,28 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie ); }// //GEN-END:initComponents + private void rewindButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rewindButtonActionPerformed + long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + //Skip 30 seconds. + long skipBehind = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); + //Ensure new video position is within bounds + long newTime = Math.max(currentTime - skipBehind, 0); + gstPlayBin.seek(newTime, TimeUnit.NANOSECONDS); + syncProgressSlider(newTime, duration); + }//GEN-LAST:event_rewindButtonActionPerformed + + private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed + long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + //Skip 30 seconds. + long skipAhead = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); + //Ensure new video position is within bounds + long newTime = Math.min(currentTime + skipAhead, duration); + gstPlayBin.seek(newTime, TimeUnit.NANOSECONDS); + syncProgressSlider(newTime, duration); + }//GEN-LAST:event_fastForwardButtonActionPerformed + private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed if (gstPlayBin.isPlaying()) { gstPlayBin.pause(); @@ -656,22 +701,21 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie } }//GEN-LAST:event_playButtonActionPerformed - private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed - long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); - Clock playbinClock = gstPlayBin.getClock(); - long currentTime = playbinClock.getTime(); - //Skip 30 seconds. - long skipAhead = TimeUnit.SECONDS.convert(SKIP_IN_SECONDS, TimeUnit.NANOSECONDS); - //Ensure new video position is within bounds - long newTime = Math.max(currentTime + skipAhead, duration); - gstPlayBin.seek(newTime, TimeUnit.NANOSECONDS); + /** + * Sync progress slider to the newTime position if it is not already there. + * + * @param newTime New time value that progress slider may or may not be positioned at + * @param duration Total duration of the video, used for determining slider position + */ + private void syncProgressSlider(long newTime, long duration) { //0 <= newTimePercent <= 1.0 double newTimePercent = ((double)newTime)/duration; //0 <= newProgressSliderPos <= PROGRESS_SLIDER_SIZE int newProgressSliderPos = (int)(PROGRESS_SLIDER_SIZE * newTimePercent); progressSlider.setValue(newProgressSliderPos); - }//GEN-LAST:event_fastForwardButtonActionPerformed - + updateTimeLabel(newTime, duration); + } + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel VolumeIcon; @@ -679,6 +723,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie private javax.swing.JPanel controlPanel; private javax.swing.JButton fastForwardButton; private javax.swing.JLabel infoLabel; + private javax.swing.JPanel jPanel1; private javax.swing.JButton playButton; private javax.swing.JLabel progressLabel; private javax.swing.JSlider progressSlider; From b2d4e220301f7606e1a2f158a00c6ee93173eed3 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 10 Oct 2019 15:09:52 -0400 Subject: [PATCH 3/6] Finished implementing and testing fast forward/rewind buttons --- .../contentviewers/MediaPlayerPanel.form | 2 +- .../contentviewers/MediaPlayerPanel.java | 37 +++---------------- 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form index c1c04e24c2..449e3c09ea 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form @@ -55,7 +55,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index 06ce6f785d..98f3350e87 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -37,7 +37,6 @@ import javax.swing.SwingWorker; import javax.swing.Timer; import javax.swing.event.ChangeEvent; import org.freedesktop.gstreamer.Bus; -import org.freedesktop.gstreamer.ClockTime; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.State; @@ -53,6 +52,7 @@ import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.TskData; import javafx.embed.swing.JFXPanel; import javax.swing.event.ChangeListener; +import org.freedesktop.gstreamer.ClockTime; import org.freedesktop.gstreamer.GstException; /** @@ -241,14 +241,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie endOfStreamListener = new Bus.EOS() { @Override public void endOfStream(GstObject go) { - playButton.setText("►"); - System.out.println(gstPlayBin.getState()); - //gstPlayBin.seek(ClockTime.ZERO); - //progressSlider.setValue(0); - /** - * Keep the video from automatically playing - */ - //Gst.getExecutor().submit(() -> gstPlayBin.pause()); + Gst.getExecutor().submit(() -> gstPlayBin.pause()); + gstPlayBin.seek(ClockTime.ZERO); } }; } @@ -376,7 +370,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie * @param total */ private void updateTimeLabel(long start, long total) { - progressLabel.setText(formatTime(start, false) + "/" + formatTime(total, true)); + progressLabel.setText(formatTime(start) + "/" + formatTime(total)); } /** @@ -386,7 +380,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie "MediaPlayerPanel.unknownTime=Unknown", "MediaPlayerPanel.timeFormat=%02d:%02d:%02d" }) - private String formatTime(long ns, boolean ceiling) { + private String formatTime(long ns) { if (ns == -1) { return Bundle.MediaPlayerPanel_unknownTime(); } @@ -635,7 +629,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie .addContainerGap() .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(infoLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 1090, Short.MAX_VALUE) + .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 738, Short.MAX_VALUE) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, controlPanelLayout.createSequentialGroup() .addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -672,14 +666,12 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie }// //GEN-END:initComponents private void rewindButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rewindButtonActionPerformed - long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); //Skip 30 seconds. long skipBehind = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); //Ensure new video position is within bounds long newTime = Math.max(currentTime - skipBehind, 0); gstPlayBin.seek(newTime, TimeUnit.NANOSECONDS); - syncProgressSlider(newTime, duration); }//GEN-LAST:event_rewindButtonActionPerformed private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed @@ -690,7 +682,6 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //Ensure new video position is within bounds long newTime = Math.min(currentTime + skipAhead, duration); gstPlayBin.seek(newTime, TimeUnit.NANOSECONDS); - syncProgressSlider(newTime, duration); }//GEN-LAST:event_fastForwardButtonActionPerformed private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed @@ -701,22 +692,6 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie } }//GEN-LAST:event_playButtonActionPerformed - /** - * Sync progress slider to the newTime position if it is not already there. - * - * @param newTime New time value that progress slider may or may not be positioned at - * @param duration Total duration of the video, used for determining slider position - */ - private void syncProgressSlider(long newTime, long duration) { - //0 <= newTimePercent <= 1.0 - double newTimePercent = ((double)newTime)/duration; - //0 <= newProgressSliderPos <= PROGRESS_SLIDER_SIZE - int newProgressSliderPos = (int)(PROGRESS_SLIDER_SIZE * newTimePercent); - progressSlider.setValue(newProgressSliderPos); - updateTimeLabel(newTime, duration); - } - - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel VolumeIcon; private javax.swing.JSlider audioSlider; From 2b946af86966db1504da71ad5225e23f6176faa4 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 10 Oct 2019 16:07:23 -0400 Subject: [PATCH 4/6] Disallow seeking to immediate end (buggy when doing so), add budnle files --- .../autopsy/contentviewers/Bundle.properties | 8 ++-- .../contentviewers/Bundle.properties-MERGED | 8 ++-- .../contentviewers/MediaPlayerPanel.form | 6 +-- .../contentviewers/MediaPlayerPanel.java | 48 +++++++++++-------- 4 files changed, 40 insertions(+), 30 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties index c799a17d61..5734df98d9 100644 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties @@ -84,9 +84,11 @@ MediaViewImagePanel.zoomTextField.text= MediaViewImagePanel.rotationTextField.text= MediaViewImagePanel.rotateLeftButton.toolTipText= HtmlPanel.showImagesToggleButton.text=Download Images -MediaPlayerPanel.audioSlider.toolTipText= -MediaPlayerPanel.VolumeIcon.text=\ \ \ \ \ Volume +MediaViewImagePanel.tagsMenu.text_1=Tags Menu MediaPlayerPanel.progressLabel.text=00:00:00/00:00:00 +MediaPlayerPanel.audioSlider.toolTipText= +MediaPlayerPanel.rewindButton.text=\u2bc7\u2bc7 +MediaPlayerPanel.fastForwardButton.text=\u25ba\u25ba MediaPlayerPanel.playButton.text=\u25ba MediaPlayerPanel.infoLabel.text=No Errors -MediaViewImagePanel.tagsMenu.text_1=Tags Menu +MediaPlayerPanel.VolumeIcon.text=\ \ \ \ \ Volume diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED index ff3341b60f..1209c49953 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED @@ -154,12 +154,14 @@ MediaViewImagePanel.zoomTextField.text= MediaViewImagePanel.rotationTextField.text= MediaViewImagePanel.rotateLeftButton.toolTipText= HtmlPanel.showImagesToggleButton.text=Download Images -MediaPlayerPanel.audioSlider.toolTipText= -MediaPlayerPanel.VolumeIcon.text=\ \ \ \ \ Volume +MediaViewImagePanel.tagsMenu.text_1=Tags Menu MediaPlayerPanel.progressLabel.text=00:00:00/00:00:00 +MediaPlayerPanel.audioSlider.toolTipText= +MediaPlayerPanel.rewindButton.text=\u2bc7\u2bc7 +MediaPlayerPanel.fastForwardButton.text=\u25ba\u25ba MediaPlayerPanel.playButton.text=\u25ba MediaPlayerPanel.infoLabel.text=No Errors -MediaViewImagePanel.tagsMenu.text_1=Tags Menu +MediaPlayerPanel.VolumeIcon.text=\ \ \ \ \ Volume # {0} - tableName SQLiteViewer.readTable.errorText=Error getting rows for table: {0} # {0} - tableName diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form index 449e3c09ea..230254020d 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form @@ -55,7 +55,7 @@ - + @@ -75,7 +75,7 @@ - + @@ -105,7 +105,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index 98f3350e87..1d02dfcd2b 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -241,8 +241,12 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie endOfStreamListener = new Bus.EOS() { @Override public void endOfStream(GstObject go) { + gstPlayBin.seek(ClockTime.ZERO); + progressSlider.setValue(0); + /** + * Keep the video from automatically playing + */ Gst.getExecutor().submit(() -> gstPlayBin.pause()); - gstPlayBin.seek(ClockTime.ZERO); } }; } @@ -265,7 +269,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie try { //Pushing off initialization to the background extractMediaWorker = new ExtractMedia(file, VideoUtils.getVideoFileInTempDir(file)); - extractMediaWorker.execute(); + extractMediaWorker.execute(); } catch (NoCurrentCaseException ex) { logger.log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS infoLabel.setText(String.format("%s", Bundle.GstVideoPanel_noOpenCase_errMsg())); @@ -314,6 +318,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie progressSlider.setEnabled(isEnabled); videoPanel.setEnabled(isEnabled); audioSlider.setEnabled(isEnabled); + rewindButton.setEnabled(isEnabled); + fastForwardButton.setEnabled(isEnabled); } @Override @@ -434,8 +440,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie protected void done() { try { super.get(); - - if(this.isCancelled()) { + + if (this.isCancelled()) { return; } @@ -451,8 +457,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie playBinBus.connect(endOfStreamListener); playBinBus.connect(stateChangeListener); playBinBus.connect(errorListener); - - if(this.isCancelled()) { + + if (this.isCancelled()) { return; } @@ -462,14 +468,14 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie videoPanel.add(fxPanel); fxAppSink = new JavaFxAppSink("JavaFxAppSink", fxPanel); gstPlayBin.setVideoSink(fxAppSink); - - if(this.isCancelled()) { + + if (this.isCancelled()) { return; } gstPlayBin.setVolume((audioSlider.getValue() * 2.0) / 100.0); gstPlayBin.pause(); - + timer.start(); enableComponents(true); } catch (CancellationException ex) { @@ -497,7 +503,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie * pipeline. We start this updater when data-flow has just been * initiated so buffering may still be in progress. */ - if (duration != -1) { + if (duration > 0 && position > 0) { double relativePosition = (double) position / duration; progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE)); } @@ -521,7 +527,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie controlPanel = new javax.swing.JPanel(); progressSlider = new javax.swing.JSlider(); progressLabel = new javax.swing.JLabel(); - jPanel1 = new javax.swing.JPanel(); + buttonPanel = new javax.swing.JPanel(); playButton = new javax.swing.JButton(); fastForwardButton = new javax.swing.JButton(); rewindButton = new javax.swing.JButton(); @@ -548,7 +554,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie org.openide.awt.Mnemonics.setLocalizedText(progressLabel, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.progressLabel.text")); // NOI18N - jPanel1.setLayout(new java.awt.GridBagLayout()); + buttonPanel.setLayout(new java.awt.GridBagLayout()); org.openide.awt.Mnemonics.setLocalizedText(playButton, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.playButton.text")); // NOI18N playButton.addActionListener(new java.awt.event.ActionListener() { @@ -562,7 +568,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie gridBagConstraints.ipadx = 21; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.insets = new java.awt.Insets(5, 6, 0, 0); - jPanel1.add(playButton, gridBagConstraints); + buttonPanel.add(playButton, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(fastForwardButton, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.fastForwardButton.text")); // NOI18N fastForwardButton.addActionListener(new java.awt.event.ActionListener() { @@ -575,7 +581,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.insets = new java.awt.Insets(5, 6, 0, 0); - jPanel1.add(fastForwardButton, gridBagConstraints); + buttonPanel.add(fastForwardButton, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(rewindButton, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.rewindButton.text")); // NOI18N rewindButton.addActionListener(new java.awt.event.ActionListener() { @@ -588,7 +594,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.insets = new java.awt.Insets(5, 0, 1, 0); - jPanel1.add(rewindButton, gridBagConstraints); + buttonPanel.add(rewindButton, gridBagConstraints); org.openide.awt.Mnemonics.setLocalizedText(VolumeIcon, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.VolumeIcon.text")); // NOI18N VolumeIcon.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT); @@ -599,7 +605,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie gridBagConstraints.ipady = 7; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.insets = new java.awt.Insets(6, 6, 0, 0); - jPanel1.add(VolumeIcon, gridBagConstraints); + buttonPanel.add(VolumeIcon, gridBagConstraints); audioSlider.setMajorTickSpacing(10); audioSlider.setMaximum(50); @@ -615,7 +621,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie gridBagConstraints.ipady = 7; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.insets = new java.awt.Insets(3, 1, 0, 10); - jPanel1.add(audioSlider, gridBagConstraints); + buttonPanel.add(audioSlider, gridBagConstraints); infoLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); org.openide.awt.Mnemonics.setLocalizedText(infoLabel, org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.infoLabel.text")); // NOI18N @@ -629,7 +635,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie .addContainerGap() .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(infoLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 738, Short.MAX_VALUE) + .addComponent(buttonPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 738, Short.MAX_VALUE) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, controlPanelLayout.createSequentialGroup() .addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -644,7 +650,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie .addComponent(progressLabel, 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)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(buttonPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(infoLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 28, Short.MAX_VALUE)) ); @@ -680,7 +686,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //Skip 30 seconds. long skipAhead = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); //Ensure new video position is within bounds - long newTime = Math.min(currentTime + skipAhead, duration); + long newTime = Math.min(currentTime + skipAhead, duration - 1); gstPlayBin.seek(newTime, TimeUnit.NANOSECONDS); }//GEN-LAST:event_fastForwardButtonActionPerformed @@ -695,10 +701,10 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JLabel VolumeIcon; private javax.swing.JSlider audioSlider; + private javax.swing.JPanel buttonPanel; private javax.swing.JPanel controlPanel; private javax.swing.JButton fastForwardButton; private javax.swing.JLabel infoLabel; - private javax.swing.JPanel jPanel1; private javax.swing.JButton playButton; private javax.swing.JLabel progressLabel; private javax.swing.JSlider progressSlider; From a1477dc45e5ee966c8b83c1c04472b4b81940c7a Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 17 Oct 2019 10:30:12 -0400 Subject: [PATCH 5/6] Updated the seek to be more accurate --- .../contentviewers/MediaPlayerPanel.java | 58 ++++++++++++++----- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index 1d02dfcd2b..b9a14df207 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -24,6 +24,7 @@ import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.util.Arrays; +import java.util.EnumSet; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; @@ -53,7 +54,10 @@ import org.sleuthkit.datamodel.TskData; import javafx.embed.swing.JFXPanel; import javax.swing.event.ChangeListener; import org.freedesktop.gstreamer.ClockTime; +import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.GstException; +import org.freedesktop.gstreamer.event.SeekFlags; +import org.freedesktop.gstreamer.event.SeekType; /** * This is a video player that is part of the Media View layered pane. It uses @@ -175,6 +179,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie private Bus.ERROR errorListener; private Bus.STATE_CHANGED stateChangeListener; private Bus.EOS endOfStreamListener; + private double playBackRate; //Update progress bar and time label during video playback private final Timer timer = new Timer(75, new VideoPanelUpdater()); @@ -196,6 +201,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie progressSlider.setMinimum(0); progressSlider.setMaximum(PROGRESS_SLIDER_SIZE); progressSlider.setValue(0); + playBackRate = 1.0; //Manage the gstreamer video position when a user is dragging the slider in the panel. progressSlider.addChangeListener(new ChangeListener() { @Override @@ -203,11 +209,19 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie if (progressSlider.getValueIsAdjusting()) { long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); double relativePosition = progressSlider.getValue() * 1.0 / PROGRESS_SLIDER_SIZE; - long newPos = (long) (relativePosition * duration); - gstPlayBin.seek(newPos, TimeUnit.NANOSECONDS); + long newStartTime = (long) (relativePosition * duration); + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the start position to newTime + SeekType.SET, newStartTime, + //Do nothing for the end position + SeekType.NONE, -1); //Keep constantly updating the time label so users have a sense of //where the slider they are dragging is in relation to the video time - updateTimeLabel(newPos, duration); + updateTimeLabel(newStartTime, duration); } } }); @@ -241,11 +255,11 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie endOfStreamListener = new Bus.EOS() { @Override public void endOfStream(GstObject go) { - gstPlayBin.seek(ClockTime.ZERO); - progressSlider.setValue(0); - /** - * Keep the video from automatically playing - */ + gstPlayBin.seek(ClockTime.ZERO); + progressSlider.setValue(0); + /** + * Keep the video from automatically playing + */ Gst.getExecutor().submit(() -> gstPlayBin.pause()); } }; @@ -674,20 +688,36 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie private void rewindButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rewindButtonActionPerformed long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); //Skip 30 seconds. - long skipBehind = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); + long rewindDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); //Ensure new video position is within bounds - long newTime = Math.max(currentTime - skipBehind, 0); - gstPlayBin.seek(newTime, TimeUnit.NANOSECONDS); + long newTime = Math.max(currentTime - rewindDelta, 0); + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the start position to newTime + SeekType.SET, newTime, + //Do nothing for the end position + SeekType.NONE, -1); }//GEN-LAST:event_rewindButtonActionPerformed private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); //Skip 30 seconds. - long skipAhead = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); + long fastForwardDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); //Ensure new video position is within bounds - long newTime = Math.min(currentTime + skipAhead, duration - 1); - gstPlayBin.seek(newTime, TimeUnit.NANOSECONDS); + long newTime = Math.min(currentTime + fastForwardDelta, duration); + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the start position to newTime + SeekType.SET, newTime, + //Do nothing for the end position + SeekType.NONE, -1); }//GEN-LAST:event_fastForwardButtonActionPerformed private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed From 8be5b01e0c2f8dfdac398b3db1a48a270d8e7f8d Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Fri, 18 Oct 2019 09:48:46 -0400 Subject: [PATCH 6/6] ignored ffw requests with less than 30s left, fixed bug with progress updating --- .../autopsy/contentviewers/MediaPlayerPanel.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index b9a14df207..cce6d3687f 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -517,7 +517,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie * pipeline. We start this updater when data-flow has just been * initiated so buffering may still be in progress. */ - if (duration > 0 && position > 0) { + if (duration >= 0 && position >= 0) { double relativePosition = (double) position / duration; progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE)); } @@ -707,8 +707,13 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); //Skip 30 seconds. long fastForwardDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); - //Ensure new video position is within bounds - long newTime = Math.min(currentTime + fastForwardDelta, duration); + + //Ignore fast forward requests if there are less than 30 seconds left. + if(currentTime + fastForwardDelta >= duration) { + return; + } + + long newTime = currentTime + fastForwardDelta; gstPlayBin.seek(playBackRate, Format.TIME, //FLUSH - flushes the pipeline