Fixed codacy, the bug will reported, the bug seen in demos

This commit is contained in:
U-BASIS\dsmyda 2019-04-01 14:29:36 -04:00
parent f039aa6601
commit c38dc25456
5 changed files with 73 additions and 51 deletions

View File

@ -39,8 +39,9 @@ GstVideoPanel.ExtractMedia.progress.buffering=Buffering {0}
MediaFileViewer.AccessibleContext.accessibleDescription= MediaFileViewer.AccessibleContext.accessibleDescription=
MediaFileViewer.title=Media MediaFileViewer.title=Media
MediaFileViewer.toolTip=Displays supported multimedia files (images, videos, audio) MediaFileViewer.toolTip=Displays supported multimedia files (images, videos, audio)
MediaPlayerPanel.noSupport=File not supported.
MediaPlayerPanel.timeFormat=%02d:%02d:%02d MediaPlayerPanel.timeFormat=%02d:%02d:%02d
MediaPlayerPanel.unknownTime=UNKNOWN MediaPlayerPanel.unknownTime=Unknown
MediaViewImagePanel.errorLabel.OOMText=Could not load file into Media View: insufficent memory. MediaViewImagePanel.errorLabel.OOMText=Could not load file into Media View: insufficent memory.
MediaViewImagePanel.errorLabel.text=Could not load file into Media View. MediaViewImagePanel.errorLabel.text=Could not load file into Media View.
MediaViewImagePanel.externalViewerButton.text=Open in External Viewer Ctrl+E MediaViewImagePanel.externalViewerButton.text=Open in External Viewer Ctrl+E

View File

