Привет, друзья. На самом деле я разрабатываю свой собственный видеоплеер, используя библиотеки VLCJ, я использую холст поверх JFrame и панель параметров с кнопками для воспроизведения, остановки и т. Д. В этот момент видеоплеер и все кнопки работают, но это настолько медленный, а частота кадров такая низкая, я думаю, что использование холста - не лучший способ воспроизведения видео, или, может быть, мой код не оптимизирован.
Основной класс:
package vlcvideo;
import java.io.File;
import javax.swing.JFileChooser;
public class VlcVideo {
static JFileChooser filex = new JFileChooser();
public static void main(String[] args)
{
String rutaVlc = "C:/vlc64/vlc";
String rutaVideo="/src/vlcVideo/c.mp4";
File ourFile;
//seleccionar la ruta de instalacion del vlc
/*filex.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);//selecciona solo directorios
filex.showSaveDialog(null);
ourFile=filex.getSelectedFile();
rutaVlc=ourFile.getAbsolutePath();*/
/*
filex.setFileSelectionMode(JFileChooser.FILES_ONLY);
filex.showSaveDialog(null);
ourFile=filex.getSelectedFile();
rutaVideo=ourFile.getAbsolutePath();*/
System.out.println(rutaVlc + "ruta DLL");
System.out.println(rutaVideo + " ruta video");
//new MediaPlayer(rutaVlc,rutaVideo).run();
//MediaPlayer mediaPlayer = new MediaPlayer(rutaVlc,rutaVideo);
prueba pb = new prueba(rutaVlc,rutaVideo);
// reproductor rp = new reproductor(rutaVlc,rutaVideo);
// rp.setVisible(true);
}
}
Класс кадра:
package vlcvideo;
import com.sun.jna.NativeLibrary;
/*import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IStream;
import com.xuggle.xuggler.IStreamCoder;*/
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.concurrent.TimeUnit;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import uk.co.caprica.vlcj.player.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;
public class prueba extends javax.swing.JFrame
{
private static final int SKIP_TIME_MS = 10 * 1000;
private boolean mousePressedPlaying = false;
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension tm = tk.getScreenSize();
private final String vlc;
Canvas c;
private final String video;
EmbeddedMediaPlayer mediaPlayer;
public prueba(String vlc,String video)
{
this.video=video;
this.vlc=vlc;
initComponents();
initMyComponentes();
createCanvas();
createMedia();
printTime();
}
public void printTime()
{
/*while(true)
{
final long time = mediaPlayer.getTime();
final int position = (int)(mediaPlayer.getPosition() * 1000.0f);
final int chapter = mediaPlayer.getChapter();
final int chapterCount = mediaPlayer.getChapterCount();
int posicionSlider=positionSlider.getValue();
if(mediaPlayer.isPlaying())
{
updateTime(time);
updatePosition(position);
updateChapter(chapter, chapterCount);
}
} */
timeThread tt = new timeThread(this,mediaPlayer);
tt.start();
}
public void createCanvas()
{
c = new Canvas();
c.setBackground(Color.black);
int panelHeight = panelVideo.getHeight();
int panelWidth = panelVideo.getWidth();
System.out.println(panelHeight + " " +panelWidth);
c.setBounds(0, 0,panelWidth, panelHeight);
panelVideo.add(c);
}
public void initMyComponentes()
{
positionSlider.setMinimum(0);
positionSlider.setMaximum(1000);
positionSlider.setValue(0);
positionSlider.setToolTipText("Position");
volumeSlider.setOrientation(JSlider.HORIZONTAL);
volumeSlider.setToolTipText("Change volume");
System.out.println(tm.height + " * "+tm.width);
}
/* public void duracion()
{
IContainer container = IContainer.make();
int result = container.open(video, IContainer.Type.READ, null);
if(result<0)
throw new RuntimeException("Failed to open media file");
long duration = container.getDuration();
System.out.println("Duration (ms): " + duration);
}*/
public void createMedia()
{
NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(),vlc);
MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory();
mediaPlayer = mediaPlayerFactory.newEmbeddedMediaPlayer();
mediaPlayer.setVideoSurface(mediaPlayerFactory.newVideoSurface(c));
mediaPlayer.toggleFullScreen();
mediaPlayer.setEnableMouseInputHandling(false);
mediaPlayer.setEnableKeyInputHandling(true);
mediaPlayer.prepareMedia(video);
mediaPlayer.play();
this.setVisible(true);
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jPanel2 = new javax.swing.JPanel();
panelVideo = new javax.swing.JPanel();
btnMute = new javax.swing.JButton();
btnPlay = new javax.swing.JButton();
btnPause = new javax.swing.JButton();
btnStop = new javax.swing.JButton();
positionSlider = new javax.swing.JSlider();
lblTime = new javax.swing.JLabel();
chapterLabel = new javax.swing.JLabel();
volumeSlider = new javax.swing.JSlider();
btnRewind = new javax.swing.JButton();
btnRewind2 = new javax.swing.JButton();
lblTotal = new javax.swing.JLabel();
jLabel1 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jPanel2.setBackground(new java.awt.Color(255, 51, 51));
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 0, Short.MAX_VALUE)
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 0, Short.MAX_VALUE)
);
javax.swing.GroupLayout panelVideoLayout = new javax.swing.GroupLayout(panelVideo);
panelVideo.setLayout(panelVideoLayout);
panelVideoLayout.setHorizontalGroup(
panelVideoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 0, Short.MAX_VALUE)
);
panelVideoLayout.setVerticalGroup(
panelVideoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 256, Short.MAX_VALUE)
);
btnMute.setIcon(new javax.swing.ImageIcon(getClass().getResource("/fotos/mute.jpg"))); // NOI18N
btnMute.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnMuteActionPerformed(evt);
}
});
btnPlay.setIcon(new javax.swing.ImageIcon(getClass().getResource("/fotos/Play.png"))); // NOI18N
btnPlay.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnPlayActionPerformed(evt);
}
});
btnPause.setIcon(new javax.swing.ImageIcon(getClass().getResource("/fotos/Pause.jpg"))); // NOI18N
btnPause.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnPauseActionPerformed(evt);
}
});
btnStop.setIcon(new javax.swing.ImageIcon(getClass().getResource("/fotos/stop.jpg"))); // NOI18N
btnStop.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnStopActionPerformed(evt);
}
});
positionSlider.setMinorTickSpacing(10);
positionSlider.setPaintTicks(true);
positionSlider.addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
positionSliderMousePressed(evt);
}
public void mouseReleased(java.awt.event.MouseEvent evt) {
positionSliderMouseReleased(evt);
}
});
lblTime.setText("0");
chapterLabel.setText("00/00");
volumeSlider.setMinorTickSpacing(10);
volumeSlider.setPaintLabels(true);
volumeSlider.setPaintTicks(true);
volumeSlider.setToolTipText("");
volumeSlider.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
volumeSliderStateChanged(evt);
}
});
btnRewind.setText("<<");
btnRewind.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnRewindActionPerformed(evt);
}
});
btnRewind2.setText(">>");
btnRewind2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnRewind2ActionPerformed(evt);
}
});
lblTotal.setText("/0t");
jLabel1.setText("Volumen");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(178, 178, 178)
.addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addComponent(panelVideo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap())
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(btnPlay, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnPause, javax.swing.GroupLayout.PREFERRED_SIZE, 43, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnStop, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(61, 61, 61)
.addComponent(positionSlider, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(91, 91, 91))
.addGroup(layout.createSequentialGroup()
.addGap(171, 171, 171)
.addComponent(lblTime)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lblTotal)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 152, Short.MAX_VALUE)
.addComponent(btnRewind)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(chapterLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jLabel1)
.addGap(37, 37, 37)
.addComponent(btnMute, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(19, 19, 19))
.addGroup(layout.createSequentialGroup()
.addGap(1, 1, 1)
.addComponent(btnRewind2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 109, Short.MAX_VALUE)
.addComponent(volumeSlider, javax.swing.GroupLayout.PREFERRED_SIZE, 128, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(34, 34, 34))))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(panelVideo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(33, 33, 33)
.addComponent(positionSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lblTime)
.addComponent(lblTotal)))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(28, 28, 28)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(chapterLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnRewind)
.addComponent(btnRewind2)))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel1)
.addComponent(btnMute, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(volumeSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))))
.addContainerGap())
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(btnPause, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnPlay)
.addComponent(btnStop, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(19, 19, 19))))
);
pack();
}// </editor-fold>
private void btnPlayActionPerformed(java.awt.event.ActionEvent evt) {
mediaPlayer.play();
}
private void btnPauseActionPerformed(java.awt.event.ActionEvent evt) {
mediaPlayer.pause();
}
private void btnStopActionPerformed(java.awt.event.ActionEvent evt) {
mediaPlayer.stop();
}
private void btnMuteActionPerformed(java.awt.event.ActionEvent evt) {
mediaPlayer.mute();
}
private void positionSliderMousePressed(java.awt.event.MouseEvent evt) {
if(mediaPlayer.isPlaying()) {
mousePressedPlaying = true;
mediaPlayer.pause();
}
else
{
mousePressedPlaying = false;
}
setSliderBasedPosition();
}
private void positionSliderMouseReleased(java.awt.event.MouseEvent evt) {
setSliderBasedPosition();
updateUIState();
}
private void volumeSliderStateChanged(javax.swing.event.ChangeEvent evt) {
JSlider source = (JSlider)evt.getSource();
// if(!source.getValueIsAdjusting()) {
mediaPlayer.setVolume(source.getValue());
// }
}
private void btnRewindActionPerformed(java.awt.event.ActionEvent evt) {
skip(-SKIP_TIME_MS);
}
private void btnRewind2ActionPerformed(java.awt.event.ActionEvent evt) {
skip(SKIP_TIME_MS);
}
public void setSliderBasedPosition()
{
if(!mediaPlayer.isSeekable()) {
return;
}
float positionValue = positionSlider.getValue() / 1000.0f;
// Avoid end of file freeze-up
if(positionValue > 0.99f) {
positionValue = 0.99f;
}
mediaPlayer.setPosition(positionValue);
}
private void updateUIState()
{
if(!mediaPlayer.isPlaying()) {
// Resume play or play a few frames then pause to show current position in video
mediaPlayer.play();
if(!mousePressedPlaying) {
try {
// Half a second probably gets an iframe
Thread.sleep(500);
}
catch(InterruptedException e) {
// Don't care if unblocked early
}
mediaPlayer.pause();
}
}
long time = mediaPlayer.getTime();
int position = (int)(mediaPlayer.getPosition() * 1000.0f);
int chapter = mediaPlayer.getChapter();
int chapterCount = mediaPlayer.getChapterCount();
updateTime(time);
updatePosition(position);
updateChapter(chapter, chapterCount);
}
public void skip(int skipTime)
{
// Only skip time if can handle time setting
if(mediaPlayer.getLength() > 0) {
mediaPlayer.skip(skipTime);
updateUIState();
}
}
public void updateTime(long millis)
{
String s = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis), TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
lblTime.setText(s);
}
public void updatePosition(int value)
{
// positionProgressBar.setValue(value);
positionSlider.setValue(value);
}
public void updateChapter(int chapter, int chapterCount) {
String s = chapterCount != -1 ? (chapter + 1) + "/" + chapterCount : "-";
chapterLabel.setText(s);
chapterLabel.invalidate();
validate();
}
public void updateVolume(int value) {
volumeSlider.setValue(value);
}
// Variables declaration - do not modify
private javax.swing.JButton btnMute;
private javax.swing.JButton btnPause;
private javax.swing.JButton btnPlay;
private javax.swing.JButton btnRewind;
private javax.swing.JButton btnRewind2;
private javax.swing.JButton btnStop;
private javax.swing.JLabel chapterLabel;
private javax.swing.JLabel jLabel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JLabel lblTime;
private javax.swing.JLabel lblTotal;
private javax.swing.JPanel panelVideo;
public javax.swing.JSlider positionSlider;
private javax.swing.JSlider volumeSlider;
// End of variables declaration
}
Поток, используемый для печати времени:
package vlcvideo;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
public class timeThread extends Thread
{
prueba pb;
EmbeddedMediaPlayer mediaPlayer;
public timeThread(prueba pb,EmbeddedMediaPlayer mediaPlayer)
{
this.pb=pb;
this.mediaPlayer=mediaPlayer;
}
public void run()
{
while(true)
{
final long time = mediaPlayer.getTime();
final int position = (int)(mediaPlayer.getPosition() * 1000.0f);
final int chapter = mediaPlayer.getChapter();
final int chapterCount = mediaPlayer.getChapterCount();
int posicionSlider=pb.positionSlider.getValue();
if(mediaPlayer.isPlaying())
{
pb.updateTime(time);
pb.updatePosition(position);
pb.updateChapter(chapter, chapterCount);
}
}
}
}
используемые библиотеки:
-jna 3.4.0.jar
-vlcj 2.1.0.jar
JDK: 1,8