|
Java форум JavaTalks форум программистов
|
|
|
|
| Предыдущая тема :: Следующая тема |
| Автор |
Сообщение |
nightman13 : 40 Новичок
|
Янв 25, 2012 0:19 |
|
|
|
|
|
|
 |
nickliverpool : 18 Новичок
|
Янв 26, 2012 0:44 |
|
|
| nightman13 писал(а): |
нужно определить размер файла
|
| nightman13 писал(а): |
получить его длительность по времени?
|
Отсюда -> http://www.javacodegeeks.com/2011/02/introduction-xuggler-video-manipulation.html, как вариант...
| Код: |
// query for the total duration
long duration = container.getDuration();
// query for the file size
long fileSize = container.getFileSize();
|
| nightman13 писал(а): |
как можно из размера файла получить его длительность по времени
|
никак  |
|
|
|
 |
nightman13 : 40 Новичок
|
Янв 26, 2012 8:17 |
|
|
те я устанавливаю значения JSlider min - 0 max - 100 и дальше определяю в процентах сколько надо перемотать, понятно)))
теперь еще вопрос: как осуществить саму перемотку, у меня такой код
есть 4 класса - Main, Frame(кнопочки и тд), Video(обновляет во Frame экран), Audio(выводит звук)
запуск программы происходит в таком порядке
в мэйне создается объект класса Frame
далее после выбора файла:
| Код: |
v = new Video2(Main.n.screen, filename, 0);
tv = new Thread(v);
tv.setName("Video");
a = new Audio(filename, 0);
ta = new Thread(a);
ta.setName("Audio");
tv.start();
ta.start(); |
в xuggle есть стандартная функция
| Код: |
| container.seekKeyFrame(videoStreamId, POSITION, IContainer.SEEK_FLAG_BYTE); |
- перемещает указатель на определенное место в файле, но так как она может переместиться не на полную картинку, в начале воспроизведения кадр неполный, можно ли как то узнать позицию в файле как бы по целым кадрам?
соответсвенно при перемещении положения слайдера я делаю так:
| Код: |
tv.suspend();
v = null;
v = new Video(Main.n.screen, filename, (FILESIZE*jSlider1.getValue())/100);
tv = new Thread(v); |
почему то это единственный вариант который срабатывает, но при этом потоков содается слишком много и прога падает - как это решить?
и такой способ не подходит для перемотки звука, вылетает ошибка, где идет проверка if (bytesDecoded < 0)
| Код: |
while(container.readNextPacket(packet) >= 0)
{
if (packet.getStreamIndex() == audioStreamId)
{
IAudioSamples samples = IAudioSamples.make(1024, audioCoder.getChannels());
int offset = 0;
while(offset < packet.getSize())
{
int bytesDecoded = audioCoder.decodeAudio(samples, packet, offset);
if (bytesDecoded < 0)
throw new RuntimeException("got error decoding audio in: " + filename);
offset += bytesDecoded;
if (samples.isComplete())
{
playJavaSound(samples);
//System.out.println("i:"+i+" A "+mLine.getMicrosecondPosition());
}
}
}
} |
и еще вопрос как осуществить синхронизацию видео и аудио, если делать sleep классу Video в размере 1000/getFrameRatе, то видео отстает от звука?[/code] |
|
|
|
 |
nickliverpool : 18 Новичок
|
Янв 26, 2012 13:12 |
|
|
| Цитата: |
| перемещает указатель на определенное место в файле |
не совсем
| Код: |
seekKeyFrame(int streamIndex, long timestamp, int flags)
Seeks to the key frame at (or the first one after) the given timestamp. |
| Цитата: |
| в начале воспроизведения кадр неполный, можно ли как то узнать позицию в файле как бы по целым кадрам? |
эта функция как-раз это и делает - перемешает указатель на ключевой кадр, другое дело, если
| Цитата: |
| в начале воспроизведения кадр неполный |
, то эта функция как-то неправильно работает. Или правильно, но для некоторых видеофайлов не совсем верно
| Код: |
tv.suspend();
v = null;
v = new Video(Main.n.screen, filename, (FILESIZE*jSlider1.getValue())/100);
tv = new Thread(v); |
Я практически не знаком с многопоточным программированием и принципом работы Garbage Collector, но код очень странный. После приостановления потока создается новый поток и теряется ссылка на старый поток, который продолжает висеть. Garbage Collector, думаю, должен такой поток остановить и удалить, но насколько быстро он поймет и очистить неизвестно. В любом случае так делать не следует. Если необходимость в потоке отпала, его надо завершать, а не приостанавливать.
| Цитата: |
| как осуществить синхронизацию видео и аудио, если делать sleep классу Video в размере 1000/getFrameRatе, то видео отстает от звука? |
Т.к. 99% видеофайлов воспроизводится с постоянной скоростью (Constant Frame Rate), то думаю, проще будет пытаться синхронизировать аудио по видео. Как? Не знаю  |
|
|
|
 |
