2016-06-27 2 views
1

Я хотел бы создать приложение медиаплеера JavaFX, имеющее два этапа (первичный и вторичный), которые показывают одно и то же видео или воспроизводят один и тот же аудиофайл, но контролируются с основного этапа. Идея заключается в том, чтобы второстепенная ступень была перенесена на второй монитор или подключенный видеопроектор и всегда была в полноэкранном режиме без видимых элементов управления.javafx media player с двумя видами

Возможно ли это?

Вот код для MediaPlayer.java.

package mediaplayer; 

import java.io.File; 
import javafx.application.Application; 
import javafx.scene.Group; 
import javafx.scene.media.Media; 
import javafx.scene.media.MediaPlayer; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 

public class FulldomeMediaPlayer extends Application { 

    private File file = new File("./media/video.mp4"); 
    private final String MEDIA_URL = file.toURI().toString(); 

    @Override 
    public void start(Stage primaryStage) { 
    // Create media player. 
    Media media = new Media(MEDIA_URL); 
    MediaPlayer mediaPlayer = new MediaPlayer(media); 
    MediaControl mediaControl = new MediaControl(mediaPlayer); 

    Group root = new Group(); 

    Scene scene = new Scene(root, 512, 512); 
    scene.setRoot(mediaControl); 

    primaryStage.setScene(scene); 
    primaryStage.setTitle("Media Player"); 
    primaryStage.setFullScreen(false); 
    primaryStage.show(); 

    Stage secondStage = new Stage(); 
    secondStage.setX(1920.0); 
    secondStage.setY(0.0); 
    secondStage.setFullScreen(true); 

    //secondStage.setScene(scene); 
    secondStage.setTitle("Second Media Player"); 
    secondStage.show(); 
    } 

    public static void main(String[] args) { 
    launch(args); 
    } 
} 

Вот код MediaControl.java, который имеет элементы управления для запуска и остановки видео. Он основан на примере Oracle, но я изменил его так, чтобы видео изменялось в центральной панели пограничной панели.

package mediaplayer; 

import javafx.application.Platform; 
import javafx.beans.InvalidationListener; 
import javafx.beans.Observable; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.scene.layout.*; 
import javafx.geometry.Insets; 
import javafx.geometry.Pos; 
import javafx.scene.control.Button; 
import javafx.scene.control.Label; 
import javafx.scene.control.Slider; 
import javafx.scene.media.MediaPlayer; 
import javafx.scene.media.MediaPlayer.Status; 
import javafx.scene.media.MediaView; 
import javafx.util.Duration; 


public class MediaControl extends BorderPane { 

    private MediaPlayer mp; 
    private MediaView mediaView; 
    private final boolean repeat = false; 
    private boolean stopRequested = false; 
    private boolean atEndOfMedia = false; 
    private Duration duration; 
    private Slider timeSlider; 
    private Label playTime; 
    private Slider volumeSlider; 
    private HBox mediaBar; 

public MediaControl(final MediaPlayer mp) { 
    this.mp = mp; 
    setStyle("-fx-background-color: #bfc2c7;"); 
    mediaView = new MediaView(mp); 


    StackPane mvPane = new StackPane(); 

    mvPane.getChildren().add(mediaView); 
    mediaView.fitWidthProperty().bind(mvPane.widthProperty()); 
    mediaView.fitHeightProperty().bind(mvPane.heightProperty()); 
    mediaView.setPreserveRatio(true); 

    setCenter(mvPane); 

    mediaBar = new HBox(); 
    mediaBar.setAlignment(Pos.CENTER); 
    mediaBar.setPadding(new Insets(5, 10, 5, 10)); 
    BorderPane.setAlignment(mediaBar, Pos.CENTER); 

    final Button playButton = new Button(">"); 

    playButton.setOnAction(new EventHandler<ActionEvent>() { 
     public void handle(ActionEvent e) { 
      Status status = mp.getStatus(); 

      if (status == Status.UNKNOWN || status == Status.HALTED) { 
       // don't do anything in these states 
       return; 
      } 

      if (status == Status.PAUSED 
        || status == Status.READY 
        || status == Status.STOPPED) { 
       // rewind the movie if we're sitting at the end 
       if (atEndOfMedia) { 
        mp.seek(mp.getStartTime()); 
        atEndOfMedia = false; 
       } 
       mp.play(); 
      } else { 
       mp.pause(); 
      } 
     } 
    }); 
    mp.currentTimeProperty().addListener(new InvalidationListener() { 
     public void invalidated(Observable ov) { 
      updateValues(); 
     } 
    }); 

    mp.setOnPlaying(new Runnable() { 
     public void run() { 
      if (stopRequested) { 
       mp.pause(); 
       stopRequested = false; 
      } else { 
       playButton.setText("||"); 
      } 
     } 
    }); 

    mp.setOnPaused(new Runnable() { 
     public void run() { 
      System.out.println("onPaused"); 
      playButton.setText(">"); 
     } 
    }); 

    mp.setOnReady(new Runnable() { 
     public void run() { 
      duration = mp.getMedia().getDuration(); 
      updateValues(); 
     } 
    }); 

    mp.setCycleCount(repeat ? MediaPlayer.INDEFINITE : 1); 
    mp.setOnEndOfMedia(new Runnable() { 
     public void run() { 
      if (!repeat) { 
       playButton.setText(">"); 
       stopRequested = true; 
       atEndOfMedia = true; 
      } 
     } 
    }); 

    mediaBar.getChildren().add(playButton); 
    // Add spacer 
    Label spacer = new Label(" "); 
    mediaBar.getChildren().add(spacer); 

    // Add Time label 
    Label timeLabel = new Label("Time: "); 
    mediaBar.getChildren().add(timeLabel); 

    // Add time slider 
    timeSlider = new Slider(); 
    HBox.setHgrow(timeSlider, Priority.ALWAYS); 
    timeSlider.setMinWidth(50); 
    timeSlider.setMaxWidth(Double.MAX_VALUE); 
    timeSlider.valueProperty().addListener(new InvalidationListener() { 
     public void invalidated(Observable ov) { 
      if (timeSlider.isValueChanging()) { 
       // multiply duration by percentage calculated by slider position 
       mp.seek(duration.multiply(timeSlider.getValue()/100.0)); 
      } 
     } 
    }); 
    mediaBar.getChildren().add(timeSlider); 

    // Add Play label 
    playTime = new Label(); 
    playTime.setPrefWidth(130); 
    playTime.setMinWidth(50); 
    mediaBar.getChildren().add(playTime); 

    // Add the volume label 
    Label volumeLabel = new Label("Vol: "); 
    mediaBar.getChildren().add(volumeLabel); 

    // Add Volume slider 
    volumeSlider = new Slider(); 
    volumeSlider.setPrefWidth(70); 
    volumeSlider.setMaxWidth(Region.USE_PREF_SIZE); 
    volumeSlider.setMinWidth(30); 
    volumeSlider.valueProperty().addListener(new InvalidationListener() { 
     public void invalidated(Observable ov) { 
      if (volumeSlider.isValueChanging()) { 
       mp.setVolume(volumeSlider.getValue()/100.0); 
      } 
     } 
    }); 
    mediaBar.getChildren().add(volumeSlider); 

    setBottom(mediaBar); 
} 

protected void updateValues() { 
    if (playTime != null && timeSlider != null && volumeSlider != null) { 
     Platform.runLater(new Runnable() { 
      public void run() { 
       Duration currentTime = mp.getCurrentTime(); 
       playTime.setText(formatTime(currentTime, duration)); 
       timeSlider.setDisable(duration.isUnknown()); 
       if (!timeSlider.isDisabled() 
         && duration.greaterThan(Duration.ZERO) 
         && !timeSlider.isValueChanging()) { 
        timeSlider.setValue(currentTime.divide(duration).toMillis() 
          * 100.0); 
       } 
       if (!volumeSlider.isValueChanging()) { 
        volumeSlider.setValue((int) Math.round(mp.getVolume() 
          * 100)); 
       } 
      } 
     }); 
    } 
} 

private static String formatTime(Duration elapsed, Duration duration) { 
    int intElapsed = (int) Math.floor(elapsed.toSeconds()); 
    int elapsedHours = intElapsed/(60 * 60); 
    if (elapsedHours > 0) { 
     intElapsed -= elapsedHours * 60 * 60; 
    } 
    int elapsedMinutes = intElapsed/60; 
    int elapsedSeconds = intElapsed - elapsedHours * 60 * 60 
      - elapsedMinutes * 60; 

    if (duration.greaterThan(Duration.ZERO)) { 
     int intDuration = (int) Math.floor(duration.toSeconds()); 
     int durationHours = intDuration/(60 * 60); 
     if (durationHours > 0) { 
      intDuration -= durationHours * 60 * 60; 
     } 
     int durationMinutes = intDuration/60; 
     int durationSeconds = intDuration - durationHours * 60 * 60 
       - durationMinutes * 60; 
     if (durationHours > 0) { 
      return String.format("%d:%02d:%02d/%d:%02d:%02d", 
        elapsedHours, elapsedMinutes, elapsedSeconds, 
        durationHours, durationMinutes, durationSeconds); 
     } else { 
      return String.format("%02d:%02d/%02d:%02d", 
        elapsedMinutes, elapsedSeconds, durationMinutes, 
        durationSeconds); 
     } 
    } else { 
     if (elapsedHours > 0) { 
      return String.format("%d:%02d:%02d", elapsedHours, 
        elapsedMinutes, elapsedSeconds); 
     } else { 
      return String.format("%02d:%02d", elapsedMinutes, 
        elapsedSeconds); 
     } 
    } 
    } 
} 

Спасибо.

ответ

1

Просто создайте новый MediaView в новом эпизоде, который будет отображаться во втором окне. Ссылка на тот же MediaPlayer, который вы создали для использования в вашей первой сцене, и элементы управления, входящие в первую сцену, будут управлять одновременно MediaViews.

secondStage.setScene(new Scene(new StackPane(new MediaView(mediaPlayer)))); 
+0

Это сработало @jewelsea, но теперь видеоролик secondStage обрезается сверху и снизу. Я попытался добавить код, который я использовал для primaryStage, чтобы изменить размер видео внутри окна, но, похоже, это не имеет значения. – CelestialCoyote

+0

Правильное определение размера изображения на весь экран - это немного другой вопрос, попробуйте задать его как новый вопрос. – jewelsea

+0

В конце концов я его разобрал. Спасибо за вашу помощь. – CelestialCoyote