mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-09 14:49:32 +00:00
Cleanup.
This commit is contained in:
parent
df3fb7f3ed
commit
b60faf0212
@ -1,443 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 Neil C Smith
|
|
||||||
* Copyright (c) 2007 Wayne Meissner
|
|
||||||
*
|
|
||||||
* This file is part of gstreamer-java.
|
|
||||||
*
|
|
||||||
* This code is free software: you can redistribute it and/or modify it under
|
|
||||||
* the terms of the GNU Lesser General Public License version 3 only, as
|
|
||||||
* published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
||||||
* version 3 for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.freedesktop.gstreamer.examples;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Component;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Graphics;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.GraphicsConfiguration;
|
|
||||||
import java.awt.RenderingHints;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.awt.event.ComponentAdapter;
|
|
||||||
import java.awt.event.ComponentEvent;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.awt.image.DataBufferInt;
|
|
||||||
import java.awt.image.VolatileImage;
|
|
||||||
import java.beans.PropertyChangeEvent;
|
|
||||||
import java.beans.PropertyChangeListener;
|
|
||||||
import java.nio.IntBuffer;
|
|
||||||
import java.util.concurrent.locks.Lock;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
|
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import javax.swing.Timer;
|
|
||||||
|
|
||||||
import org.freedesktop.gstreamer.Element;
|
|
||||||
import org.freedesktop.gstreamer.Structure;
|
|
||||||
import org.freedesktop.gstreamer.elements.AppSink;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import org.freedesktop.gstreamer.Buffer;
|
|
||||||
import org.freedesktop.gstreamer.Caps;
|
|
||||||
import org.freedesktop.gstreamer.FlowReturn;
|
|
||||||
import org.freedesktop.gstreamer.Sample;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
//DLG: Made public
|
|
||||||
public class SimpleVideoComponent extends javax.swing.JComponent {
|
|
||||||
|
|
||||||
private BufferedImage currentImage = null;
|
|
||||||
private final Lock bufferLock = new ReentrantLock();
|
|
||||||
private final AppSink videosink;
|
|
||||||
// private Pad videoPad;
|
|
||||||
private RenderComponent renderComponent = new RenderComponent();
|
|
||||||
private boolean keepAspect = true;
|
|
||||||
private Timer resourceTimer;
|
|
||||||
private VolatileImage volatileImage;
|
|
||||||
private boolean frameRendered = false;
|
|
||||||
private volatile boolean updatePending = false;
|
|
||||||
private final boolean useVolatile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance of GstVideoComponent
|
|
||||||
*/
|
|
||||||
public SimpleVideoComponent() {
|
|
||||||
this(new AppSink("GstVideoComponent"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance of GstVideoComponent
|
|
||||||
*/
|
|
||||||
public SimpleVideoComponent(AppSink appsink) {
|
|
||||||
this.videosink = appsink;
|
|
||||||
videosink.set("emit-signals", true);
|
|
||||||
AppSinkListener listener = new AppSinkListener();
|
|
||||||
videosink.connect((AppSink.NEW_SAMPLE) listener);
|
|
||||||
videosink.connect((AppSink.NEW_PREROLL) listener);
|
|
||||||
StringBuilder caps = new StringBuilder("video/x-raw,pixel-aspect-ratio=1/1,");
|
|
||||||
// JNA creates ByteBuffer using native byte order, set masks according to that.
|
|
||||||
if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
|
|
||||||
caps.append("format=BGRx");
|
|
||||||
} else {
|
|
||||||
caps.append("format=xRGB");
|
|
||||||
}
|
|
||||||
videosink.setCaps(new Caps(caps.toString()));
|
|
||||||
|
|
||||||
useVolatile = true;
|
|
||||||
|
|
||||||
// Kick off a timer to free up the volatile image if there have been no recent updates
|
|
||||||
// (e.g. the player is paused)
|
|
||||||
//
|
|
||||||
resourceTimer = new Timer(250, resourceReaper);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Don't use a layout manager - the output component will positioned within this
|
|
||||||
// component according to the aspect ratio and scaling mode
|
|
||||||
//
|
|
||||||
setLayout(null);
|
|
||||||
add(renderComponent);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listen for the child changing its preferred size to the size of the
|
|
||||||
// video stream.
|
|
||||||
//
|
|
||||||
renderComponent.addPropertyChangeListener("preferredSize", new PropertyChangeListener() {
|
|
||||||
|
|
||||||
public void propertyChange(PropertyChangeEvent evt) {
|
|
||||||
setPreferredSize(renderComponent.getPreferredSize());
|
|
||||||
scaleVideoOutput();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//
|
|
||||||
// Scale the video output in response to this component being resized
|
|
||||||
//
|
|
||||||
addComponentListener(new ComponentAdapter() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void componentResized(ComponentEvent arg0) {
|
|
||||||
scaleVideoOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
renderComponent.setBounds(getBounds());
|
|
||||||
setOpaque(true);
|
|
||||||
setBackground(Color.BLACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scales the video output component according to its aspect ratio
|
|
||||||
*/
|
|
||||||
private void scaleVideoOutput() {
|
|
||||||
final Component child = renderComponent;
|
|
||||||
final Dimension childSize = child.getPreferredSize();
|
|
||||||
final int width = getWidth(), height = getHeight();
|
|
||||||
// Figure out the aspect ratio
|
|
||||||
double aspect = keepAspect ? (double) childSize.width / (double) childSize.height : 1.0f;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Now scale and position the videoChild component to be in the correct position
|
|
||||||
// to keep the aspect ratio correct.
|
|
||||||
//
|
|
||||||
int scaledHeight = (int) ((double) width / aspect);
|
|
||||||
if (!keepAspect) {
|
|
||||||
//
|
|
||||||
// Just make the child match the parent
|
|
||||||
//
|
|
||||||
child.setBounds(0, 0, width, height);
|
|
||||||
} else if (scaledHeight < height) {
|
|
||||||
//
|
|
||||||
// Output window is taller than the image is when scaled, so move the
|
|
||||||
// video component to sit vertically in the centre of the VideoComponent.
|
|
||||||
//
|
|
||||||
final int y = (height - scaledHeight) / 2;
|
|
||||||
child.setBounds(0, y, width, scaledHeight);
|
|
||||||
} else {
|
|
||||||
final int scaledWidth = (int) ((double) height * aspect);
|
|
||||||
final int x = (width - scaledWidth) / 2;
|
|
||||||
child.setBounds(x, 0, scaledWidth, height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private ActionListener resourceReaper = new ActionListener() {
|
|
||||||
public void actionPerformed(ActionEvent arg0) {
|
|
||||||
if (!frameRendered) {
|
|
||||||
if (volatileImage != null) {
|
|
||||||
volatileImage.flush();
|
|
||||||
volatileImage = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop the timer so we don't wakeup needlessly
|
|
||||||
resourceTimer.stop();
|
|
||||||
}
|
|
||||||
frameRendered = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public Element getElement() {
|
|
||||||
return videosink;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKeepAspect(boolean keepAspect) {
|
|
||||||
this.keepAspect = keepAspect;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLightweight() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void paintComponent(Graphics g) {
|
|
||||||
if (isOpaque()) {
|
|
||||||
Graphics2D g2d = (Graphics2D) g.create();
|
|
||||||
g2d.setColor(getBackground());
|
|
||||||
g2d.fillRect(0, 0, getWidth(), getHeight());
|
|
||||||
g2d.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RenderComponent extends javax.swing.JComponent {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -4736605073704494268L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void paintComponent(Graphics g) {
|
|
||||||
int width = getWidth(), height = getHeight();
|
|
||||||
Graphics2D g2d = (Graphics2D) g.create();
|
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
|
||||||
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
|
||||||
if (currentImage != null) {
|
|
||||||
GraphicsConfiguration gc = getGraphicsConfiguration();
|
|
||||||
render(g2d, 0, 0, width, height);
|
|
||||||
} else {
|
|
||||||
g2d.setColor(getBackground());
|
|
||||||
g2d.fillRect(0, 0, width, height);
|
|
||||||
}
|
|
||||||
g2d.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOpaque() {
|
|
||||||
return SimpleVideoComponent.this.isOpaque();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLightweight() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderVolatileImage(BufferedImage bufferedImage) {
|
|
||||||
do {
|
|
||||||
int w = bufferedImage.getWidth(), h = bufferedImage.getHeight();
|
|
||||||
GraphicsConfiguration gc = getGraphicsConfiguration();
|
|
||||||
if (volatileImage == null || volatileImage.getWidth() != w
|
|
||||||
|| volatileImage.getHeight() != h
|
|
||||||
|| volatileImage.validate(gc) == VolatileImage.IMAGE_INCOMPATIBLE) {
|
|
||||||
if (volatileImage != null) {
|
|
||||||
volatileImage.flush();
|
|
||||||
}
|
|
||||||
volatileImage = gc.createCompatibleVolatileImage(w, h);
|
|
||||||
volatileImage.setAccelerationPriority(1.0f);
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// Now paint the BufferedImage into the accelerated image
|
|
||||||
//
|
|
||||||
Graphics2D g = volatileImage.createGraphics();
|
|
||||||
g.drawImage(bufferedImage, 0, 0, null);
|
|
||||||
g.dispose();
|
|
||||||
} while (volatileImage.contentsLost());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders to a volatile image, and then paints that to the screen. This
|
|
||||||
* helps with scaling performance on accelerated surfaces (e.g. OpenGL)
|
|
||||||
*
|
|
||||||
* @param g the graphics to paint the image to
|
|
||||||
* @param x the left coordinate to start painting at.
|
|
||||||
* @param y the top coordinate to start painting at.
|
|
||||||
* @param w the width of the paint area
|
|
||||||
* @param h the height of the paint area
|
|
||||||
*/
|
|
||||||
private void volatileRender(Graphics g, int x, int y, int w, int h) {
|
|
||||||
do {
|
|
||||||
if (updatePending || volatileImage == null
|
|
||||||
|| volatileImage.validate(getGraphicsConfiguration()) != VolatileImage.IMAGE_OK) {
|
|
||||||
bufferLock.lock();
|
|
||||||
try {
|
|
||||||
updatePending = false;
|
|
||||||
renderVolatileImage(currentImage);
|
|
||||||
} finally {
|
|
||||||
bufferLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g.drawImage(volatileImage, x, y, w, h, null);
|
|
||||||
} while (volatileImage.contentsLost());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders directly to the given <tt>Graphics</tt>. This is only really
|
|
||||||
* useful on MacOS where swing graphics are unaccelerated so using a
|
|
||||||
* volatile just incurs an extra memcpy().
|
|
||||||
*
|
|
||||||
* @param g the graphics to paint the image to
|
|
||||||
* @param x the left coordinate to start painting at.
|
|
||||||
* @param y the top coordinate to start painting at.
|
|
||||||
* @param w the width of the paint area
|
|
||||||
* @param h the height of the paint area
|
|
||||||
*/
|
|
||||||
private void heapRender(Graphics g, int x, int y, int w, int h) {
|
|
||||||
bufferLock.lock();
|
|
||||||
try {
|
|
||||||
updatePending = false;
|
|
||||||
g.drawImage(currentImage, x, y, w, h, null);
|
|
||||||
} finally {
|
|
||||||
bufferLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the current frame to the given <tt>Graphics</tt>.
|
|
||||||
*
|
|
||||||
* @param g the graphics to paint the image to
|
|
||||||
* @param x the left coordinate to start painting at.
|
|
||||||
* @param y the top coordinate to start painting at.
|
|
||||||
* @param w the width of the paint area
|
|
||||||
* @param h the height of the paint area
|
|
||||||
*/
|
|
||||||
private void render(Graphics g, int x, int y, int w, int h) {
|
|
||||||
if (useVolatile) {
|
|
||||||
volatileRender(g, x, y, w, h);
|
|
||||||
} else {
|
|
||||||
heapRender(g, x, y, w, h);
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// Restart the resource reaper timer if neccessary
|
|
||||||
//
|
|
||||||
if (!frameRendered) {
|
|
||||||
frameRendered = true;
|
|
||||||
if (!resourceTimer.isRunning()) {
|
|
||||||
resourceTimer.restart();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int imgWidth = 0, imgHeight = 0;
|
|
||||||
|
|
||||||
private final void update(final int width, final int height) {
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
//
|
|
||||||
// If the image changed size, resize the component to fit
|
|
||||||
//
|
|
||||||
if (width != imgWidth || height != imgHeight) {
|
|
||||||
renderComponent.setPreferredSize(new Dimension(width, height));
|
|
||||||
imgWidth = width;
|
|
||||||
imgHeight = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (renderComponent.isVisible()) {
|
|
||||||
renderComponent.paintImmediately(0, 0,
|
|
||||||
renderComponent.getWidth(), renderComponent.getHeight());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private BufferedImage getBufferedImage(int width, int height) {
|
|
||||||
if (currentImage != null && currentImage.getWidth() == width
|
|
||||||
&& currentImage.getHeight() == height) {
|
|
||||||
return currentImage;
|
|
||||||
}
|
|
||||||
if (currentImage != null) {
|
|
||||||
currentImage.flush();
|
|
||||||
}
|
|
||||||
currentImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
|
||||||
currentImage.setAccelerationPriority(0.0f);
|
|
||||||
return currentImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class AppSinkListener implements AppSink.NEW_SAMPLE, AppSink.NEW_PREROLL {
|
|
||||||
|
|
||||||
public void rgbFrame(boolean isPrerollFrame, int width, int height, IntBuffer rgb) {
|
|
||||||
// If the EDT is still copying data from the buffer, just drop this frame
|
|
||||||
//
|
|
||||||
if (!bufferLock.tryLock()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// If there is already a swing update pending, also drop this frame.
|
|
||||||
//
|
|
||||||
if (updatePending && !isPrerollFrame) {
|
|
||||||
bufferLock.unlock();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
final BufferedImage renderImage = getBufferedImage(width, height);
|
|
||||||
int[] pixels = ((DataBufferInt) renderImage.getRaster().getDataBuffer()).getData();
|
|
||||||
rgb.get(pixels, 0, width * height);
|
|
||||||
updatePending = true;
|
|
||||||
} finally {
|
|
||||||
bufferLock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// int scaledWidth = currentImage.getWidth();
|
|
||||||
// if (keepAspect) {
|
|
||||||
// // Scale width according to pixel aspect ratio.
|
|
||||||
// Caps videoCaps = videoPad.getNegotiatedCaps();
|
|
||||||
// Structure capsStruct = videoCaps.getStructure(0);
|
|
||||||
// if (capsStruct.hasField("pixel-aspect-ratio")) {
|
|
||||||
// Fraction pixelAspectRatio = capsStruct.getFraction("pixel-aspect-ratio");
|
|
||||||
// scaledWidth = scaledWidth * pixelAspectRatio.getNumerator() / pixelAspectRatio.getDenominator();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Tell swing to use the new buffer
|
|
||||||
update(currentImage.getWidth(), currentImage.getHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FlowReturn newSample(AppSink elem) {
|
|
||||||
Sample sample = elem.pullSample();
|
|
||||||
Structure capsStruct = sample.getCaps().getStructure(0);
|
|
||||||
int w = capsStruct.getInteger("width");
|
|
||||||
int h = capsStruct.getInteger("height");
|
|
||||||
Buffer buffer = sample.getBuffer();
|
|
||||||
ByteBuffer bb = buffer.map(false);
|
|
||||||
if (bb != null) {
|
|
||||||
rgbFrame(false, w, h, bb.asIntBuffer());
|
|
||||||
buffer.unmap();
|
|
||||||
}
|
|
||||||
sample.dispose();
|
|
||||||
return FlowReturn.OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FlowReturn newPreroll(AppSink elem) {
|
|
||||||
Sample sample = elem.pullPreroll();
|
|
||||||
Structure capsStruct = sample.getCaps().getStructure(0);
|
|
||||||
int w = capsStruct.getInteger("width");
|
|
||||||
int h = capsStruct.getInteger("height");
|
|
||||||
Buffer buffer = sample.getBuffer();
|
|
||||||
ByteBuffer bb = buffer.map(false);
|
|
||||||
if (bb != null) {
|
|
||||||
rgbFrame(false, w, h, bb.asIntBuffer());
|
|
||||||
buffer.unmap();
|
|
||||||
}
|
|
||||||
sample.dispose();
|
|
||||||
return FlowReturn.OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -23,16 +23,11 @@ import java.awt.Dimension;
|
|||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.BoxLayout;
|
import javax.swing.BoxLayout;
|
||||||
@ -45,25 +40,15 @@ import javax.swing.SwingWorker;
|
|||||||
import javax.swing.Timer;
|
import javax.swing.Timer;
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
import org.freedesktop.gstreamer.Bus;
|
|
||||||
import org.freedesktop.gstreamer.ClockTime;
|
import org.freedesktop.gstreamer.ClockTime;
|
||||||
import org.freedesktop.gstreamer.Format;
|
|
||||||
import org.freedesktop.gstreamer.Gst;
|
import org.freedesktop.gstreamer.Gst;
|
||||||
import org.freedesktop.gstreamer.GstException;
|
import org.freedesktop.gstreamer.GstException;
|
||||||
import org.freedesktop.gstreamer.GstObject;
|
|
||||||
import org.freedesktop.gstreamer.Message;
|
|
||||||
import org.freedesktop.gstreamer.MessageType;
|
|
||||||
import org.freedesktop.gstreamer.State;
|
import org.freedesktop.gstreamer.State;
|
||||||
import org.freedesktop.gstreamer.StateChangeReturn;
|
import org.freedesktop.gstreamer.StateChangeReturn;
|
||||||
import org.freedesktop.gstreamer.Structure;
|
|
||||||
import org.freedesktop.gstreamer.elements.PlayBin;
|
import org.freedesktop.gstreamer.elements.PlayBin;
|
||||||
import org.netbeans.api.progress.ProgressHandle;
|
import org.netbeans.api.progress.ProgressHandle;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
|
||||||
import org.openide.util.lookup.ServiceProviders;
|
|
||||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.corecomponents.FrameCapture;
|
|
||||||
import org.sleuthkit.autopsy.corecomponents.VideoFrame;
|
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.VideoUtils;
|
import org.sleuthkit.autopsy.coreutils.VideoUtils;
|
||||||
@ -76,13 +61,15 @@ import org.sleuthkit.datamodel.TskData;
|
|||||||
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
||||||
public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaViewPanel {
|
public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaViewPanel {
|
||||||
|
|
||||||
private static final String[] EXTENSIONS = new String[] {
|
private static final String[] FILE_EXTENSIONS = new String[] {
|
||||||
|
".3g2",
|
||||||
".3gp",
|
".3gp",
|
||||||
".aac", //froze
|
".3gpp",
|
||||||
|
".aac",
|
||||||
".aif",
|
".aif",
|
||||||
".aiff",
|
".aiff",
|
||||||
".amr",
|
".amr",
|
||||||
".asf", //froze
|
".asf",
|
||||||
".au",
|
".au",
|
||||||
".avi",
|
".avi",
|
||||||
".flac",
|
".flac",
|
||||||
@ -92,36 +79,35 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
".mka",
|
".mka",
|
||||||
".mkv",
|
".mkv",
|
||||||
".mov",
|
".mov",
|
||||||
".mp2", //froze
|
".mp2",
|
||||||
".mp3", //froze
|
".mp3",
|
||||||
".mp4",
|
".mp4",
|
||||||
".mpeg",
|
".mpeg",
|
||||||
".mpg",
|
".mpg",
|
||||||
".mxf",
|
".mxf",
|
||||||
".ogg",
|
".ogg",
|
||||||
".ra", //froze
|
|
||||||
".wav",
|
".wav",
|
||||||
".webm",
|
".webm",
|
||||||
".wma",
|
".wma",
|
||||||
".wmv",
|
".wmv",
|
||||||
}; //NON-NLS
|
}; //NON-NLS
|
||||||
private static final List<String> MIMETYPES = Arrays.asList(
|
private static final List<String> MIME_TYPES = Arrays.asList(
|
||||||
"video/3gpp", //tested
|
"video/3gpp",
|
||||||
"audio/aiff", //tested
|
"video/3gpp2",
|
||||||
|
"audio/aiff",
|
||||||
"audio/amr-wb",
|
"audio/amr-wb",
|
||||||
"audio/basic",
|
"audio/basic",
|
||||||
"audio/mp4", //tested
|
"audio/mp4",
|
||||||
"video/mp4", //tested
|
"video/mp4",
|
||||||
"audio/mpeg", //froze
|
"audio/mpeg",
|
||||||
"video/mpeg", //tested
|
"video/mpeg",
|
||||||
"audio/mpeg3",
|
"audio/mpeg3",
|
||||||
"application/mxf", //tested
|
"application/mxf",
|
||||||
"application/ogg",
|
"application/ogg",
|
||||||
"video/quicktime", //tested
|
"video/quicktime",
|
||||||
"audio/vorbis", //tested
|
"audio/vorbis",
|
||||||
"application/vnd.rn-realmedia",
|
"audio/vnd.wave",
|
||||||
"audio/vnd.wave", //tested
|
"video/webm",
|
||||||
"video/webm", //tested
|
|
||||||
"video/x-3ivx",
|
"video/x-3ivx",
|
||||||
"audio/x-aac",
|
"audio/x-aac",
|
||||||
"audio/x-adpcm",
|
"audio/x-adpcm",
|
||||||
@ -131,8 +117,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
"audio/x-dv",
|
"audio/x-dv",
|
||||||
"video/x-dv",
|
"video/x-dv",
|
||||||
"video/x-ffv",
|
"video/x-ffv",
|
||||||
"audio/x-flac", //tested
|
"audio/x-flac",
|
||||||
"video/x-flv", //tested
|
"video/x-flv",
|
||||||
"audio/x-gsm",
|
"audio/x-gsm",
|
||||||
"video/x-h263",
|
"video/x-h263",
|
||||||
"video/x-h264",
|
"video/x-h264",
|
||||||
@ -142,22 +128,22 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
"audio/x-ircam",
|
"audio/x-ircam",
|
||||||
"video/x-jpeg",
|
"video/x-jpeg",
|
||||||
"audio/x-m4a",
|
"audio/x-m4a",
|
||||||
"video/x-m4v", //tested
|
"video/x-m4v",
|
||||||
"audio/x-mace",
|
"audio/x-mace",
|
||||||
"audio/x-matroska", //tested
|
"audio/x-matroska",
|
||||||
"video/x-matroska", //tested
|
"video/x-matroska",
|
||||||
"audio/x-mpeg",
|
"audio/x-mpeg",
|
||||||
"video/x-mpeg",
|
"video/x-mpeg",
|
||||||
"audio/x-mpeg-3",
|
"audio/x-mpeg-3",
|
||||||
"video/x-ms-asf",
|
"video/x-ms-asf",
|
||||||
"audio/x-ms-wma", //tested
|
"audio/x-ms-wma",
|
||||||
"video/x-ms-wmv", //tested
|
"video/x-ms-wmv",
|
||||||
"video/x-msmpeg",
|
"video/x-msmpeg",
|
||||||
"video/x-msvideo", //tested
|
"video/x-msvideo",
|
||||||
"video/x-msvideocodec",
|
"video/x-msvideocodec",
|
||||||
"audio/x-mulaw",
|
"audio/x-mulaw",
|
||||||
"audio/x-nist",
|
"audio/x-nist",
|
||||||
"audio/x-oggflac", //tested
|
"audio/x-oggflac",
|
||||||
"audio/x-paris",
|
"audio/x-paris",
|
||||||
"audio/x-qdm2",
|
"audio/x-qdm2",
|
||||||
"audio/x-raw",
|
"audio/x-raw",
|
||||||
@ -182,9 +168,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
private boolean gstInited;
|
private boolean gstInited;
|
||||||
private static final String MEDIA_PLAYER_ERROR_STRING = NbBundle.getMessage(MediaPlayerPanel.class, "GstVideoPanel.cannotProcFile.err");
|
private static final String MEDIA_PLAYER_ERROR_STRING = NbBundle.getMessage(MediaPlayerPanel.class, "GstVideoPanel.cannotProcFile.err");
|
||||||
//playback
|
//playback
|
||||||
private boolean durationSet;
|
|
||||||
private long durationMillis = 0;
|
private long durationMillis = 0;
|
||||||
//DLG: private VideoProgressWorker videoProgressWorker;
|
|
||||||
private int totalHours, totalMinutes, totalSeconds;
|
private int totalHours, totalMinutes, totalSeconds;
|
||||||
private volatile PlayBin gstPlayBin;
|
private volatile PlayBin gstPlayBin;
|
||||||
private GstVideoRendererPanel gstVideoRenderer;
|
private GstVideoRendererPanel gstVideoRenderer;
|
||||||
@ -192,43 +176,10 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
private final Object playbinLock = new Object(); // lock for synchronization of gstPlayBin player
|
private final Object playbinLock = new Object(); // lock for synchronization of gstPlayBin player
|
||||||
private AbstractFile currentFile;
|
private AbstractFile currentFile;
|
||||||
|
|
||||||
private Timer timer; //DLG:
|
private Timer timer;
|
||||||
private ExtractMedia extractMediaWorker; //DLG:
|
private ExtractMedia extractMediaWorker;
|
||||||
|
|
||||||
private final long END_TIME_MARGIN_NS = 50000000; //DLG:
|
private final long END_TIME_MARGIN_NS = 50000000;
|
||||||
|
|
||||||
//DLG:
|
|
||||||
/*private Bus.STATE_CHANGED busStateChangedListener = new Bus.STATE_CHANGED() {
|
|
||||||
@Override
|
|
||||||
public void stateChanged(GstObject source, State old, State current, State pending) {
|
|
||||||
if (durationSet == false && current.equals(State.PLAYING)) {
|
|
||||||
durationSet = true;
|
|
||||||
|
|
||||||
durationMillis = gstPlayBin.queryDuration().toMillis();
|
|
||||||
|
|
||||||
// pick out the total hours, minutes, seconds
|
|
||||||
long durationSeconds = (int) durationMillis / 1000;
|
|
||||||
totalHours = (int) durationSeconds / 3600;
|
|
||||||
durationSeconds -= totalHours * 3600;
|
|
||||||
totalMinutes = (int) durationSeconds / 60;
|
|
||||||
durationSeconds -= totalMinutes * 60;
|
|
||||||
totalSeconds = (int) durationSeconds;
|
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
progressSlider.setMaximum((int) durationMillis);
|
|
||||||
progressSlider.setMinimum(0);
|
|
||||||
|
|
||||||
pauseButton.setText("||");
|
|
||||||
videoProgressWorker = new VideoProgressWorker();
|
|
||||||
videoProgressWorker.execute();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!current.equals(State.PLAYING)) {
|
|
||||||
System.out.println();
|
|
||||||
System.out.println();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new form MediaViewVideoPanel
|
* Creates new form MediaViewVideoPanel
|
||||||
@ -269,21 +220,19 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
}
|
}
|
||||||
|
|
||||||
progressSlider.setEnabled(false); // disable slider; enable after user plays vid
|
progressSlider.setEnabled(false); // disable slider; enable after user plays vid
|
||||||
//DLG:
|
progressSlider.setMinimum(0);
|
||||||
progressSlider.setMinimum(0); //DLG:
|
progressSlider.setMaximum(2000);
|
||||||
progressSlider.setMaximum(2000); //DLG:
|
|
||||||
progressSlider.setValue(0);
|
progressSlider.setValue(0);
|
||||||
//DLG:
|
|
||||||
progressSlider.addChangeListener(new ChangeListener() {
|
progressSlider.addChangeListener(new ChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void stateChanged(ChangeEvent e) {
|
public void stateChanged(ChangeEvent e) {
|
||||||
if (gstPlayBin == null) { //DLG: Is this needed?
|
if (gstPlayBin == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (progressSlider.getValueIsAdjusting()) {
|
if (progressSlider.getValueIsAdjusting()) {
|
||||||
synchronized (playbinLock) {
|
synchronized (playbinLock) {
|
||||||
long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS);
|
long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS);
|
||||||
long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); //DLG: Not used!
|
long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS);
|
||||||
if (duration > 0) {
|
if (duration > 0) {
|
||||||
double relativePosition = progressSlider.getValue() / 2000.0;
|
double relativePosition = progressSlider.getValue() / 2000.0;
|
||||||
gstPlayBin.seek((long) (relativePosition * duration), TimeUnit.NANOSECONDS);
|
gstPlayBin.seek((long) (relativePosition * duration), TimeUnit.NANOSECONDS);
|
||||||
@ -295,34 +244,6 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//DLG:
|
|
||||||
/*progressSlider.addChangeListener((ChangeEvent e) -> {
|
|
||||||
/**
|
|
||||||
* Should always try to synchronize any call to
|
|
||||||
* progressSlider.setValue() to avoid a different thread changing
|
|
||||||
* playbin while stateChanged() is processing
|
|
||||||
*/
|
|
||||||
//DLG:
|
|
||||||
/* int time = progressSlider.getValue();
|
|
||||||
synchronized (playbinLock) {
|
|
||||||
if (gstPlayBin != null && !autoTracking) {
|
|
||||||
State orig = gstPlayBin.getState();
|
|
||||||
if (gstPlayBin.pause() == StateChangeReturn.FAILURE) {
|
|
||||||
logger.log(Level.WARNING, "Attempt to call PlayBin.pause() failed."); //NON-NLS
|
|
||||||
infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
State test = gstPlayBin.getState(); //DLG: Remove this!
|
|
||||||
if (gstPlayBin.seek(ClockTime.fromMillis(time)) == false) {
|
|
||||||
logger.log(Level.WARNING, "Attempt to call PlayBin.seek() failed."); //NON-NLS
|
|
||||||
infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
gstPlayBin.setState(orig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean initGst() {
|
private boolean initGst() {
|
||||||
@ -392,7 +313,6 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
infoLabel.setToolTipText(path);
|
infoLabel.setToolTipText(path);
|
||||||
pauseButton.setEnabled(true);
|
pauseButton.setEnabled(true);
|
||||||
progressSlider.setEnabled(true);
|
progressSlider.setEnabled(true);
|
||||||
//DLG:
|
|
||||||
timer = new Timer(50, e -> {
|
timer = new Timer(50, e -> {
|
||||||
if (!progressSlider.getValueIsAdjusting()) {
|
if (!progressSlider.getValueIsAdjusting()) {
|
||||||
long duration;
|
long duration;
|
||||||
@ -445,8 +365,6 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
});
|
});
|
||||||
timer.start();
|
timer.start();
|
||||||
|
|
||||||
|
|
||||||
//gstVideoComponent = new SimpleVideoComponent();
|
|
||||||
gstVideoRenderer = new GstVideoRendererPanel();
|
gstVideoRenderer = new GstVideoRendererPanel();
|
||||||
synchronized (playbinLock) {
|
synchronized (playbinLock) {
|
||||||
if (gstPlayBin != null) {
|
if (gstPlayBin != null) {
|
||||||
@ -458,21 +376,12 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
videoPanel.removeAll();
|
videoPanel.removeAll();
|
||||||
|
|
||||||
videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS));
|
videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS));
|
||||||
//videoPanel.add(gstVideoComponent);
|
|
||||||
|
|
||||||
videoPanel.add(gstVideoRenderer);//add jfx ui to JPanel
|
videoPanel.add(gstVideoRenderer);//add jfx ui to JPanel
|
||||||
|
|
||||||
videoPanel.setVisible(true);
|
videoPanel.setVisible(true);
|
||||||
|
|
||||||
gstPlayBin.setInputFile(ioFile);
|
gstPlayBin.setInputFile(ioFile);
|
||||||
|
|
||||||
//DLG:
|
|
||||||
/*if (gstPlayBin.setState(State.READY) == StateChangeReturn.FAILURE) {
|
|
||||||
logger.log(Level.WARNING, "Attempt to call PlayBin.setState(State.READY) failed."); //NON-NLS
|
|
||||||
infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//DLG: gstPlayBin.getBus().connect(busStateChangedListener);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -481,8 +390,6 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
* Prepare this MediaViewVideoPanel to accept a different media file.
|
* Prepare this MediaViewVideoPanel to accept a different media file.
|
||||||
*/
|
*/
|
||||||
void reset() {
|
void reset() {
|
||||||
|
|
||||||
//DLG:
|
|
||||||
if (timer != null) {
|
if (timer != null) {
|
||||||
timer.stop();
|
timer.stop();
|
||||||
}
|
}
|
||||||
@ -505,37 +412,12 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//DLG:
|
|
||||||
/*if (gstPlayBin.setState(State.NULL) == StateChangeReturn.FAILURE) {
|
|
||||||
logger.log(Level.WARNING, "Attempt to call PlayBin.setState(State.NULL) failed."); //NON-NLS
|
|
||||||
infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (gstPlayBin.getState().equals(State.NULL)) {
|
|
||||||
gstPlayBin.getBus().disconnect(busStateChangedListener);
|
|
||||||
gstPlayBin.dispose();
|
|
||||||
}*/
|
|
||||||
gstPlayBin.dispose();
|
gstPlayBin.dispose();
|
||||||
gstPlayBin = null;
|
gstPlayBin = null;
|
||||||
}
|
}
|
||||||
//gstVideoComponent = null;
|
|
||||||
gstVideoRenderer = null;
|
gstVideoRenderer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get rid of any existing videoProgressWorker thread
|
|
||||||
//DLG:
|
|
||||||
/*if (videoProgressWorker != null) {
|
|
||||||
videoProgressWorker.cancel(true);
|
|
||||||
videoProgressWorker = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
durationSet = false;
|
|
||||||
|
|
||||||
durationMillis = 0;
|
|
||||||
totalHours = 0;
|
|
||||||
totalMinutes = 0;
|
|
||||||
totalSeconds = 0;
|
|
||||||
*/
|
|
||||||
progressSlider.setValue(0);
|
progressSlider.setValue(0);
|
||||||
pauseButton.setText("►");
|
pauseButton.setText("►");
|
||||||
|
|
||||||
@ -641,13 +523,6 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pauseButton.setText("►");
|
pauseButton.setText("►");
|
||||||
// Is this call necessary considering we just called gstPlayBin.pause()?
|
|
||||||
//DLG:
|
|
||||||
/*if (gstPlayBin.setState(State.PAUSED) == StateChangeReturn.FAILURE) {
|
|
||||||
logger.log(Level.WARNING, "Attempt to call PlayBin.setState(State.PAUSED) failed."); //NON-NLS
|
|
||||||
infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
} else if (state.equals(State.PAUSED)) {
|
} else if (state.equals(State.PAUSED)) {
|
||||||
if (gstPlayBin.play() == StateChangeReturn.FAILURE) {
|
if (gstPlayBin.play() == StateChangeReturn.FAILURE) {
|
||||||
logger.log(Level.WARNING, "Attempt to call PlayBin.play() failed."); //NON-NLS
|
logger.log(Level.WARNING, "Attempt to call PlayBin.play() failed."); //NON-NLS
|
||||||
@ -655,13 +530,6 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pauseButton.setText("||");
|
pauseButton.setText("||");
|
||||||
// Is this call necessary considering we just called gstPlayBin.play()?
|
|
||||||
//DLG:
|
|
||||||
/*if (gstPlayBin.setState(State.PLAYING) == StateChangeReturn.FAILURE) {
|
|
||||||
logger.log(Level.WARNING, "Attempt to call PlayBin.setState(State.PLAYING) failed."); //NON-NLS
|
|
||||||
infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
} else if (state.equals(State.READY) || state.equals(State.NULL)) {
|
} else if (state.equals(State.READY) || state.equals(State.NULL)) {
|
||||||
final File tempVideoFile;
|
final File tempVideoFile;
|
||||||
try {
|
try {
|
||||||
@ -692,117 +560,6 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
private javax.swing.JPanel videoPanel;
|
private javax.swing.JPanel videoPanel;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
//DLG:
|
|
||||||
/*
|
|
||||||
private class VideoProgressWorker extends SwingWorker<Object, Object> {
|
|
||||||
|
|
||||||
private final String durationFormat = "%02d:%02d:%02d/%02d:%02d:%02d "; //NON-NLS
|
|
||||||
private long millisElapsed = 0;
|
|
||||||
private final long INTER_FRAME_PERIOD_MS = 20;
|
|
||||||
private final long END_TIME_MARGIN_MS = 50;
|
|
||||||
|
|
||||||
private boolean isPlayBinReady() {
|
|
||||||
synchronized (playbinLock) {
|
|
||||||
return gstPlayBin != null && !gstPlayBin.getState().equals(State.NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resetVideo() throws Exception {
|
|
||||||
synchronized (playbinLock) {
|
|
||||||
if (gstPlayBin != null) {
|
|
||||||
if (gstPlayBin.stop() == StateChangeReturn.FAILURE) {
|
|
||||||
logger.log(Level.WARNING, "Attempt to call PlayBin.stop() failed."); //NON-NLS
|
|
||||||
infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
|
|
||||||
}
|
|
||||||
// ready to be played again
|
|
||||||
if (gstPlayBin.setState(State.READY) == StateChangeReturn.FAILURE) {
|
|
||||||
logger.log(Level.WARNING, "Attempt to call PlayBin.setState(State.READY) failed."); //NON-NLS
|
|
||||||
infoLabel.setText(MEDIA_PLAYER_ERROR_STRING);
|
|
||||||
}
|
|
||||||
gstPlayBin.getState(); //NEW
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pauseButton.setText("►");
|
|
||||||
progressSlider.setValue(0);
|
|
||||||
|
|
||||||
String durationStr = String.format(durationFormat, 0, 0, 0,
|
|
||||||
totalHours, totalMinutes, totalSeconds);
|
|
||||||
progressLabel.setText(durationStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true while millisElapsed is greater than END_TIME_MARGIN_MS
|
|
||||||
* from durationMillis. This is used to indicate when the video
|
|
||||||
* has ended because for some videos the time elapsed never
|
|
||||||
* becomes equal to the reported duration of the video.
|
|
||||||
*/
|
|
||||||
//DLG:
|
|
||||||
/*
|
|
||||||
private boolean hasNotEnded() {
|
|
||||||
return (durationMillis - millisElapsed) > END_TIME_MARGIN_MS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Object doInBackground() throws Exception {
|
|
||||||
|
|
||||||
// enable the slider
|
|
||||||
progressSlider.setEnabled(true);
|
|
||||||
|
|
||||||
ClockTime pos;
|
|
||||||
while (hasNotEnded() && isPlayBinReady() && !isCancelled()) {
|
|
||||||
|
|
||||||
synchronized (playbinLock) {
|
|
||||||
pos = gstPlayBin.queryPosition();
|
|
||||||
}
|
|
||||||
millisElapsed = pos.toMillis();
|
|
||||||
|
|
||||||
// pick out the elapsed hours, minutes, seconds
|
|
||||||
long secondsElapsed = millisElapsed / 1000;
|
|
||||||
int elapsedHours = (int) secondsElapsed / 3600;
|
|
||||||
secondsElapsed -= elapsedHours * 3600;
|
|
||||||
int elapsedMinutes = (int) secondsElapsed / 60;
|
|
||||||
secondsElapsed -= elapsedMinutes * 60;
|
|
||||||
int elapsedSeconds = (int) secondsElapsed;
|
|
||||||
|
|
||||||
String durationStr = String.format(durationFormat,
|
|
||||||
elapsedHours, elapsedMinutes, elapsedSeconds,
|
|
||||||
totalHours, totalMinutes, totalSeconds);
|
|
||||||
|
|
||||||
progressLabel.setText(durationStr);
|
|
||||||
autoTracking = true;
|
|
||||||
progressSlider.setValue((int) millisElapsed);
|
|
||||||
autoTracking = false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(INTER_FRAME_PERIOD_MS);
|
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// disable the slider
|
|
||||||
progressSlider.setEnabled(false);
|
|
||||||
|
|
||||||
resetVideo();
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void done() {
|
|
||||||
// see if any exceptions were thrown
|
|
||||||
try {
|
|
||||||
get();
|
|
||||||
} catch (InterruptedException | ExecutionException ex) {
|
|
||||||
logger.log(Level.WARNING, "Error updating video progress: {0}", ex.getMessage()); //NON-NLS
|
|
||||||
infoLabel.setText(NbBundle.getMessage(this.getClass(), "GstVideoPanel.progress.infoLabel.updateErr",
|
|
||||||
ex.getMessage()));
|
|
||||||
} // catch and ignore if we were cancelled
|
|
||||||
catch (java.util.concurrent.CancellationException ex) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} //end class progress worker
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Thread that extracts and plays a file
|
* Thread that extracts and plays a file
|
||||||
*/
|
*/
|
||||||
@ -863,7 +620,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
synchronized (playbinLock) {
|
synchronized (playbinLock) {
|
||||||
gstPlayBin.seek(ClockTime.ZERO); //DLG:
|
gstPlayBin.seek(ClockTime.ZERO);
|
||||||
// must play, then pause and get state to get duration.
|
// must play, then pause and get state to get duration.
|
||||||
if (gstPlayBin.play() == StateChangeReturn.FAILURE) {
|
if (gstPlayBin.play() == StateChangeReturn.FAILURE) {
|
||||||
logger.log(Level.WARNING, "Attempt to call PlayBin.play() failed."); //NON-NLS
|
logger.log(Level.WARNING, "Attempt to call PlayBin.play() failed."); //NON-NLS
|
||||||
@ -877,12 +634,12 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getSupportedExtensions() {
|
public List<String> getSupportedExtensions() {
|
||||||
return Arrays.asList(EXTENSIONS.clone());
|
return Arrays.asList(FILE_EXTENSIONS.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getSupportedMimeTypes() {
|
public List<String> getSupportedMimeTypes() {
|
||||||
return MIMETYPES;
|
return MIME_TYPES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user