nightman13 : 40 Новичок
|
Янв 26, 2012 17:03 |
|
|
| Цитата: |
Цитата:
перемещает указатель на определенное место в файле
не совсем
Код:
1 seekKeyFrame(int streamIndex, long timestamp, int flags)
2 Seeks to the key frame at (or the first one after) the given timestamp.
Цитата:
в начале воспроизведения кадр неполный, можно ли как то узнать позицию в файле как бы по целым кадрам?
эта функция как-раз это и делает - перемешает указатель на ключевой кадр, другое дело, если |
у этой функции есть несколько флагов:
| Код: |
static int SEEK_FLAG_ANY
Flag; Seek to any frame, even non-keyframes
static int SEEK_FLAG_BACKWARDS
Flag; Seek backwards
static int SEEK_FLAG_BYTE
Flag; Use bytes instead of time stamps for seeking
static int SEEK_FLAG_FRAME
Flag; Seek based on frame number instead of time stamps |
но срабатывает только SEEK_FLAG_BYTE
| Цитата: |
| Я практически не знаком с многопоточным программированием и принципом работы Garbage Collector, но код очень странный. После приостановления потока создается новый поток и теряется ссылка на старый поток, который продолжает висеть. Garbage Collector, думаю, должен такой поток остановить и удалить, но насколько быстро он поймет и очистить неизвестно. В любом случае так делать не следует. Если необходимость в потоке отпала, его надо завершать, а не приостанавливать. |
если написать
| Код: |
tv.stop();
v = null;
v = new Video2(Main.n.screen, filename, (FILESIZE*jSlider1.getValue())/100);
tv = new Thread(v);
tv.start(); |
то программа вообще вылетает))) |
|
|
|
 |
nickliverpool : 18 Новичок
|
Янв 26, 2012 17:57 |
|
|
С Xuggle не знаком, может быть, поддержка других флагов еще не дописана, не знаю...
| Цитата: |
| программа вообще вылетает)) |
Нужен код, а лучше весь проект, тогда на выходных смогу посмотреть и может быть помочь...  |
|
|
|
 |
nightman13 : 40 Новичок
|
Янв 26, 2012 17:59 |
|
|
Main
| Код: |
public class Main
{
protected static NewJFrame n;
public static void main(String [] args)
{
n = new NewJFrame();
new Thread(n);
n.setVisible(true);
}
} |
Video
| Код: |
public class Video2 implements Runnable{
protected long SLEEP;
static JLabel label;
static String filename;
protected IPacket packet;
protected int WIDTH, HEIGHT;
protected boolean FLAG = false;
protected long POSITION;
public Video2(JLabel jl, String f, long position)
{
label = jl;
filename = f;
POSITION = position;
}
public void play() throws Exception
{
try
{
if (!IVideoResampler.isSupported(IVideoResampler.Feature.FEATURE_COLORSPACECONVERSION))
{
throw new RuntimeException("could not find video stream in container: "+filename);
}
IContainer container = IContainer.make();
IStream stream;
IStreamCoder coder;
if (container.open(filename, IContainer.Type.READ, null) < 0)
throw new IllegalArgumentException("could not open file: " + filename);
//JOptionPane.showMessageDialog(Main.n, "Unfortunately, such happens.", "Error", JOptionPane.ERROR_MESSAGE);
int numStreams = container.getNumStreams();
int videoStreamId = -1;
IStreamCoder videoCoder = null;
for(int i = 0; i < numStreams; i++)
{
stream = container.getStream(i);
coder = stream.getStreamCoder();
if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO)
{
videoStreamId = i;
videoCoder = coder;
break;
}
}
if (videoStreamId == -1)
throw new RuntimeException("could not find video stream in container: "+filename);
if (videoCoder.open() < 0)
throw new RuntimeException("could not open video decoder for container: "+filename);
IVideoResampler resampler = null;
packet = IPacket.make();
Main.n.setSize(videoCoder.getWidth(), videoCoder.getHeight()+150);
IVideoPicture picture;
SLEEP = (long) (1000 / videoCoder.getFrameRate().getValue());
Main.n.FILESIZE = container.getFileSize();
container.seekKeyFrame(videoStreamId, POSITION, IContainer.SEEK_FLAG_BYTE);
//double K = (double)videoCoder.getWidth()/(double)videoCoder.getHeight();
//System.out.println(videoCoder.getWidth()+" "+videoCoder.getHeight()+" "+K);
long firstTimestampInStream = Global.NO_PTS;
long systemClockStartTime = 0;
while(container.readNextPacket(packet) >= 0)
{
if (packet.getStreamIndex() == videoStreamId)
{
WIDTH = Main.n.getWidth();
HEIGHT = Main.n.getHeight()-150;
videoCoder.setWidth(WIDTH);
videoCoder.setHeight(HEIGHT);
picture = IVideoPicture.make(videoCoder.getPixelType(),
videoCoder.getWidth(), videoCoder.getHeight());
int offset = 0;
while(offset < packet.getSize())
{
int bytesDecoded = videoCoder.decodeVideo(picture, packet, offset);
if (bytesDecoded < 0)
throw new RuntimeException("got error decoding video in: "+ filename);
offset += bytesDecoded;
if (picture.isComplete())
{
IVideoPicture newPic = picture;
if (videoCoder.getPixelType() != IPixelFormat.Type.BGR24)
{
resampler = IVideoResampler.make(WIDTH,
HEIGHT, IPixelFormat.Type.BGR24,
videoCoder.getWidth(), videoCoder.getHeight(), videoCoder.getPixelType());
if (resampler == null)
throw new RuntimeException("could not create color space resampler for: "+filename);
}
if (resampler != null)
{
newPic = IVideoPicture.make(resampler.getOutputPixelFormat(),
WIDTH, HEIGHT);
if (resampler.resample(newPic, picture) < 0)
throw new RuntimeException("could not resample video from: "+ filename);
}
if (newPic.getPixelType() != IPixelFormat.Type.BGR24)
throw new RuntimeException("could not decode video" +" as BGR 24 bit data in: " + filename);
BufferedImage javaImage = Utils.videoPictureToImage(newPic);
if (firstTimestampInStream == Global.NO_PTS)
{
firstTimestampInStream = picture.getTimeStamp();
systemClockStartTime = System.currentTimeMillis();
}
else
{
long systemClockCurrentTime = System.currentTimeMillis();
long millisecondsClockTimeSinceStartofVideo =
systemClockCurrentTime - systemClockStartTime;
long millisecondsStreamTimeSinceStartOfVideo =
(picture.getTimeStamp() - firstTimestampInStream)/1000;
final long millisecondsTolerance = 50;
final long millisecondsToSleep =
(millisecondsStreamTimeSinceStartOfVideo -
(millisecondsClockTimeSinceStartofVideo +
millisecondsTolerance));
if (millisecondsToSleep > 0)
{
try
{
Thread.sleep(millisecondsToSleep);
}
catch (InterruptedException e){return;}}
}
// }
//System.out.println("Before Pic "+newPic.getTimeStamp()+" MLINE "+Main.n.a.MLPOS);
// while(newPic.getTimeStamp()>Main.n.a.MLPOS)
// {
// Thread.sleep(1);
// }
//updateJavaWindow(javaImage);
//Main.n.timel.setText(newPic.getFormattedTimeStamp());
updateJavaWindow(javaImage);
Main.n.timel.setText(newPic.getFormattedTimeStamp());
}
}
}
}
if (videoCoder != null)
{
videoCoder.close();
}
if (container !=null)
{
container.close();
}
}
catch(RuntimeException e)
{
e.printStackTrace();
JOptionPane.showMessageDialog(Main.n, "Unfortunately, such happens.\n", "Error", JOptionPane.ERROR_MESSAGE);
Thread.currentThread().stop();
Main.n.tv.stop();
}
}
private void updateJavaWindow(BufferedImage javaImage) throws InterruptedException
{
Main.n.screen.setIcon(new ImageIcon(javaImage));
}
@Override
public void run() {
try {
play();
} catch (Exception ex) {
Logger.getLogger(Video2.class.getName()).log(Level.SEVERE, null, ex);
}
}
} |
Audio
| Код: |
public class Audio implements Runnable{
protected String filename;
protected SourceDataLine mLine;
protected IStreamCoder audioCoder = null;
protected long POSITION;
protected long MLPOS;
protected long delta;
int f = 0;
public Audio(String f, long p)
{
filename = f;
POSITION = p;
}
public void play()
{
//while(Main.n.v.FLAG!=true){}
IContainer container = IContainer.make();
if (container.open(filename, IContainer.Type.READ, null) < 0)
throw new IllegalArgumentException("could not open file: " + filename);
int numStreams = container.getNumStreams();
IStream stream = null;
int audioStreamId = -1;
for(int i = 0; i < numStreams; i++)
{
stream = container.getStream(i);
IStreamCoder coder = stream.getStreamCoder();
if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO)
{
audioStreamId = i;
audioCoder = coder;
break;
}
}
if (audioStreamId == -1)
throw new RuntimeException("could not find audio stream in container: "+filename);
if (audioCoder.open() < 0)
throw new RuntimeException("could not open audio decoder for container: "+filename);
//System.out.println(stream.getTimeBase().getDouble());
openJavaSound(audioCoder, (float)1.0);
IPacket packet = IPacket.make();
//System.out.println(audioCoder.getSampleRate());
container.seekKeyFrame(audioStreamId, POSITION, IContainer.SEEK_FLAG_BYTE);
while(container.readNextPacket(packet) >= 0)
{
if (packet.getStreamIndex() == audioStreamId)
{
IAudioSamples samples = IAudioSamples.make(1024, audioCoder.getChannels());
int offset = 0;
while(offset < packet.getSize())
{
int bytesDecoded = audioCoder.decodeAudio(samples, packet, offset);
if (bytesDecoded < 0)
throw new RuntimeException("got error decoding audio in: " + filename);
offset += bytesDecoded;
if (samples.isComplete())
{
playJavaSound(samples);
}
}
}
}
closeJavaSound();
if (audioCoder != null)
{
audioCoder.close();
audioCoder = null;
}
if (container !=null)
{
container.close();
container = null;
}
}
protected void openJavaSound(IStreamCoder aAudioCoder, float speed)
{
AudioFormat audioFormat = new AudioFormat(aAudioCoder.getSampleRate()*speed,
(int)IAudioSamples.findSampleBitDepth(aAudioCoder.getSampleFormat()),
aAudioCoder.getChannels(),
true,
false);
//System.out.println(mLine.getMicrosecondPosition());
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
try
{
mLine = (SourceDataLine) AudioSystem.getLine(info);
mLine.open(audioFormat);
mLine.start();
}
catch (LineUnavailableException e)
{
throw new RuntimeException("could not open audio line");
}
}
private void playJavaSound(IAudioSamples aSamples)
{
byte[] rawBytes = aSamples.getData().getByteArray(0, aSamples.getSize());
mLine.write(rawBytes, 0, aSamples.getSize());
MLPOS = mLine.getMicrosecondPosition();
//System.out.println("MLine "+mLine.getMicrosecondPosition());
}
protected void closeJavaSound()
{
if (mLine != null)
{
mLine.drain();
mLine.close();
mLine=null;
}
}
@Override
public void run() {
play();
}
} |
Frame
| Код: |
public class NewJFrame extends javax.swing.JFrame implements Runnable {
public static int SCREEN_CLICKED = 0;
protected Thread tv = null;
protected Thread ta = null;
protected Video2 v = null;
protected Audio a = null;
protected String filename;
protected static int threadID=1;
protected static int click = 1;
protected long FILESIZE;
public NewJFrame() {
initComponents();
setCenterPosition();
setMinimumSize(new Dimension(500, 152));
setSize(500, 500);
}
protected final void setCenterPosition() {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = this.getPreferredSize();
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
this.setLocation(screenSize.width / 6 , screenSize.height / 6);
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
screen = new javax.swing.JLabel();
jPanel1 = new javax.swing.JPanel();
play = new javax.swing.JButton();
pause = new javax.swing.JButton();
slow = new javax.swing.JButton();
fast = new javax.swing.JButton();
time = new javax.swing.JProgressBar();
jSlider1 = new javax.swing.JSlider();
timel = new javax.swing.JLabel();
jMenuBar1 = new javax.swing.JMenuBar();
jMenu1 = new javax.swing.JMenu();
jMenuItem1 = new javax.swing.JMenuItem();
jMenuItem2 = new javax.swing.JMenuItem();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
screen.setBackground(new java.awt.Color(0, 0, 0));
screen.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
screenMouseClicked(evt);
}
});
getContentPane().add(screen, java.awt.BorderLayout.NORTH);
play.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/Play1Normal.png"))); // NOI18N
play.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
playActionPerformed(evt);
}
});
pause.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/PauseNormal.png"))); // NOI18N
pause.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
pauseActionPerformed(evt);
}
});
slow.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/StepBackNormalOrange.png"))); // NOI18N
slow.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
slowActionPerformed(evt);
}
});
fast.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/StepForwardNormalBlue.png"))); // NOI18N
fast.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
fastActionPerformed(evt);
}
});
time.setMinimum(0);
time.setMinimum(100000000);
time.setValue(10000000);
jSlider1.setMinimum(0);
jSlider1.setMaximum(100);
jSlider1.setValue(0);
jSlider1.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
jSlider1StateChanged(evt);
}
});
timel.setText("00:00:00");
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(time, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(play)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(pause)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(slow)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(fast)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(timel, javax.swing.GroupLayout.PREFERRED_SIZE, 123, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 249, Short.MAX_VALUE))
.addComponent(jSlider1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(time, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(play)
.addComponent(pause)
.addComponent(slow)
.addComponent(fast)
.addComponent(timel))
.addContainerGap())
);
getContentPane().add(jPanel1, java.awt.BorderLayout.SOUTH);
jMenu1.setText("Файл");
jMenuItem1.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
jMenuItem1.setText("Открыть файл");
jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jMenuItem1ActionPerformed(evt);
}
});
jMenu1.add(jMenuItem1);
jMenuItem2.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F4, java.awt.event.InputEvent.ALT_MASK));
jMenuItem2.setText("Выход");
jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jMenuItem2ActionPerformed(evt);
}
});
jMenu1.add(jMenuItem2);
jMenuBar1.add(jMenu1);
setJMenuBar(jMenuBar1);
pack();
}// </editor-fold>
private void pauseActionPerformed(java.awt.event.ActionEvent evt) {
if(tv!=null)
{
tv.suspend();
ta.suspend();
}
}
private void screenMouseClicked(java.awt.event.MouseEvent evt) {
if(tv!=null)
{
if(SCREEN_CLICKED == 0)
{
tv.suspend();
ta.suspend();
SCREEN_CLICKED=1;
}
else
{
tv.resume();
ta.resume();
SCREEN_CLICKED=0;
}
}
}
private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {
Toolkit.getDefaultToolkit().setDynamicLayout(true);
JFileChooser jfc = new JFileChooser("C:\\");
int ret = jfc.showOpenDialog(this);
if (ret == JFileChooser.APPROVE_OPTION)
{
if(tv != null)
{
System.out.println("No null");
tv.stop();
ta.stop();
}
filename = jfc.getSelectedFile().getAbsolutePath();
v = new Video2(Main.n.screen, filename, 0);
tv = new Thread(v);
tv.setName("Video");
a = new Audio(filename, 0);
ta = new Thread(a);
ta.setName("Audio");
ta.start();
tv.start();
setTitle(jfc.getSelectedFile().getName()+" MyPlayer");
}
else
jfc.disable();
}
private void slowActionPerformed(java.awt.event.ActionEvent evt) {
if(v.SLEEP-v.SLEEP/2<160)
{
v.SLEEP = v.SLEEP*2;
}
}
private void fastActionPerformed(java.awt.event.ActionEvent evt) {
if(v.SLEEP+v.SLEEP*2>10)
{
a.closeJavaSound();
//v.SLEEP = v.SLEEP/2;
}
}
private void playActionPerformed(java.awt.event.ActionEvent evt) {
if(tv!=null)
{
tv.resume();
ta.resume();
}
}
private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {
if(tv!=null)
{
tv.stop();
ta.stop();
dispose();
}
else dispose();
}
private void jSlider1StateChanged(javax.swing.event.ChangeEvent evt) {
if(tv!=null)
{
ta.suspend();
//tv.stop();
tv=null;
v = null;
v = new Video2(Main.n.screen, filename, (FILESIZE*jSlider1.getValue())/100);
tv = new Thread(v);
tv.start();
//a = null;
//a = new Audio(filename, (FILESIZE*jSlider1.getValue())/100);
//ta = new Thread(a);
tv.start();
//ta.start();
}
}
// Variables declaration - do not modify
private javax.swing.JButton fast;
private javax.swing.JMenu jMenu1;
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JMenuItem jMenuItem1;
private javax.swing.JMenuItem jMenuItem2;
private javax.swing.JPanel jPanel1;
protected javax.swing.JSlider jSlider1;
private javax.swing.JButton pause;
private javax.swing.JButton play;
protected javax.swing.JLabel screen;
private javax.swing.JButton slow;
protected javax.swing.JProgressBar time;
protected javax.swing.JLabel timel;
// End of variables declaration
@Override
public void run() {
new NewJFrame().setVisible(true);
}
} |
|
|
|
|
 |
nickliverpool : 18 Новичок
|
Янв 26, 2012 18:38 |
|
|
Ок, вечером воскресенья отпишусь насчет результатов  |
|
|
|
 |
nickliverpool : 18 Новичок
|
Янв 29, 2012 22:53 |
|
|
|
|
|
|
 |
nightman13 : 40 Новичок
|
Янв 30, 2012 7:18 |
|
|
|
|
|
|
 |
nightman13 : 40 Новичок
|
Янв 30, 2012 10:08 |
|
|
главная проблема, которую надо решить - это перемотка, с синхронизацией вроде бы разобрался
проблема поменьше - ускоренное/замедленное воспроизведение
класс видео с синх по аудио:
| Код: |
package javaapplication3;
import com.xuggle.xuggler.*;
import java.awt.image.BufferedImage;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
public class Video2 implements Runnable {
private JLabel screen;
private JProgressBar pb;
private JLabel time;
private String filename;
protected long fs;
protected long positionV = -1;
protected IContainer container;
protected int videoStreamId = -1;
private int WIDTH, HEIGHT;
protected long picTime;
public Video2(String f, JLabel scr, JProgressBar p, JLabel tl) {
filename = f;
screen = scr;
pb = p;
time = tl;
}
public void play() throws Exception {
try {
IVideoPicture picture;
if (!IVideoResampler.isSupported(IVideoResampler.Feature.FEATURE_COLORSPACECONVERSION)) {
throw new RuntimeException("could not find video stream in container: " + filename);
}
container = IContainer.make();
IStream stream;
IStreamCoder coder;
if (container.open(filename, IContainer.Type.READ, null) < 0) {
throw new IllegalArgumentException("could not open file: " + filename);
}
fs = container.getFileSize();
int numStreams = container.getNumStreams();
IStreamCoder videoCoder = null;
for (int i = 0; i < numStreams; i++) {
stream = container.getStream(i);
coder = stream.getStreamCoder();
if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
videoStreamId = i;
videoCoder = coder;
break;
}
}
if (videoStreamId == -1) {
throw new RuntimeException("could not find video stream in container: " + filename);
}
if (videoCoder.open() < 0) {
throw new RuntimeException("could not open video decoder for container: " + filename);
}
IVideoResampler resampler = null;
IPacket packet = IPacket.make();
Main.n.setSize(videoCoder.getWidth(), videoCoder.getHeight() + 150);
long alldecode = 0;
long fsize = container.getFileSize();
while (container.readNextPacket(packet) >= 0) {
if (packet.getPosition() >= positionV) {
if (packet.getStreamIndex() == videoStreamId)
{
WIDTH = Main.n.getWidth();
HEIGHT = Main.n.getHeight() - 150;
videoCoder.setWidth(WIDTH);
videoCoder.setHeight(HEIGHT);
picture = IVideoPicture.make(videoCoder.getPixelType(),
videoCoder.getWidth(), videoCoder.getHeight());
int offset = 0;
int bytesDecoded = 0;
while (offset < packet.getSize()) {
bytesDecoded = videoCoder.decodeVideo(picture, packet, offset);
if (bytesDecoded < 0) {
break;
}
offset += bytesDecoded;
alldecode += bytesDecoded;
if (picture.isComplete()) {
IVideoPicture newPic = picture;
if (videoCoder.getPixelType() != IPixelFormat.Type.BGR24) {
resampler = IVideoResampler.make(WIDTH,
HEIGHT, IPixelFormat.Type.BGR24,
videoCoder.getWidth(), videoCoder.getHeight(), videoCoder.getPixelType());
if (resampler == null) {
throw new RuntimeException("could not create color space resampler for: " + filename);
}
}
if (resampler != null) {
newPic = IVideoPicture.make(resampler.getOutputPixelFormat(),
WIDTH, HEIGHT);
if (resampler.resample(newPic, picture) < 0) {
throw new RuntimeException("could not resample video from: " + filename);
}
}
if (newPic.getPixelType() != IPixelFormat.Type.BGR24) {
throw new RuntimeException("could not decode video" + " as BGR 24 bit data in: " + filename);
}
BufferedImage javaImage = Utils.videoPictureToImage(newPic);
picTime = newPic.getTimeStamp() / 1000;
long mPos = Main.n.a.mLine.getMicrosecondPosition() / 1000;
if (picTime > mPos && mPos > 0) {
long ttsleep = picTime - mPos;
if (ttsleep > 0) {
Thread.sleep(ttsleep);
}
}
updateJavaWindow(javaImage);
time.setText(newPic.getFormattedTimeStamp().substring(0, 8));
pb.setValue((int) ((alldecode * 100) / fsize));
}
}
if (bytesDecoded < 0) {
break;
}
}
}
}
if (videoCoder != null) {
videoCoder.close();
}
if (container != null) {
container.close();
}
} catch (RuntimeException e) {
e.printStackTrace();
//JOptionPane.showMessageDialog(Main.n, "Unfortunately, such happens.\n", "Error", JOptionPane.ERROR_MESSAGE);
Thread.currentThread().stop();
Main.n.tv.stop();
}
}
private void updateJavaWindow(BufferedImage javaImage) throws InterruptedException {
screen.setIcon(new ImageIcon(javaImage));
}
@Override
public void run() {
try {
play();
} catch (Exception ex) {
Logger.getLogger(Video2.class.getName()).log(Level.SEVERE, null, ex);
}
}
} |
|
|
|
|
 |
