Updated the seek to be more accurate

This commit is contained in:
U-BASIS\dsmyda 2019-10-17 10:30:12 -04:00
parent 2b946af869
commit a1477dc45e

View File

@ -24,6 +24,7 @@ import java.awt.event.ActionListener;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
@ -53,7 +54,10 @@ import org.sleuthkit.datamodel.TskData;
import javafx.embed.swing.JFXPanel; import javafx.embed.swing.JFXPanel;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import org.freedesktop.gstreamer.ClockTime; import org.freedesktop.gstreamer.ClockTime;
import org.freedesktop.gstreamer.Format;
import org.freedesktop.gstreamer.GstException; 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 * 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.ERROR errorListener;
private Bus.STATE_CHANGED stateChangeListener; private Bus.STATE_CHANGED stateChangeListener;
private Bus.EOS endOfStreamListener; private Bus.EOS endOfStreamListener;
private double playBackRate;
//Update progress bar and time label during video playback //Update progress bar and time label during video playback
private final Timer timer = new Timer(75, new VideoPanelUpdater()); 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.setMinimum(0);
progressSlider.setMaximum(PROGRESS_SLIDER_SIZE); progressSlider.setMaximum(PROGRESS_SLIDER_SIZE);
progressSlider.setValue(0); progressSlider.setValue(0);
playBackRate = 1.0;
//Manage the gstreamer video position when a user is dragging the slider in the panel. //Manage the gstreamer video position when a user is dragging the slider in the panel.
progressSlider.addChangeListener(new ChangeListener() { progressSlider.addChangeListener(new ChangeListener() {
@Override @Override
@ -203,11 +209,19 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
if (progressSlider.getValueIsAdjusting()) { if (progressSlider.getValueIsAdjusting()) {
long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS);
double relativePosition = progressSlider.getValue() * 1.0 / PROGRESS_SLIDER_SIZE; double relativePosition = progressSlider.getValue() * 1.0 / PROGRESS_SLIDER_SIZE;
long newPos = (long) (relativePosition * duration); long newStartTime = (long) (relativePosition * duration);
gstPlayBin.seek(newPos, TimeUnit.NANOSECONDS); 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 //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 //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() { endOfStreamListener = new Bus.EOS() {
@Override @Override
public void endOfStream(GstObject go) { public void endOfStream(GstObject go) {
gstPlayBin.seek(ClockTime.ZERO); gstPlayBin.seek(ClockTime.ZERO);
progressSlider.setValue(0); progressSlider.setValue(0);
/** /**
* Keep the video from automatically playing * Keep the video from automatically playing
*/ */
Gst.getExecutor().submit(() -> gstPlayBin.pause()); 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 private void rewindButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rewindButtonActionPerformed
long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS);
//Skip 30 seconds. //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 //Ensure new video position is within bounds
long newTime = Math.max(currentTime - skipBehind, 0); long newTime = Math.max(currentTime - rewindDelta, 0);
gstPlayBin.seek(newTime, TimeUnit.NANOSECONDS); 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 }//GEN-LAST:event_rewindButtonActionPerformed
private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed
long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS);
long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS);
//Skip 30 seconds. //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 //Ensure new video position is within bounds
long newTime = Math.min(currentTime + skipAhead, duration - 1); long newTime = Math.min(currentTime + fastForwardDelta, duration);
gstPlayBin.seek(newTime, TimeUnit.NANOSECONDS); 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 }//GEN-LAST:event_fastForwardButtonActionPerformed
private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed