2014-12-31 4 views
1

Стандартный вопрос для VLCJ - КАК получить видео с изменяемым размером для JavaFX .... Какая причина заключается в отсутствии этой функции. Я работал над этим в течение нескольких дней, любая помощь будет принята с благодарностью ....Изменение размера VLCJ PixelWriter

  @Override 
      public void display(DirectMediaPlayer mp, Memory[] memory, final BufferFormat bufferFormat) { 
       final int renderFrameNumber = frameNumber.incrementAndGet(); 
       currentByteBuffer.set(memory[0].getByteBuffer(0,memory[0].size())); 
       Platform.runLater(new Runnable() { 
        @Override 
        public void run() { 
         ByteBuffer byteBuffer = currentByteBuffer.get(); 
         int actualFrameNumber = frameNumber.get(); 
         if (renderFrameNumber == actualFrameNumber) { 
          canvas.getPixelWriter().setPixels(0, 0, 
            bufferFormat.getWidth(), 
            bufferFormat.getHeight(), 
            byteBgraInstance, byteBuffer, 
            bufferFormat.getPitches()[0]); 
         } else { 
          System.out.println("[FINE] " 
            + " - Skipped late frame " 
            + renderFrameNumber 
            + " (actual = " 
            + actualFrameNumber + ")"); 
         } 
        } 
       }); 
      } 

Довольно много я могу получить видео в оригинальном размере, но не масштаб или размер, чтобы соответствовать что-нибудь еще. Есть ли у кого-нибудь опыт работы с PixelWriter и копирование его во второй раз на масштабированное изображение или НИЧЕГО?

ответ

1

К сожалению, для JavaFX-подхода с vlcj требуется так называемый медиа-проигрыватель «прямой рендеринг» (как вы используете в своем вопросе).

Этот медиа-проигрыватель с прямым рендерингом использует обратные вызовы воспроизведения видеоизображения LibVLC, чтобы предоставить каждому кадру видео для вашего приложения в любом виде, который он считает нужным.

Способ, которым работает собственный API, заключается в том, что вы должны сначала предоставить обратные вызовы для установки желаемого формата буфера видео - это включает в себя формат изображения, но также включает в себя ширину и высоту, которые вы хотите для буфера видео.

Этот нативный обратный вызов вызывается один раз до видео начинает воспроизводиться и больше никогда (если вы не прекратите воспроизведение видео и не запустите его снова).

Очевидно, это означает, что размеры собственного видео-буфера фиксированы после начала воспроизведения и не могут динамически изменяться «на лету».

Это отвечает первой части вашего вопроса о том, почему функциональность не существует - она ​​просто не поддерживается базовой библиотекой.

Какой vlcj дает вам доступ к «необработанному» собственному видео-буферу, то вам решать, как вы его визуализируете - используете ли вы BufferedImage, OGL Texture или действительно PixelWriter. Также зависит от вас, как вы масштабируете его, если вам нужно это поддержать. Масштабирование в программном обеспечении, конечно же, позволит увеличить нагрузку на ваш процессор.

В этой второй части вашего вопроса я больше не могу советовать.

Не связанный с вашим конкретным вопросом ... но после просмотра вашего опубликованного кода я не уверен в семантике синхронизации, которую у вас есть - внутри вашего метода «run()» нет ничего, что я мог бы предотвратить, предотвращая собственное видео буфер от перезаписи. Последняя версия демонстрационного проекта vlcj-javafx, требуемая для Java8, использует новые методы блокировки/разблокировки буфера, которые должны использоваться для обеспечения правильной синхронизации.

+0

Знаете ли вы о реализации swingnode, которая позволила бы мне использовать встроенный проигрыватель в моем JavaFX? – msj121

+0

Если бы это было так, было бы легко. То, что я делаю для таких вещей, наоборот, у меня есть приложение Swing, в котором я могу использовать встроенный медиаплеер (используя java.awt.Canvas), а затем внедряю компонент JavaFX в мое приложение Swing. Конечно, это не идеально. – caprica

+0

Но JavaFX в настоящее время становится основным способом взаимодействия с графическим интерфейсом для Java, насколько я могу судить. Он пробился в ядро ​​Java, для этого создаются инструменты. Я не удивлюсь, если он скоро вернется в Swing ... Кажется, что он лучше обработан с наблюдаемыми свойствами и привязкой. Нет необходимости переписывать код. В моем случае все приложение JavaFX я просто хочу воспроизвести видео с изменяемым размером ... – msj121

0

Я искал это некоторое время и даже пытался изменить размер rgbBuffer вручную, что у меня есть в какой-то момент в моем коде. Но теперь у меня есть подход, который работает для меня.

Вместо использования Canvas я использовал ImageView, который работает лучше для изменения размера, поскольку для него предусмотрена встроенная реализация. Я видел комментарии людей, говорящих, что PixelWriter на изображениях медленный, но это было либо давно, либо их компьютер просто медленно. Кажется, у меня нет никаких проблем (пока;)); это достаточно быстро для меня.

Создайте нормальный Pane (или, желательно, подклассируйте его и добавьте остальную часть вашего кода там). Эта область может быть изменена с использованием обычного кода.

Внутри Pane добавьте ImageView и привяжите его к ширине и высоте родительской панели. Присвойте WritableImageImageView и используйте PixelWriter от WritableImage, чтобы записать пиксели в изображение.

Следующий класс демонстрирует изменяемое по размеру изображение и приобретает PixelWriter.

import javafx.scene.image.ImageView; 
import javafx.scene.image.PixelWriter; 
import javafx.scene.image.WritableImage; 
import javafx.scene.layout.Pane; 

public class ResizableVlcPlayer extends Pane { 

    private ImageView mImageView; 
    private WritableImage mWritableImage; 
    private PixelWriter mPixelWriter; 

    public ResizableVlcPlayer() { 
     mImageView = new ImageView(); 

     // this auto resizes the image when the pane resizes 
     mImageView.fitWidthProperty().bind(widthProperty()); 
     mImageView.fitHeightProperty().bind(heightProperty()); 

     getChildren().add(mImageView); 

     mWritableImage = new WritableImage(1280,720); 
     mImageView.setImage(mWritableImage); 

     mPixelWriter = mWritableImage.getPixelWriter(); 

     // Continue normal implementation by writing to the PixelWriter 
    } 
} 
Смежные вопросы