Обычная версия
Java форум JavaTalks
форум программистов

Поиск   Пользователи   Группы   Регистрация 
 Профиль   Личные сообщения 

 Вход 

Видеопроигрыватель
Список форумов
 ->  Swing, AWT & SWT


На страницу 1, 2  След. 
Начать новую тему 
Предыдущая тема :: Следующая тема  
Автор Сообщение
nightman13 : 40
Новичок

СообщениеЯнв 25, 2012 0:19 
Ответить с цитатой
Пишу плеер на java с использованием Xuggle
основные примеры здесь:
http://xuggle.googlecode.com/svn/trunk/java/xuggle-xuggler/src/com/xuggle/xuggler/demos/DecodeAndPlayAudio.java - звук

http://xuggle.googlecode.com/svn/trunk/java/xuggle-xuggler/src/com/xuggle/xuggler/demos/DecodeAndPlayVideo.java - картинка

вместо стандартной VideoImage для отображения, я использую JLabel, у которой вызываю метод setIconImage - передаю кадры

нужно сделать возможность перемотки

при открытии файла, нужно определить размер файла для дальнейшего позиционирования бегунка (JSlider) для перемотки

подскажите как определить макс значение бегунка(как можно из размера файла получить его длительность по времени)?
еще стоит задача синхронизации аудио и видео потоков
Exclamation Question
К началу Посмотреть профиль Отправить личное сообщение
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 писал(а):

как можно из размера файла получить его длительность по времени

никак Smile
К началу Посмотреть профиль Отправить личное сообщение
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.

Цитата:
в начале воспроизведения кадр неполный, можно ли как то узнать позицию в файле как бы по целым кадрам?

эта функция как-раз это и делает - перемешает указатель на ключевой кадр, другое дело, если
Цитата:
в начале воспроизведения кадр неполный
, то эта функция как-то неправильно работает. Или правильно, но для некоторых видеофайлов не совсем верно Smile

Код:
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), то думаю, проще будет пытаться синхронизировать аудио по видео. Как? Не знаю Smile
К началу Посмотреть профиль Отправить личное сообщение
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 не знаком, может быть, поддержка других флагов еще не дописана, не знаю...
Цитата:
программа вообще вылетает))

Нужен код, а лучше весь проект, тогда на выходных смогу посмотреть и может быть помочь... Smile
К началу Посмотреть профиль Отправить личное сообщение
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 
Ответить с цитатой
Ок, вечером воскресенья отпишусь насчет результатов Very Happy
К началу Посмотреть профиль Отправить личное сообщение
nickliverpool : 18
Новичок

СообщениеЯнв 29, 2012 22:53 
Ответить с цитатой
Скинь куда-нибудь папку icons. Времени свободного было не так много, с твоим кодом пока не разбирался. Только проект собрал и примеры посмотрел.

Как вариант, можно глянуть еще сюда -> http://code.google.com/p/xuggle/source/browse/trunk/java/xuggle-xuggler/src/com/xuggle/xuggler/demos/DecodeAndPlayAudioAndVideo.java?r=646, там может быть какая-то полезная информация насчет синхронизации, сам пока не читал.

Известна дата следующей попытки сдачи курсовика?

Но, пока не знаю насколько сильно буду занят, в начале недели разберу исходники и подумаю насчет синхронизации, но как скоро это будет не знаю. Так что сильно на меня не рассчитывай.
К началу Посмотреть профиль Отправить личное сообщение
nightman13 : 40
Новичок

СообщениеЯнв 30, 2012 7:18 
Ответить с цитатой
http://ifolder.ru/28384113
К началу Посмотреть профиль Отправить личное сообщение
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

И может быть будет работать Smile
К началу Посмотреть профиль Отправить личное сообщение
nightman13 : 40
Новичок

СообщениеЯнв 31, 2012 17:44 
Ответить с цитатой
для ускоренного воспроизведения я сделал так
Код:
ttsleep = picTime - mPos*coeff;

coeff - скорость, те если в два раза быстрее то coeff=2

это работает, но вот для замедленного воспроизведения не знаю как сделать
К началу Посмотреть профиль Отправить личное сообщение
nightman13 : 40
Новичок

СообщениеЯнв 31, 2012 17:50 
Ответить с цитатой
все, вроде бы разобрался)))
ваш метод работает вроде как)))
спасибо!) Very Happy
К началу Посмотреть профиль Отправить личное сообщение
 
Начать новую тему  Ответить на тему
Страница 1 из 2
На страницу 1, 2  След.
Список форумов
 -> Swing, AWT & SWT


 
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Java and all Java-related trademarks and logos are trademarks or registered trademarks of Oracle Corporation in the United States and other countries.
Это сайт не относится к фирме Oracle Corporation и не поддерживается ею.

© 2006-2010 www.javatalks.ru: форум java программистов
Используется скрипт phpBB © 2001, 2010 phpBB Group

Хостинг от bizname.ru