19 package org.sleuthkit.autopsy.contentviewers;
 
   21 import com.google.common.io.Files;
 
   22 import java.awt.Dimension;
 
   23 import java.awt.Image;
 
   24 import java.awt.image.BufferedImage;
 
   26 import java.io.IOException;
 
   27 import java.nio.IntBuffer;
 
   28 import java.util.ArrayList;
 
   29 import java.util.Arrays;
 
   30 import java.util.Collections;
 
   31 import java.util.HashSet;
 
   32 import java.util.List;
 
   34 import java.util.concurrent.CancellationException;
 
   35 import java.util.concurrent.ExecutionException;
 
   36 import java.util.concurrent.TimeUnit;
 
   37 import java.util.logging.Level;
 
   38 import javax.swing.BoxLayout;
 
   39 import javax.swing.JButton;
 
   40 import javax.swing.JLabel;
 
   41 import javax.swing.JPanel;
 
   42 import javax.swing.JSlider;
 
   43 import javax.swing.SwingUtilities;
 
   44 import javax.swing.SwingWorker;
 
   45 import javax.swing.event.ChangeEvent;
 
   46 import org.gstreamer.ClockTime;
 
   47 import org.gstreamer.Gst;
 
   48 import org.gstreamer.GstException;
 
   49 import org.gstreamer.State;
 
   50 import org.gstreamer.StateChangeReturn;
 
   51 import org.gstreamer.elements.PlayBin2;
 
   52 import org.gstreamer.elements.RGBDataSink;
 
   53 import org.gstreamer.swing.VideoComponent;
 
   54 import org.netbeans.api.progress.ProgressHandle;
 
   55 import org.openide.util.NbBundle;
 
   56 import org.openide.util.lookup.ServiceProvider;
 
   57 import org.openide.util.lookup.ServiceProviders;
 
   69 @ServiceProviders(value = {
 
   70     @ServiceProvider(service = FrameCapture.class)
 
   74     private static final String[] EXTENSIONS = 
new String[]{
".mov", 
".m4v", 
".flv", 
".mp4", 
".3gp", 
".avi", 
".mpg", 
".mpeg", 
".wmv"}; 
 
   75     private static final List<String> MIMETYPES = Arrays.asList(
"video/quicktime", 
"audio/mpeg", 
"audio/x-mpeg", 
"video/mpeg", 
"video/x-mpeg", 
"audio/mpeg3", 
"audio/x-mpeg-3", 
"video/x-flv", 
"video/mp4", 
"audio/x-m4a", 
"video/x-m4v", 
"audio/x-wav"); 
 
   79     private static final long MIN_FRAME_INTERVAL_MILLIS = 500;
 
   80     private static final long FRAME_CAPTURE_TIMEOUT_MILLIS = 1000;
 
   81     private static final String MEDIA_PLAYER_ERROR_STRING = NbBundle.getMessage(
GstVideoPanel.class, 
"GstVideoPanel.cannotProcFile.err");
 
   83     private long durationMillis = 0;
 
   88     private boolean autoTracking = 
false; 
 
   89     private final Object playbinLock = 
new Object(); 
 
   91     private final Set<String> badVideoFiles = Collections.synchronizedSet(
new HashSet<>());
 
   98         customizeComponents();
 
  106         return progressLabel;
 
  110         return progressSlider;
 
  118         return gstVideoComponent;
 
  131         progressSlider.setEnabled(
false); 
 
  132         progressSlider.setValue(0);
 
  134         progressSlider.addChangeListener((ChangeEvent e) -> {
 
  140             int time = progressSlider.getValue();
 
  141             synchronized (playbinLock) {
 
  142                 if (gstPlaybin2 != null && !autoTracking) {
 
  143                     State orig = gstPlaybin2.getState();
 
  144                     if (gstPlaybin2.pause() == StateChangeReturn.FAILURE) {
 
  145                         logger.log(Level.WARNING, 
"Attempt to call PlayBin2.pause() failed."); 
 
  146                         infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
 
  149                     if (gstPlaybin2.seek(ClockTime.fromMillis(time)) == 
false) {
 
  150                         logger.log(Level.WARNING, 
"Attempt to call PlayBin2.seek() failed."); 
 
  151                         infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
 
  154                     gstPlaybin2.setState(orig);
 
  162             logger.log(Level.INFO, 
"Initializing gstreamer for video/audio viewing"); 
 
  165         } 
catch (GstException e) {
 
  167             logger.log(Level.SEVERE, 
"Error initializing gstreamer for audio/video viewing and frame extraction capabilities", e); 
 
  169                     NbBundle.getMessage(
this.getClass(), 
"GstVideoPanel.initGst.gstException.msg"),
 
  172         } 
catch (UnsatisfiedLinkError | NoClassDefFoundError | Exception e) {
 
  174             logger.log(Level.SEVERE, 
"Error initializing gstreamer for audio/video viewing and extraction capabilities", e); 
 
  176                     NbBundle.getMessage(
this.getClass(), 
"GstVideoPanel.initGst.otherException.msg"),
 
  185     @NbBundle.Messages ({
"GstVideoPanel.noOpenCase.errMsg=No open case available."})
 
  186     void setupVideo(
final AbstractFile file, 
final Dimension dims) {
 
  188         infoLabel.setText(
"");
 
  190         final boolean deleted = file.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC);
 
  192             infoLabel.setText(NbBundle.getMessage(
this.getClass(), 
"GstVideoPanel.setupVideo.infoLabel.text"));
 
  193             videoPanel.removeAll();
 
  194             pauseButton.setEnabled(
false);
 
  195             progressSlider.setEnabled(
false);
 
  201             ioFile = VideoUtils.getTempVideoFile(file);
 
  202         } 
catch (NoCurrentCaseException ex) {
 
  203             logger.log(Level.SEVERE, 
"Exception while getting open case.", ex); 
 
  204             infoLabel.setText(Bundle.GstVideoPanel_noOpenCase_errMsg());
 
  205             pauseButton.setEnabled(
false);
 
  206             progressSlider.setEnabled(
false);
 
  213             path = file.getUniquePath();
 
  214         } 
catch (TskCoreException ex) {
 
  215             logger.log(Level.SEVERE, 
"Cannot get unique path of video file"); 
 
  217         infoLabel.setText(path);
 
  218         infoLabel.setToolTipText(path);
 
  219         pauseButton.setEnabled(
true);
 
  220         progressSlider.setEnabled(
true);
 
  223         gstVideoComponent = 
new VideoComponent();
 
  224         synchronized (playbinLock) {
 
  225             if (gstPlaybin2 != null) {
 
  226                 gstPlaybin2.dispose();
 
  228             gstPlaybin2 = 
new PlayBin2(
"VideoPlayer"); 
 
  229             gstPlaybin2.setVideoSink(gstVideoComponent.getElement());
 
  231             videoPanel.removeAll();
 
  233             videoPanel.setLayout(
new BoxLayout(videoPanel, BoxLayout.Y_AXIS));
 
  234             videoPanel.add(gstVideoComponent);
 
  236             videoPanel.setVisible(
true);
 
  238             gstPlaybin2.setInputFile(ioFile);
 
  240             if (gstPlaybin2.setState(State.READY) == StateChangeReturn.FAILURE) {
 
  241                 logger.log(Level.WARNING, 
"Attempt to call PlayBin2.setState(State.READY) failed."); 
 
  242                 infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
 
  252         SwingUtilities.invokeLater(() -> {
 
  253             progressLabel.setText(
"");
 
  260         synchronized (playbinLock) {
 
  261             if (gstPlaybin2 != null) {
 
  262                 if (gstPlaybin2.isPlaying()) {
 
  263                     if (gstPlaybin2.stop() == StateChangeReturn.FAILURE) {
 
  264                         logger.log(Level.WARNING, 
"Attempt to call PlayBin2.stop() failed."); 
 
  265                         infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
 
  269                 if (gstPlaybin2.setState(State.NULL) == StateChangeReturn.FAILURE) {
 
  270                     logger.log(Level.WARNING, 
"Attempt to call PlayBin2.setState(State.NULL) failed."); 
 
  271                     infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
 
  274                 if (gstPlaybin2.getState().equals(State.NULL)) {
 
  275                     gstPlaybin2.dispose();
 
  279             gstVideoComponent = null;
 
  283         if (videoProgressWorker != null) {
 
  284             videoProgressWorker.cancel(
true);
 
  285             videoProgressWorker = null;
 
  302     public List<VideoFrame> 
captureFrames(java.io.File file, 
int numFrames) 
throws Exception {
 
  304         List<VideoFrame> frames = 
new ArrayList<>();
 
  306         Object lock = 
new Object();
 
  314         if (badVideoFiles.contains(file.getName())) {
 
  316                     NbBundle.getMessage(
this.getClass(), 
"GstVideoPanel.exception.problemFile.msg", file.getName()));
 
  320         RGBDataSink videoSink = 
new RGBDataSink(
"rgb", rgbListener); 
 
  321         PlayBin2 playbin = 
new PlayBin2(
"VideoFrameCapture"); 
 
  322         playbin.setInputFile(file);
 
  323         playbin.setVideoSink(videoSink);
 
  326         StateChangeReturn ret = playbin.play();
 
  327         if (ret == StateChangeReturn.FAILURE) {
 
  329             badVideoFiles.add(file.getName());
 
  330             throw new Exception(NbBundle.getMessage(
this.getClass(), 
"GstVideoPanel.exception.problemPlay.msg"));
 
  332         ret = playbin.pause();
 
  333         if (ret == StateChangeReturn.FAILURE) {
 
  335             badVideoFiles.add(file.getName());
 
  336             throw new Exception(NbBundle.getMessage(
this.getClass(), 
"GstVideoPanel.exception.problemPause.msg"));
 
  341         TimeUnit unit = TimeUnit.MILLISECONDS;
 
  342         long myDurationMillis = playbin.queryDuration(unit);
 
  343         if (myDurationMillis <= 0) {
 
  348         int numFramesToGet = numFrames;
 
  349         long frameInterval = myDurationMillis / numFrames;
 
  350         if (frameInterval < MIN_FRAME_INTERVAL_MILLIS) {
 
  355         for (
int i = 0; i < numFramesToGet; ++i) {
 
  356             long timeStamp = i * frameInterval;
 
  358             ret = playbin.pause();
 
  359             if (ret == StateChangeReturn.FAILURE) {
 
  361                 badVideoFiles.add(file.getName());
 
  363                         NbBundle.getMessage(
this.getClass(), 
"GstVideoPanel.exception.problemPauseCaptFrame.msg"));
 
  367             if (!playbin.seek(timeStamp, unit)) {
 
  368                 logger.log(Level.INFO, 
"There was a problem seeking to " + timeStamp + 
" " + unit.name().toLowerCase()); 
 
  371             ret = playbin.play();
 
  372             if (ret == StateChangeReturn.FAILURE) {
 
  374                 badVideoFiles.add(file.getName());
 
  376                         NbBundle.getMessage(
this.getClass(), 
"GstVideoPanel.exception.problemPlayCaptFrame.msg"));
 
  380             synchronized (lock) {
 
  382                     lock.wait(FRAME_CAPTURE_TIMEOUT_MILLIS);
 
  383                 } 
catch (InterruptedException e) {
 
  384                     logger.log(Level.INFO, 
"InterruptedException occurred while waiting for frame capture.", e); 
 
  387             Image image = rgbListener.
getImage();
 
  389             ret = playbin.stop();
 
  390             if (ret == StateChangeReturn.FAILURE) {
 
  392                 badVideoFiles.add(file.getName());
 
  394                         NbBundle.getMessage(
this.getClass(), 
"GstVideoPanel.exception.problemStopCaptFrame.msg"));
 
  398                 logger.log(Level.WARNING, 
"There was a problem while trying to capture a frame from file " + file.getName()); 
 
  399                 badVideoFiles.add(file.getName());
 
  412             this.waiter = waiter;
 
  415         private BufferedImage 
bi;
 
  419         public void rgbFrame(
boolean bln, 
int w, 
int h, IntBuffer rgbPixels) {
 
  420             synchronized (waiter) {
 
  421                 bi = 
new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
 
  422                 bi.setRGB(0, 0, w, h, rgbPixels.array(), 0, w);
 
  428             synchronized (waiter) {
 
  442     @SuppressWarnings(
"unchecked")
 
  444     private 
void initComponents() {
 
  446         videoPanel = 
new javax.swing.JPanel();
 
  447         controlPanel = 
new javax.swing.JPanel();
 
  448         pauseButton = 
new javax.swing.JButton();
 
  449         progressSlider = 
new javax.swing.JSlider();
 
  450         progressLabel = 
new javax.swing.JLabel();
 
  451         infoLabel = 
new javax.swing.JLabel();
 
  453         javax.swing.GroupLayout videoPanelLayout = 
new javax.swing.GroupLayout(videoPanel);
 
  454         videoPanel.setLayout(videoPanelLayout);
 
  455         videoPanelLayout.setHorizontalGroup(
 
  456                 videoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  457                 .addGap(0, 0, Short.MAX_VALUE)
 
  459         videoPanelLayout.setVerticalGroup(
 
  460                 videoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  461                 .addGap(0, 231, Short.MAX_VALUE)
 
  464         org.openide.awt.Mnemonics.setLocalizedText(pauseButton, 
org.openide.util.NbBundle.getMessage(
GstVideoPanel.class, 
"MediaViewVideoPanel.pauseButton.text")); 
 
  465         pauseButton.addActionListener(
new java.awt.event.ActionListener() {
 
  466             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  467                 pauseButtonActionPerformed(evt);
 
  471         org.openide.awt.Mnemonics.setLocalizedText(progressLabel, 
org.openide.util.NbBundle.getMessage(
GstVideoPanel.class, 
"MediaViewVideoPanel.progressLabel.text")); 
 
  473         org.openide.awt.Mnemonics.setLocalizedText(infoLabel, 
org.openide.util.NbBundle.getMessage(
GstVideoPanel.class, 
"MediaViewVideoPanel.infoLabel.text")); 
 
  475         javax.swing.GroupLayout controlPanelLayout = 
new javax.swing.GroupLayout(controlPanel);
 
  476         controlPanel.setLayout(controlPanelLayout);
 
  477         controlPanelLayout.setHorizontalGroup(
 
  478                 controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  479                 .addGroup(controlPanelLayout.createSequentialGroup()
 
  481                         .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  482                                 .addGroup(controlPanelLayout.createSequentialGroup()
 
  484                                         .addComponent(infoLabel)
 
  485                                         .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
 
  486                                 .addGroup(controlPanelLayout.createSequentialGroup()
 
  487                                         .addComponent(pauseButton)
 
  488                                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  489                                         .addComponent(progressSlider, javax.swing.GroupLayout.DEFAULT_SIZE, 265, Short.MAX_VALUE)
 
  490                                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  491                                         .addComponent(progressLabel)
 
  492                                         .addContainerGap())))
 
  494         controlPanelLayout.setVerticalGroup(
 
  495                 controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  496                 .addGroup(controlPanelLayout.createSequentialGroup()
 
  498                         .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  499                                 .addComponent(progressSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 
  500                                 .addComponent(pauseButton)
 
  501                                 .addComponent(progressLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  502                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  503                         .addComponent(infoLabel)
 
  507         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  508         this.setLayout(layout);
 
  509         layout.setHorizontalGroup(
 
  510                 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  511                 .addComponent(controlPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  512                 .addComponent(videoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  514         layout.setVerticalGroup(
 
  515                 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  516                 .addGroup(layout.createSequentialGroup()
 
  517                         .addComponent(videoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
 
  518                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 
  519                         .addComponent(controlPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
 
  524         synchronized (playbinLock) {
 
  525             State state = gstPlaybin2.getState();
 
  526             if (state.equals(State.PLAYING)) {
 
  527                 if (gstPlaybin2.pause() == StateChangeReturn.FAILURE) {
 
  528                     logger.log(Level.WARNING, 
"Attempt to call PlayBin2.pause() failed."); 
 
  529                     infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
 
  532                 pauseButton.setText(
"►");
 
  534                 if (gstPlaybin2.setState(State.PAUSED) == StateChangeReturn.FAILURE) {
 
  535                     logger.log(Level.WARNING, 
"Attempt to call PlayBin2.setState(State.PAUSED) failed."); 
 
  536                     infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
 
  539             } 
else if (state.equals(State.PAUSED)) {
 
  540                 if (gstPlaybin2.play() == StateChangeReturn.FAILURE) {
 
  541                     logger.log(Level.WARNING, 
"Attempt to call PlayBin2.play() failed."); 
 
  542                     infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
 
  545                 pauseButton.setText(
"||");
 
  547                 if (gstPlaybin2.setState(State.PLAYING) == StateChangeReturn.FAILURE) {
 
  548                     logger.log(Level.WARNING, 
"Attempt to call PlayBin2.setState(State.PLAYING) failed."); 
 
  549                     infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
 
  552             } 
else if (state.equals(State.READY)) {
 
  553                 final File tempVideoFile;
 
  557                     logger.log(Level.WARNING, 
"Exception while getting open case."); 
 
  558                     infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
 
  579         private final String durationFormat = 
"%02d:%02d:%02d/%02d:%02d:%02d  "; 
 
  580         private long millisElapsed = 0;
 
  581         private final long INTER_FRAME_PERIOD_MS = 20;
 
  582         private final long END_TIME_MARGIN_MS = 50;
 
  585             synchronized (playbinLock) {
 
  586                 return gstPlaybin2 != null && !gstPlaybin2.getState().equals(State.NULL);
 
  591             synchronized (playbinLock) {
 
  592                 if (gstPlaybin2 != null) {
 
  593                     if (gstPlaybin2.stop() == StateChangeReturn.FAILURE) {
 
  594                         logger.log(Level.WARNING, 
"Attempt to call PlayBin2.stop() failed."); 
 
  595                         infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
 
  598                     if (gstPlaybin2.setState(State.READY) == StateChangeReturn.FAILURE) {
 
  599                         logger.log(Level.WARNING, 
"Attempt to call PlayBin2.setState(State.READY) failed."); 
 
  600                         infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
 
  602                     gstPlaybin2.getState(); 
 
  605             pauseButton.setText(
"►");
 
  606             progressSlider.setValue(0);
 
  608             String durationStr = String.format(durationFormat, 0, 0, 0,
 
  609                     totalHours, totalMinutes, totalSeconds);
 
  610             progressLabel.setText(durationStr);
 
  620             return (durationMillis - millisElapsed) > END_TIME_MARGIN_MS;
 
  627             progressSlider.setEnabled(
true);
 
  630             while (hasNotEnded() && isPlayBinReady() && !isCancelled()) {
 
  632                 synchronized (playbinLock) {
 
  633                     pos = gstPlaybin2.queryPosition();
 
  635                 millisElapsed = pos.toMillis();
 
  638                 long secondsElapsed = millisElapsed / 1000;
 
  639                 int elapsedHours = (int) secondsElapsed / 3600;
 
  640                 secondsElapsed -= elapsedHours * 3600;
 
  641                 int elapsedMinutes = (int) secondsElapsed / 60;
 
  642                 secondsElapsed -= elapsedMinutes * 60;
 
  643                 int elapsedSeconds = (int) secondsElapsed;
 
  645                 String durationStr = String.format(durationFormat,
 
  646                         elapsedHours, elapsedMinutes, elapsedSeconds,
 
  647                         totalHours, totalMinutes, totalSeconds);
 
  649                 progressLabel.setText(durationStr);
 
  651                 progressSlider.setValue((
int) millisElapsed);
 
  652                 autoTracking = 
false;
 
  655                     Thread.sleep(INTER_FRAME_PERIOD_MS);
 
  656                 } 
catch (InterruptedException ex) {
 
  662             progressSlider.setEnabled(
false);
 
  674             } 
catch (InterruptedException | ExecutionException ex) {
 
  675                 logger.log(Level.WARNING, 
"Error updating video progress: " + ex.getMessage()); 
 
  676                 infoLabel.setText(NbBundle.getMessage(
this.getClass(), 
"GstVideoPanel.progress.infoLabel.updateErr",
 
  679             catch (java.util.concurrent.CancellationException ex) {
 
  694             this.sourceFile = sFile;
 
  695             this.tempFile = jFile;
 
  700             if (tempFile.exists() == 
false || tempFile.length() < sourceFile.getSize()) {
 
  701                 progress = ProgressHandle.createHandle(NbBundle.getMessage(
GstVideoPanel.class, 
"GstVideoPanel.ExtractMedia.progress.buffering", sourceFile.getName()), () -> 
ExtractMedia.this.cancel(
true));
 
  702                 progressLabel.setText(NbBundle.getMessage(
this.getClass(), 
"GstVideoPanel.progress.buffering"));
 
  705                     Files.createParentDirs(tempFile);
 
  707                 } 
catch (IOException ex) {
 
  708                     logger.log(Level.WARNING, 
"Error buffering file", ex); 
 
  722             } 
catch (CancellationException ex) {
 
  723                 logger.log(Level.INFO, 
"Media buffering was canceled."); 
 
  724             } 
catch (InterruptedException ex) {
 
  725                 logger.log(Level.INFO, 
"Media buffering was interrupted."); 
 
  726             } 
catch (Exception ex) {
 
  727                 logger.log(Level.SEVERE, 
"Fatal error during media buffering.", ex); 
 
  729                 if (progress != null) {
 
  732                 if (!this.isCancelled()) {
 
  739             if (tempFile == null || !tempFile.exists()) {
 
  740                 progressLabel.setText(NbBundle.getMessage(
this.getClass(), 
"GstVideoPanel.progressLabel.bufferingErr"));
 
  744             synchronized (playbinLock) {
 
  746                 if (gstPlaybin2.play() == StateChangeReturn.FAILURE) {
 
  747                     logger.log(Level.WARNING, 
"Attempt to call PlayBin2.play() failed."); 
 
  748                     infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
 
  751                 if (gstPlaybin2.pause() == StateChangeReturn.FAILURE) {
 
  752                     logger.log(Level.WARNING, 
"Attempt to call PlayBin2.pause() failed."); 
 
  753                     infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
 
  756                 gstPlaybin2.getState();
 
  757                 dur = gstPlaybin2.queryDuration();
 
  759             durationMillis = dur.toMillis();
 
  762             long durationSeconds = (int) durationMillis / 1000;
 
  763             totalHours = (int) durationSeconds / 3600;
 
  764             durationSeconds -= totalHours * 3600;
 
  765             totalMinutes = (int) durationSeconds / 60;
 
  766             durationSeconds -= totalMinutes * 60;
 
  767             totalSeconds = (int) durationSeconds;
 
  769             SwingUtilities.invokeLater(() -> {
 
  770                 progressSlider.setMaximum((
int) durationMillis);
 
  771                 progressSlider.setMinimum(0);
 
  773                 synchronized (playbinLock) {
 
  774                     if (gstPlaybin2.play() == StateChangeReturn.FAILURE) {
 
  775                         logger.log(Level.WARNING, 
"Attempt to call PlayBin2.play() failed."); 
 
  776                         infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
 
  779                 pauseButton.setText(
"||");
 
  780                 videoProgressWorker = 
new VideoProgressWorker();
 
  781                 videoProgressWorker.execute();
 
  788         return EXTENSIONS.clone();
 
void rgbFrame(boolean bln, int w, int h, IntBuffer rgbPixels)
 
javax.swing.JButton pauseButton
 
VideoComponent gstVideoComponent
 
void customizeComponents()
 
static< T > long writeToFile(Content content, java.io.File outputFile, ProgressHandle progress, Future< T > worker, boolean source)
 
JLabel getProgressLabel()
 
List< String > getMimeTypes()
 
FrameCaptureRGBListener(Object waiter)
 
VideoComponent getVideoComponent()
 
JSlider getProgressSlider()
 
javax.swing.JPanel videoPanel
 
javax.swing.JSlider progressSlider
 
javax.swing.JPanel controlPanel
 
javax.swing.JLabel infoLabel
 
static void error(String title, String message)
 
void pauseButtonActionPerformed(java.awt.event.ActionEvent evt)
 
synchronized static Logger getLogger(String name)
 
static File getTempVideoFile(AbstractFile file)
 
volatile PlayBin2 gstPlaybin2
 
VideoProgressWorker videoProgressWorker
 
List< VideoFrame > captureFrames(java.io.File file, int numFrames)
 
javax.swing.JLabel progressLabel