java 如何在MediaPlayer播放视频时停止当前线程?

hec6srdp  于 2023-04-19  发布在  Java
关注(0)|答案(1)|浏览(188)

我在JavaFX上写程序,它必须显示窗口,播放视频,播放后隐藏窗口,并在随机时间后再次重复此操作。我需要知道如何在媒体播放器完成播放当前视频时进行随机延迟。我的想法是这些-如果通过在player.play()后添加scene.hide(),在播放完成前隐藏窗口,接下来播放器在另一个线程中工作。但是如果我在player.play()命令后通过TimeUnit.SECONDS.sleep(10)添加延迟,视频播放将在10秒后开始。请解释一下,实际发生了什么,以及如何在播放完成后添加延迟。
我的代码:

import java.io.File;
import java.lang.management.ManagementFactory;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.DoubleProperty;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.scene.input.KeyCombination;
import java.util.concurrent.TimeUnit;
public class Main extends Application implements Runnable {
     private String Dir = System.getProperty("./");
     private Stage stage;
     private boolean fl;
     public static void main(String[] args) throws Exception{
               launch(args);
     }
     
     public void run() { //if playing is complete - hide window
         
         //System.out.printf("Media player thread is %d \n",Thread.currentThread().getId());
         this.stage.hide();
     }
     private static int randomIntBetween(int first, int last) {
         int rnd_int= (int)(first + Math.round(Math.random()*Math.abs((last-first))));
         return rnd_int;
     }
     @Override
     public void start(Stage stage) throws Exception {
         this.stage=stage;
         String[]  video_paths = {"lp.mp4","sc_1.mp4"};
         stage.setFullScreen(true);
         stage.setFullScreenExitHint("");
         stage.setFullScreenExitKeyCombination(javafx.scene.input.KeyCombination.NO_MATCH);
         while (true){
         String video_path = video_paths[randomIntBetween(0,video_paths.length-1)];//Get random video (path)
         File f = new File(video_path);
         
         Media media = new Media(f.toURI().toURL().toString());
         javafx.scene.media.MediaPlayer player = new   javafx.scene.media.MediaPlayer(media);
         MediaView viewer = new MediaView(player);
        
        //change width and height to fit video
        DoubleProperty width = viewer.fitWidthProperty();
        DoubleProperty height = viewer.fitHeightProperty();
        width.bind(Bindings.selectDouble(viewer.sceneProperty(), "width"));
        height.bind(Bindings.selectDouble(viewer.sceneProperty(), "height"));
        viewer.setPreserveRatio(true);
    
        StackPane root = new StackPane();
        root.getChildren().add(viewer);
        
        //set the Scene
        Scene scenes = new Scene(root);
        stage.setScene(scenes);
        player.setOnEndOfMedia(this);
        //System.out.printf("Main thread is %d \n",Thread.currentThread().getId());
        stage.show();
        player.play();
        //this.stage.hide();
        //TimeUnit.SECONDS.sleep(randomIntBetween(3,100); 
        break;//added for single iteration
       
    
         }
 
  }
}

如果我在www.example.com()后面加上break,我的代码就可以工作player.play了。但这并不能解决我的问题。

oyt4ldly

oyt4ldly1#

不幸的是,你的方法是完全错误的。你的方法中有一些主要的错误和误解,还有一些小的改进可以在你的代码中进行。
主要问题:
1.你不需要(也不应该)创建另一个线程来暂停,使用PauseTransition
1.永远不要让JavaFX线程休眠。
1.您应该 * 永远不要 * 从JavaFX线程以外的任何线程修改Scene Graph或Stages中节点的属性。

  1. GUI是事件驱动的,因此响应并生成事件(例如PauseTransition.onFinished),而不是代码循环。
    1.永远不要在JavaFX线程上循环-GUI中不会发生任何事情。
    其他改进:
    1.应用程序应该只对应用程序生命周期负责。
    1.应用程序不应实现runnable。
    1.要获取工作目录,请使用system property "user.dir"
    1.不要写一个函数来获取范围内的随机整数,使用内置的库函数。
    1.关注naming conventionsalways
    1.对于大多数应用程序来说,设置一个不匹配的键和全屏退出的提示似乎是一个坏主意。
    1.不要定义像名称错误的Dir这样的变量,因为您从来没有使用过它。
    1.代码应为properly formatted
    1.绑定到属性,而不是你使用的奇怪的绑定选择方案,例如,你可以写viewer.fitWidthProperty().bind(scene.widthProperty())
    1.但是,不要使用绑定进行布局,使用带有最少适当布局提示的布局窗格。
    1.不要在代码中不必要地使用完全限定名,而是添加适当的import语句。
    相关:
  • JavaFX媒体播放器示例。

相关问题