nightman13 : 40 Новичок
|
Янв 30, 2012 17:59 |
|
|
вот окончательная задача:
сделать так, чтобы при нажатии кнопок ускоренное\замедленное воспроизведение, файл начинал воспроизводиться сначала, но с соответствующей скоростью
помогите пожалуйста) |
|
|
|
 |
nickliverpool : 18 Новичок
|
Янв 31, 2012 17:39 |
|
|
Для видео:
Каждый кадр отображается на экране в течение некоторого времени в зависимости от частоты кадров в исходнике (для constant framerate). Так для PAL при частоте 25 кадров/сек. каждый кадр отображается в течение 1/25 = 0.040 сек = 40 мс.
Тебе в твоем коде надо всего лишь увеличивать или уменьшать это значение. Т.е, предполагаю сделать что-то следующее:
- завести переменную currentSpeed = 1
- изменить кусок кода
| Код: |
picTime = newPic.getTimeStamp() / 1000;
|
на примерно следующий
| Код: |
picTime = newPic.getTimeStamp() / 1000 / currentSpeed;
|
по нажатию клавиши увеличивать или уменьшать currentSpeed на, например, 0.1
И может быть будет работать  |
|
|
|
 |
nightman13 : 40 Новичок
|
Янв 31, 2012 17:44 |
|
|
для ускоренного воспроизведения я сделал так
| Код: |
| ttsleep = picTime - mPos*coeff; |
coeff - скорость, те если в два раза быстрее то coeff=2
это работает, но вот для замедленного воспроизведения не знаю как сделать |
|
|
|
 |
nightman13 : 40 Новичок
|
Янв 31, 2012 17:50 |
|
|
все, вроде бы разобрался)))
ваш метод работает вроде как)))
спасибо!)  |
|
|
|
 |
|
|
Страница 1 из 2 На страницу 1, 2 След. |
Список форумов
-> Swing, AWT & SWT |
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
|
|