使用javafx的Media,MediaPlayer,MediaView。代码如下:
import java.io.Fileimport javafx.application.Application
import javafx.beans.binding.Bindings
import javafx.beans.property.ReadOnlyProperty
import javafx.beans.value.ObservableValue
import javafx.event.ActionEvent
import javafx.geometry.Pos
import javafx.scene.Scene
import javafx.scene.control.Button
import javafx.scene.control.Menu
import javafx.scene.control.MenuBar
import javafx.scene.control.MenuItem
import javafx.scene.control.Slider
import javafx.scene.image.Image
import javafx.scene.image.ImageView
import javafx.scene.layout.BorderPane
import javafx.scene.layout.HBox
import javafx.scene.layout.Pane
import javafx.scene.layout.VBox
import javafx.scene.media.Media
import javafx.scene.media.MediaPlayer
import javafx.scene.media.MediaPlayer.Status
import javafx.scene.media.MediaView
import javafx.stage.FileChooser
import javafx.stage.FileChooser.ExtensionFilter
import javafx.stage.Stage
import javafx.util.Duration
public class App extends Application {
private MediaView mediaView
private Slider processSlider
private static final Object AUTO = new Object(), MANUAL = new Object()
public static void main(String[] args) {
launch(args)
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("javafx视频播放器")
BorderPane root = new BorderPane()
// 菜单栏
initMenu(root)
// 视频播放控件
mediaView = initMediaView(root)
// 视频功能控件
initMediaControllView(root)
primaryStage.setScene(new Scene(root, 600, 400))
primaryStage.setOnCloseRequest(event -> System.exit(0))
primaryStage.show()
}
private MenuBar initMenu(final BorderPane parent) {
Menu menu = new Menu("菜单")
MenuItem item = new MenuItem("打开")
item.setOnAction(event -> {
FileChooser chooser = new FileChooser()
chooser.setTitle("选择视频文件")
chooser.getExtensionFilters().add(new ExtensionFilter("视频文件", "*.mp4", "*.flv"))
File file = chooser.showOpenDialog(parent.getScene().getWindow())
if (file != null) {
MediaPlayer player = mediaView.getMediaPlayer()
// 关闭当前的player
if (player != null) {
player.stop()
player.dispose()
}
processSlider.setValue(0)
// 创建一个新的player并自动播放
player = new MediaPlayer(new Media(file.toURI().toString()))
player.currentTimeProperty().addListener(this::mediaProcessChanged)
player.setAutoPlay(true)
mediaView.setMediaPlayer(player)
}
})
menu.getItems().add(item)
item = new MenuItem("退出")
item.setOnAction(event -> parent.getScene().getWindow().hide())
menu.getItems().add(item)
MenuBar menuBar = new MenuBar(menu)
parent.setTop(menuBar)
return menuBar
}
private MediaView initMediaView(final BorderPane parent) {
MediaView view = new MediaView()
Pane pane = new Pane(view)
parent.setCenter(pane)
// 视频宽高可随着窗口变化而自动缩放
view.fitWidthProperty().bind(Bindings.selectDouble(view.parentProperty(), "width"))
view.fitHeightProperty().bind(Bindings.selectDouble(view.parentProperty(), "height"))
view.setPreserveRatio(true)
return view
}
private void initMediaControllView(final BorderPane parent) {
VBox bottom = new VBox(10)
bottom.setAlignment(Pos.CENTER)
parent.setBottom(bottom)
Slider slider = new Slider(0, 100, 0)
slider.valueProperty().addListener(this::processSliderChanged)
// slider.setOnMouseClicked(this::processSliderClicked)
bottom.getChildren().add(slider)
processSlider = slider
HBox hbox = new HBox(10)
bottom.getChildren().add(hbox)
hbox.setAlignment(Pos.CENTER)
Button btn = new Button(null, new ImageView(loadImage("pause.png")))
btn.setOnAction(this::pauseOrPlay)
hbox.getChildren().add(btn)
btn = new Button(null, new ImageView(loadImage("stop.png")))
btn.setOnAction(this::stopPlay)
hbox.getChildren().add(btn)
}
private static Image loadImage(String resPath) {
return new Image(Thread.currentThread().getContextClassLoader().getResourceAsStream(resPath))
}
private void pauseOrPlay(ActionEvent event) {
MediaPlayer player = mediaView.getMediaPlayer()
if (player == null) {
return
}
Status status = player.getStatus()
if (status == Status.READY || status == Status.PAUSED) {
player.play()
((Button) event.getTarget()).setGraphic(new ImageView(loadImage("pause.png")))
} else if (status == Status.PLAYING) {
player.pause()
((Button) event.getTarget()).setGraphic(new ImageView(loadImage("play.png")))
}
}
private void stopPlay(ActionEvent event) {
MediaPlayer player = mediaView.getMediaPlayer()
if (player == null) {
return
}
player.stop()
}
// private void processSliderClicked(MouseEvent event) {
// Slider slider = (Slider) event.getSource()
// if (mediaView.getMediaPlayer() != null) {
// Duration d = mediaView.getMediaPlayer().getTotalDuration().multiply(slider.getValue() / slider.getMax())
// mediaView.getMediaPlayer().seek(d)
// }
// }
private void processSliderChanged(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
Slider slider = (Slider) ((ReadOnlyProperty<? extends Number>) observable).getBean()
if (slider.getUserData() == AUTO) { // 进度条是自动改变的,因此不用设置播放器
slider.setUserData(null)
return
}
if (mediaView.getMediaPlayer() != null) {
slider.setUserData(MANUAL)
Duration d = mediaView.getMediaPlayer().getTotalDuration().multiply(newValue.doubleValue() / slider.getMax())
mediaView.getMediaPlayer().seek(d)
}
}
private void mediaProcessChanged(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
if (processSlider.getUserData() == MANUAL) { // 手动点击进度条
processSlider.setUserData(null)
return
}
MediaPlayer player = (MediaPlayer) ((ReadOnlyProperty<? extends Duration>) observable).getBean()
processSlider.setUserData(AUTO)
processSlider.setValue(newValue.toMillis() / player.getTotalDuration().toMillis() * 100)
}
}
JavaFX脚本是一种声明式、静态类型编程语言。它具有一等函数(first-class functions)、声明式的语法、列表推导(list-comprehensions)及基于依赖关系的增量式求值(incremental dependency-based evaluation)等特征。JavaFX脚本为多种多样的 *** 作提供了声明式、无中间程序逻辑的语法,这些 *** 作包括创建2D动画、设置属性或者声明在模式和视图对象之间的绑定依赖关系。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)