@ -69,6 +69,8 @@ final class JavaFxAppSink extends AppSink {
* Clear the current frame in the JFXPanel * Clear the current frame in the JFXPanel
*/ */
public void clear() { public void clear() {
disconnect((AppSink.NEW_SAMPLE) updater);
disconnect((AppSink.NEW_PREROLL) updater);
updater.clear(); updater.clear();
} }
@ -80,6 +82,8 @@ final class JavaFxAppSink extends AppSink {
private final ImageView fxImageView; private final ImageView fxImageView;
public JavaFxFrameUpdater(JFXPanel target) { public JavaFxFrameUpdater(JFXPanel target) {
//We should probably pass an ImageView instead of a JFXPanel to make
//it more reuseable
fxImageView = new ImageView(); // Will hold the current video frame. fxImageView = new ImageView(); // Will hold the current video frame.
BorderPane borderpane = new BorderPane(fxImageView); // Center and size ImageView. BorderPane borderpane = new BorderPane(fxImageView); // Center and size ImageView.
Scene scene = new Scene(borderpane); // Root of the JavaFX tree. Scene scene = new Scene(borderpane); // Root of the JavaFX tree.
@ -95,7 +99,6 @@ final class JavaFxAppSink extends AppSink {
/** /**
* Updates the ImageView when a brand new frame is in the pipeline. * Updates the ImageView when a brand new frame is in the pipeline.
* Note here we retrieve that new frame with pullSample().
* *
* @param appSink Pipeline containing the new frame * @param appSink Pipeline containing the new frame
* @return Result of update * @return Result of update

View File

@ -23,6 +23,7 @@ import java.awt.Component;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import org.freedesktop.gstreamer.GstException;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
@ -53,7 +54,7 @@ class MediaFileViewer extends javax.swing.JPanel implements FileTypeViewer {
try { try {
mediaPlayerPanel = new MediaPlayerPanel(); mediaPlayerPanel = new MediaPlayerPanel();
} catch (Exception ex) { } catch (GstException | UnsatisfiedLinkError ex) {
LOGGER.log(Level.SEVERE, "Error initializing gstreamer for audio/video viewing and frame extraction capabilities", ex); //NON-NLS LOGGER.log(Level.SEVERE, "Error initializing gstreamer for audio/video viewing and frame extraction capabilities", ex); //NON-NLS
MessageNotifyUtil.Notify.error( MessageNotifyUtil.Notify.error(
NbBundle.getMessage(this.getClass(), "MediaFileViewer.initGst.gstException.msg"), NbBundle.getMessage(this.getClass(), "MediaFileViewer.initGst.gstException.msg"),
@ -68,7 +69,10 @@ class MediaFileViewer extends javax.swing.JPanel implements FileTypeViewer {
private void customizeComponents() { private void customizeComponents() {
add(imagePanel, IMAGE_VIEWER_LAYER); add(imagePanel, IMAGE_VIEWER_LAYER);
add(mediaPlayerPanel, MEDIA_PLAYER_LAYER);
if(mediaPlayerPanel != null) {
add(mediaPlayerPanel, MEDIA_PLAYER_LAYER);
}
showImagePanel(); showImagePanel();
} }
@ -99,7 +103,9 @@ class MediaFileViewer extends javax.swing.JPanel implements FileTypeViewer {
List<String> mimeTypes = new ArrayList<>(); List<String> mimeTypes = new ArrayList<>();
mimeTypes.addAll(this.imagePanel.getSupportedMimeTypes()); mimeTypes.addAll(this.imagePanel.getSupportedMimeTypes());
mimeTypes.addAll(this.mediaPlayerPanel.getSupportedMimeTypes()); if(mediaPlayerPanel != null) {
mimeTypes.addAll(this.mediaPlayerPanel.getSupportedMimeTypes());
}
return mimeTypes; return mimeTypes;
} }

View File

@ -155,7 +155,7 @@
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="MediaPlayerPanel.audioSlider.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="MediaPlayerPanel.audioSlider.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
<Property name="value" type="int" value="0"/> <Property name="value" type="int" value="25"/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor"> <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[200, 21]"/> <Dimension value="[200, 21]"/>
</Property> </Property>

View File

@ -53,6 +53,7 @@ import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskData; 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.GstException;
/** /**
* 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
@ -172,26 +173,20 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
private PlayBin gstPlayBin; private PlayBin gstPlayBin;
private JavaFxAppSink fxAppSink; private JavaFxAppSink fxAppSink;
private JFXPanel fxPanel; private JFXPanel fxPanel;
private volatile boolean livePlayBin = false; private volatile boolean livePlayBin;
private volatile boolean hasError;
//When a video is playing, update the UI every 75 ms //When a video is playing, update the UI every 75 ms
private final Timer timer = new Timer(75, new VideoPanelUpdater()); private final Timer timer = new Timer(75, new VideoPanelUpdater());
private static final int PROGRESS_SLIDER_SIZE = 2000; private static final int PROGRESS_SLIDER_SIZE = 2000;
/**
* Perform media extraction off the EDT to not block the UI. Necessary for
* larger media files
*/
private ExtractMedia extractMediaWorker; private ExtractMedia extractMediaWorker;
/** /**
* Creates new form MediaViewVideoPanel * Creates new form MediaViewVideoPanel
*
* @throws java.lang.Exception
*/ */
public MediaPlayerPanel() throws Exception { public MediaPlayerPanel() throws GstException, UnsatisfiedLinkError {
initComponents(); initComponents();
//This could fail with any number of exceptions
initGst(); initGst();
customizeComponents(); customizeComponents();
} }
@ -226,17 +221,13 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
} }
}); });
//Set the slider to the current volume location
audioSlider.setValue(gstPlayBin.getVolumePercent() / 2);
videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS)); videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS));
fxPanel = new JFXPanel(); fxPanel = new JFXPanel();
videoPanel.add(fxPanel);//add jfx ui to JPanel videoPanel.add(fxPanel);//add jfx ui to JPanel
} }
private void initGst() throws Exception { private void initGst() throws GstException, UnsatisfiedLinkError {
logger.log(Level.INFO, "Attempting initializing of gstreamer for video/audio viewing"); //NON-NLS logger.log(Level.INFO, "Attempting initializing of gstreamer for video/audio viewing"); //NON-NLS
//This call may fail with any # of exception types
Gst.init(); Gst.init();
gstPlayBin = new PlayBin("VideoPlayer"); gstPlayBin = new PlayBin("VideoPlayer");
} }
@ -252,6 +243,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
//Ensure everything is back in the initial state //Ensure everything is back in the initial state
reset(); reset();
infoLabel.setText("");
if (file.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC)) { if (file.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC)) {
infoLabel.setText(NbBundle.getMessage(this.getClass(), "GstVideoPanel.setupVideo.infoLabel.text")); infoLabel.setText(NbBundle.getMessage(this.getClass(), "GstVideoPanel.setupVideo.infoLabel.text"));
return; return;
@ -268,9 +260,17 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
} }
} }
/**
* Assume no support on a fresh reset until we begin loading the file
* for play.
*/
@NbBundle.Messages({
"MediaPlayerPanel.noSupport=File not supported."
})
void resetComponents() { void resetComponents() {
progressLabel.setText("00:00:00/00:00:00"); progressLabel.setText(String.format("%s/%s", Bundle.MediaPlayerPanel_unknownTime(),
infoLabel.setText(""); Bundle.MediaPlayerPanel_unknownTime()));
infoLabel.setText(Bundle.MediaPlayerPanel_noSupport());
progressSlider.setValue(0); progressSlider.setValue(0);
} }
@ -278,14 +278,21 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
* Return this panel to its initial state. * Return this panel to its initial state.
*/ */
void reset() { void reset() {
livePlayBin = false;
timer.stop(); timer.stop();
gstPlayBin.stop(); if(livePlayBin && !hasError) {
gstPlayBin.stop();
}
hasError = false;
livePlayBin = false;
gstPlayBin.dispose();
if (fxAppSink != null) { if (fxAppSink != null) {
fxAppSink.clear(); fxAppSink.clear();
} }
videoPanel.removeAll();
if (extractMediaWorker != null) { if (extractMediaWorker != null) {
extractMediaWorker.cancel(true); extractMediaWorker.cancel(true);
} }
@ -372,7 +379,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
* Convert nanoseconds into an HH:MM:SS format. * Convert nanoseconds into an HH:MM:SS format.
*/ */
@NbBundle.Messages({ @NbBundle.Messages({
"MediaPlayerPanel.unknownTime=UNKNOWN", "MediaPlayerPanel.unknownTime=Unknown",
"MediaPlayerPanel.timeFormat=%02d:%02d:%02d" "MediaPlayerPanel.timeFormat=%02d:%02d:%02d"
}) })
private String formatTime(long ns, boolean ceiling) { private String formatTime(long ns, boolean ceiling) {
@ -437,13 +444,15 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
super.get(); super.get();
//Video is ready for playback. Clean up previous components and create new ones //Video is ready for playback. Clean up previous components and create new ones
gstPlayBin.dispose();
gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI()); gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI());
livePlayBin = true;
//Create a custom AppSink that hooks into JavaFx panels for video display //Create a custom AppSink that hooks into JavaFx panels for video display
fxPanel = new JFXPanel();
fxAppSink = new JavaFxAppSink("JavaFxAppSink", fxPanel); fxAppSink = new JavaFxAppSink("JavaFxAppSink", fxPanel);
gstPlayBin.setVideoSink(fxAppSink); gstPlayBin.setVideoSink(fxAppSink);
videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS));
videoPanel.add(fxPanel);//add jfx ui to JPanel
//Configure event handling //Configure event handling
attachEOSListener(gstPlayBin); //Handle end of video events attachEOSListener(gstPlayBin); //Handle end of video events
attachStateListener(gstPlayBin); //Handle syncing play/pause button to the stream state attachStateListener(gstPlayBin); //Handle syncing play/pause button to the stream state
@ -456,6 +465,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
* Prepare the PlayBin for playback. * Prepare the PlayBin for playback.
*/ */
gstPlayBin.ready(); gstPlayBin.ready();
livePlayBin = true;
//Customize components //Customize components
enableComponents(true); enableComponents(true);
} catch (CancellationException ex) { } catch (CancellationException ex) {
@ -487,15 +497,16 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
/** /**
* Listen for state changes and update the play/pause button * Listen for state changes and update the play/pause button
* accordingly. * accordingly. In addition, handle the state transition from
* READY -> PAUSED.
*/ */
private void attachStateListener(PlayBin gstPlayBin) { private void attachStateListener(PlayBin gstPlayBin) {
gstPlayBin.getBus().connect(new Bus.STATE_CHANGED() { gstPlayBin.getBus().connect(new Bus.STATE_CHANGED() {
@Override @Override
public void stateChanged(GstObject go, State oldState, State currentState, State pendingState) { public void stateChanged(GstObject go, State oldState, State currentState, State pendingState) {
/** /**
* If we are ready, it is safe to transition to pause state * If we are ready, it is safe to transition to the pause state
* to initiate data-flow for preRoll frame and duration * to initiate data-flow for pre-roll frame and duration
* information. * information.
*/ */
if (State.READY.equals(currentState)) { if (State.READY.equals(currentState)) {
@ -523,6 +534,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
enableComponents(false); enableComponents(false);
setLabelText(String.format("<html><font color='red'>%s</font></html>", setLabelText(String.format("<html><font color='red'>%s</font></html>",
MEDIA_PLAYER_ERROR_STRING)); MEDIA_PLAYER_ERROR_STRING));
timer.stop();
hasError = true;
} }
}); });
} }
@ -536,19 +549,21 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (!progressSlider.getValueIsAdjusting()) { if (!progressSlider.getValueIsAdjusting()) {
long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); if(livePlayBin) {
long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS);
/** long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS);
* Duration may not be known until there is video data in the /**
* pipeline. We start this updater when data-flow has just been * Duration may not be known until there is video data in the
* initiated so buffering may still be in progress. * pipeline. We start this updater when data-flow has just been
*/ * initiated so buffering may still be in progress.
if (duration != -1) { */
double relativePosition = (double) position / duration; if (duration != -1) {
progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE)); double relativePosition = (double) position / duration;
} progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE));
}
updateTimeLabel(position, duration); updateTimeLabel(position, duration);
}
} }
} }
} }
@ -607,7 +622,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
audioSlider.setMinorTickSpacing(5); audioSlider.setMinorTickSpacing(5);
audioSlider.setPaintTicks(true); audioSlider.setPaintTicks(true);
audioSlider.setToolTipText(org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.audioSlider.toolTipText")); // NOI18N audioSlider.setToolTipText(org.openide.util.NbBundle.getMessage(MediaPlayerPanel.class, "MediaPlayerPanel.audioSlider.toolTipText")); // NOI18N
audioSlider.setValue(0); audioSlider.setValue(25);
audioSlider.setMinimumSize(new java.awt.Dimension(200, 21)); audioSlider.setMinimumSize(new java.awt.Dimension(200, 21));
audioSlider.setPreferredSize(new java.awt.Dimension(200, 21)); audioSlider.setPreferredSize(new java.awt.Dimension(200, 21));
@ -666,13 +681,10 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed
switch (gstPlayBin.getState()) { if(gstPlayBin.isPlaying()) {
case PLAYING: gstPlayBin.pause();
gstPlayBin.pause(); } else {
break; gstPlayBin.play();
default:
gstPlayBin.play();
break;
} }
}//GEN-LAST:event_playButtonActionPerformed }//GEN-LAST:event_playButtonActionPerformed