Not playing video in mediaPlayer javafx - java

I have problem with showing video in JavaFx Media:
public void showVideo(File videoFile) {
scrollPane.setHvalue(scrollPane.getHmin());
scrollPane.setVvalue(scrollPane.getVmin());
Media media = new Media("http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv");
final MediaPlayer mediaPlayer = new MediaPlayer(media);
final MediaView mediaContent = new MediaView(mediaPlayer);
HBox menuBox = new HBox();
menuBox.setAlignment(Pos.CENTER);
menuBox.getChildren().addAll(playButton, stopButton);
VBox videoBox = new VBox();
videoBox.setAlignment(Pos.CENTER);
videoBox.getChildren().addAll(mediaContent, menuBox);
playButtonListener(mediaPlayer);
stopButtonListener(mediaPlayer);
mediaPlayer.setOnEndOfMedia(new Runnable() {
#Override public void run() {
playButton.setGraphic(WindowUtil.createIcon(IconsConstants.ICON_PLAYER_REPEAT));
mediaPlayer.stop();
playButtonListener(mediaPlayer);
}
});
scrollPane.setContent(videoBox);
}
I know that the code isn't wrong because in my coworker system it shows.
I try to show flv file.
I saw question:
JavaFX video not playing
I have windows 10 N with K-Lite standart codec and jdk-8u65-windows-x64 Java and I installed feature pack for windows 10 like in link above.
And I don't know what can be the problem.

Ok, problem solved. I update feature pack and now it's working. Probably previous version of feature pack for windows 10 N doesn't have codecs which I need.

Related

Watch Twitch Live Stream in JavaFX

I want to do a simple JavaFX application to watch Twitch Live Streams.
So far, I come up with 3 possible solutions:
1) JavaFX WebView. With it I was successful to watch Twitch clip video, but Live Steaming seems not supported.
Code:
public class App extends Application {
public static void main(String[] args) {
launch();
}
#Override
public void start(Stage stage) {
WebView webview = new WebView();
webview.getEngine().load(
"https://www.twitch.tv/stariy_bog/clip/RelievedPopularYakinikuDancingBanana"
);
WebView webView = new WebView();
webview.setPrefSize(640, 390);
stage.setScene(new Scene(webview));
stage.show();
}
}
2) JavaFX scene.media package. I’ve found this package in JavaFX documentation: it states that HLS Live Streaming is supported, but I’ve found no success in loading any Twitch channel.
Code:
public class MediaTest extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
String uri = "https://www.twitch.tv/qsnake";
try {
primaryStage.setTitle("Embedded Media Player");
Group root = new Group();
Scene scene = new Scene(root, 540, 210);
Media media = new Media(uri);
MediaPlayer mediaPlayer = new MediaPlayer(media);
mediaPlayer.setAutoPlay(true);
// create mediaView and add media player to the viewer
MediaView mediaView = new MediaView(mediaPlayer);
((Group) scene.getRoot()).getChildren().add(mediaView);
primaryStage.setScene(scene);
primaryStage.sizeToScene();
primaryStage.show();
mediaPlayer.setOnPlaying(() -> {
System.out.println(mediaPlayer.getMedia().getDuration().toString());
});
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
3) Twitch Developers API. Did not found any information about live steams using Java here so far.
Also, yes, I’ve searched web about this problem. For example I’ve found a topic, but it OPs problem was not resolved.

play video when mouse is idle. and stop video when mouse is clicked/move JAVAFX

I am trying to implement a feature where the program plays a video in fullscreen when there is no mouseclick or mousemove, say for x seconds. and stops the video and go back to previous scene when mouse is clicked or moved
currently i have this one working.. BUT the video plays after 5 seconds even though i click and move the mouse.. and I can't seem to find a solution on how to close the video and proceed to the previous scene/fxml when mouse is clicked move..
current code as of writing:
for playing video when mouse is idle:
PauseTransition delay = new PauseTransition(Duration.seconds(5));
delay.setOnFinished( event -> {
try {
Main.showVideo();
} catch (IOException ex) {
Logger.getLogger(UserMainPage2Controller.class.getName()).log(Level.SEVERE, null, ex);
}
} );
delay.play();
for showing video (located inside my main class):
public static void showVideo() throws IOException
{
File f = new File("C:\\vid\\saitama.mp4");
Media media = new Media(f.toURI().toString());
MediaView mv = new MediaView();
MediaPlayer mp = new MediaPlayer(media);
mv.setMediaPlayer(mp);
FXMLLoader loader=new FXMLLoader();
loader.setLocation(Main.class.getResource("page/videoPlayer.fxml"));
mainLayout = loader.load();
StackPane root=new StackPane();
root.getChildren().add(mv);
stage.setScene(new Scene(root,1000,1000));
stage.setTitle("Video");
stage.setFullScreen(true);
stage.show();
mp.play();
}
and im not really sure what to put inside my VideoPlayercontroller class either:
right now it is empty.
public class VideoPlayerController implements Initializable {
#Override
public void initialize(URL url, ResourceBundle rb) {
}
}
So what im trying to do is only play the video when mouse is idle (not clicked or moved for x seconds).. and closes the video when the mouse is moved or click..
like for example..
if mouseclicked then Main.showPreviousScene();
May be an issue that your delay is happening every time 5 seconds after first movement but not being updated before its elapsed. Try using timers instead so that you set the timer to 5 seconds on mouse moved event on timer elapsed event set the video to play.

HTTP Live streaming not working in JavaFX application

I am trying to create a media-player which plays local media files/media over HTTP live streaming using JavaFX version 2.0.
I am able to play local media files successfully in my media player. But when I try to play media files over HTTP live streaming, then its not working. I am getting white-blank screen as shown below when I try to play media files using HTTP live streaming.
click here to see the screenshot
And following is my code to play media over HTTP live streaming:
public class RemoteMultipleFileStreaming extends Application {
private static final String MEDIA_URL = "http://youtu.be/uvcUO8DPWfs?list=PLRQuJcU2aZG-aMedJxa7p7ylYmOn5iMlS&t=2";
#Override
public void start(Stage primaryStage) {
GridPane root = new GridPane();
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setMaximized(true);
primaryStage.show();
Media media = new Media(MEDIA_URL);
MediaPlayer mediaPlayer = new MediaPlayer(media);
mediaPlayer.setAutoPlay(true);
MediaView mediaView = new MediaView(mediaPlayer);
mediaView.setFitHeight(500);
mediaView.setFitWidth(500);
root.add(mediaView);
mediaPlayer.play();
}
public static void main(String[] args) {
launch(args);
}
}
Please let me know what needs to be done in order to play media files over HTTP live streaming in media player using JavaFX.
i think you may need to ebmedd the video html source like this example and run it as html on WebView object
WebView webView= new WebView();
webView.getEngine().loadContent("<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/EtwcTIqEOKo\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>" +
"", "text/html");

How to read a video frame by frame?

i would like to read a Mp4 file in java8-64bit frame by frame and write each frame as a jpg to my harddisk. my first attempt was to use JavaFX 2.2 media player to play the file
on a View component. i thought maybe there would be an option to register an observer to get an event each time a new frame was loaded and ready to be painted on the component surface but seems there is no such method.
it would be enough to grab just those frames/pixels that got painted on the component.
Can this be done by using the media player? the reason why i use the media player is bcs it was the simplest solution i got workin. i tryed vlcj, just 32bit, and gstreamer but without luck :(
what i got so far:
public class VideoGrabber extends extends JFrame {
// code for scene setup omitted
final MediaView view = createMediaView(...)
// some other stuff happens here
// now start the video
view.getMediaPlayer().seek(Duration.ZERO);
view.getMediaPlayer().play();
view.getMediaPlayer().setOnEndOfMedia(new Runnable()
{ // save image when done
BufferedImage img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_BGR
view.paint(img.getGraphics());
ImageIO.write(img, "JPEG", new File("pic-"+System.currentTimeMillis()+".jpg"));
});
// somewhere else to create
private MediaView createMediaView(String url)
{
final Media clip = new Media(url);
final MediaPlayer player = new MediaPlayer(clip);
final MediaView view = new MediaView(player);
view.setFitWidth(VID_WIDTH);
view.setFitHeight(VID_HEIGHT);
return view;
}
is there somehow a way to do the following:
player.setOnNextFrameReady(final Event evt) { writeImage(evt.getFrame()) };
Thanks!
You can use the snapshot() of MediaView.
First connect a mediaPlayer to a MediaView component, then use mediaPlayer.seek() to seek the video position. And then you can use the following code to extract the image frame:
int width = mediaPlayer.getMedia().getWidth();
int height = mediaPlayer.getMedia().getHeight();
WritableImage wim = new WritableImage(width, height);
MediaView mv = new MediaView();
mv.setFitWidth(width);
mv.setFitHeight(height);
mv.setMediaPlayer(mediaPlayer);
mv.snapshot(null, wim);
try {
ImageIO.write(SwingFXUtils.fromFXImage(wim, null), "png", new File("/test.png"));
} catch (Exception s) {
System.out.println(s);
}
Marvin Framework provides methods to process media files frame by frame. Below it is shown a simple video processing example that highlights the path of a snooker ball.
At the left the video is played frame by frame with an interval of 30ms between frames. At the right the video is played frame by frame, but keeping all positions of the white ball through a simple image processing approach.
The source code can be checked here and the video here.
Below the essential source code to request media file frames using Marvin:
public class MediaFileExample implements Runnable{
private MarvinVideoInterface videoAdapter;
private MarvinImage videoFrame;
public MediaFileExample(){
try{
// Create the VideoAdapter used to load the video file
videoAdapter = new MarvinJavaCVAdapter();
videoAdapter.loadResource("./res/snooker.wmv");
// Start the thread for requesting the video frames
new Thread(this).start();
}
catch(MarvinVideoInterfaceException e){e.printStackTrace();}
}
#Override
public void run() {
try{
while(true){
// Request a video frame
videoFrame = videoAdapter.getFrame();
}
}catch(MarvinVideoInterfaceException e){e.printStackTrace();}
}
public static void main(String[] args) {
MediaFileExample m = new MediaFileExample();
}
}
Frameworks like ffmpeg come with command line tools to split a video into individual frames (i.e. images in a folder).
See this question: ffmpeg split avi into frames with known frame rate
The answers contains links to Java frameworks which wrap ffmpeg.

Playing audio using JavaFX MediaPlayer in a normal Java application?

I need to be able to play Audio files (MP3 / Wav) in a normal Java project. I'd prefer using the new JavaFX MediaPlayer rather than JMF. I wrote some code to test this:
public void play()
{
URL thing = getClass().getResource("mysound.wav");
Media audioFile = new Media( thing.toString() );
try
{
MediaPlayer player = new MediaPlayer(audioFile);
player.play();
}
catch (Exception e)
{
System.out.println( e.getMessage() );
System.exit(0);
}
}
When I run this, I get the exception: Toolkit not initialized
I get that this has something to do with the JavaFX thread. My question is, how can I solve this? Do I need to create a JavaFX Panel just to play some audio files in the background of my normal app, or is there any other way?
Edit: Stacktrace:
java.lang.IllegalStateException: Toolkit not initialized
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:121)
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:116)
at javafx.application.Platform.runLater(Platform.java:52)
at javafx.scene.media.MediaPlayer.init(MediaPlayer.java:445)
at javafx.scene.media.MediaPlayer.<init>(MediaPlayer.java:360)
at javaapplication6.JavaApplication6.play(JavaApplication6.java:23)
at javaapplication6.JavaApplication6.main(JavaApplication6.java:14)
For a solution with integrates a JavaFX MediaPlayer in Swing
Use a JFXPanel and be careful to only use JavaFX objects on the JavaFX thread and after the JavaFX system has been properly initialized.
JavaFX is normal Java which makes the question a bit confusing, but I guess you mean Swing.
Here's a sample audio player which is launched from Swing. The sample assumes that there are a bunch of mp3 files in the default public sample music folder for Windows 7 (C:\Users\Public\Music\Sample Music) and plays each file in turn.
JavaFXMediaPlayerLaunchedFromSwing.java
This code is responsible for creating a Swing application which, in turn, initializes the JavaFX toolkit and creates a JavaFX scene on the JavaFX application thread.
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javax.swing.*;
/**
* Example of playing all mp3 audio files in a given directory
* using a JavaFX MediaView launched from Swing
*/
public class JavaFXMediaPlayerLaunchedFromSwing {
private static void initAndShowGUI() {
// This method is invoked on Swing thread
JFrame frame = new JFrame("FX");
final JFXPanel fxPanel = new JFXPanel();
frame.add(fxPanel);
frame.setBounds(200, 100, 800, 250);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
Platform.runLater(() -> initFX(fxPanel));
}
private static void initFX(JFXPanel fxPanel) {
// This method is invoked on JavaFX thread
Scene scene = new MediaSceneGenerator().createScene();
fxPanel.setScene(scene);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(
JavaFXMediaPlayerLaunchedFromSwing::initAndShowGUI
);
}
}
MediaSceneGenerator.java
Creates a JavaFX media player which sequentially plays all of the .mp3 media files in a given folder. It provides some controls for the media (play, pause, skip track, current track play progress indicator).
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.layout.VBox;
import javafx.scene.media.*;
import javafx.util.Duration;
import java.io.File;
import java.util.*;
public class MediaSceneGenerator {
private static final String MUSIC_FOLDER = "C:\\Users\\Public\\Music\\Sample Music";
private static final String MUSIC_FILE_EXTENSION = ".mp3";
private final Label currentlyPlaying = new Label();
private final ProgressBar progress = new ProgressBar();
private ChangeListener<Duration> progressChangeListener;
public Scene createScene() {
final StackPane layout = new StackPane();
// determine the source directory for the playlist
final File dir = new File(MUSIC_FOLDER);
if (!dir.exists() || !dir.isDirectory()) {
System.out.println("Cannot find media source directory: " + dir);
Platform.exit();
return null;
}
// create some media players.
final List<MediaPlayer> players = new ArrayList<>();
for (String file : Objects.requireNonNull(dir.list((dir1, name) -> name.endsWith(MUSIC_FILE_EXTENSION))))
players.add(
createPlayer(
normalizeFileURL(dir, file)
)
);
if (players.isEmpty()) {
System.out.println("No audio found in " + dir);
Platform.exit();
return null;
}
// create a view to show the mediaplayers.
final MediaView mediaView = new MediaView(players.get(0));
final Button skip = new Button("Skip");
final Button play = new Button("Pause");
// play each audio file in turn.
for (int i = 0; i < players.size(); i++) {
MediaPlayer player = players.get(i);
MediaPlayer nextPlayer = players.get((i + 1) % players.size());
player.setOnEndOfMedia(() -> {
final MediaPlayer curPlayer = mediaView.getMediaPlayer();
nextPlayer.seek(Duration.ZERO);
if (nextPlayer != curPlayer) {
curPlayer.currentTimeProperty().removeListener(progressChangeListener);
}
mediaView.setMediaPlayer(nextPlayer);
nextPlayer.play();
});
}
// allow the user to skip a track.
skip.setOnAction(actionEvent -> {
final MediaPlayer curPlayer = mediaView.getMediaPlayer();
MediaPlayer nextPlayer = players.get((players.indexOf(curPlayer) + 1) % players.size());
nextPlayer.seek(Duration.ZERO);
mediaView.setMediaPlayer(nextPlayer);
if (nextPlayer != curPlayer) {
curPlayer.currentTimeProperty().removeListener(progressChangeListener);
}
nextPlayer.play();
});
// allow the user to play or pause a track.
play.setOnAction(actionEvent -> {
if ("Pause".equals(play.getText())) {
mediaView.getMediaPlayer().pause();
play.setText("Play");
} else {
mediaView.getMediaPlayer().play();
play.setText("Pause");
}
});
// display the name of the currently playing track.
mediaView.mediaPlayerProperty().addListener(
(observableValue, oldPlayer, newPlayer) -> setCurrentlyPlaying(newPlayer)
);
// start playing the first track.
mediaView.setMediaPlayer(players.get(0));
mediaView.getMediaPlayer().play();
setCurrentlyPlaying(mediaView.getMediaPlayer());
// silly invisible button used as a template to get the actual preferred size of the Pause button.
Button invisiblePause = new Button("Pause");
invisiblePause.setVisible(false);
play.prefHeightProperty().bind(invisiblePause.heightProperty());
play.prefWidthProperty().bind(invisiblePause.widthProperty());
// layout the scene.
HBox controls = new HBox(10, skip, play, progress);
controls.setAlignment(Pos.CENTER);
VBox mediaPanel = new VBox(10, currentlyPlaying, mediaView, controls);
layout.setStyle("-fx-background-color: cornsilk; -fx-font-size: 20; -fx-padding: 20; -fx-alignment: center;");
layout.getChildren().addAll(
invisiblePause,
mediaPanel
);
progress.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(progress, Priority.ALWAYS);
return new Scene(layout);
}
/**
* sets the currently playing label to the label of the new media player and updates the progress monitor.
*/
private void setCurrentlyPlaying(final MediaPlayer newPlayer) {
progress.setProgress(0);
progressChangeListener = (observableValue, oldValue, newValue) ->
progress.setProgress(
1.0 * newPlayer.getCurrentTime().toMillis() / newPlayer.getTotalDuration().toMillis()
);
newPlayer.currentTimeProperty().addListener(progressChangeListener);
String source = getUserFriendlyMediaName(newPlayer);
currentlyPlaying.setText("Now Playing: " + source);
}
/**
* #return a MediaPlayer for the given source which will report any errors it encounters
*/
private MediaPlayer createPlayer(String aMediaSrc) {
System.out.println("Creating player for: " + aMediaSrc);
final MediaPlayer player = new MediaPlayer(new Media(aMediaSrc));
player.setOnError(() -> System.out.println("Media error occurred: " + player.getError()));
return player;
}
private String normalizeFileURL(File dir, String file) {
return "file:///" + (dir + "\\" + file).replace("\\", "/").replaceAll(" ", "%20");
}
private String getUserFriendlyMediaName(MediaPlayer newPlayer) {
String source = newPlayer.getMedia().getSource();
source = source.substring(0, source.length() - MUSIC_FILE_EXTENSION.length());
source = source.substring(source.lastIndexOf("/") + 1).replaceAll("%20", " ");
return source;
}
}
If you just want a native JavaFX application with a MediaPlayer and no Swing
The solution above which uses Swing answers the question asked. However, I have noted that sometimes people have picked up this answer and used it to create Java based media players even when they don't have an existing Swing application that they are embedding their application into.
If you don't have an existing Swing application, then eliminate the Swing code completely from your application and write a native JavaFX application instead. To do this, use the JavaFXMediaPlayer class below instead of the class JavaFXMediaPlayerLaunchedFromSwing from the sample above.
JavaFXMediaPlayer
import javafx.application.Application;
import javafx.stage.Stage;
public class JavaFXMediaPlayer extends Application {
#Override
public void start(Stage stage) throws Exception {
stage.setScene(new MediaSceneGenerator().createScene());
stage.show();
}
}
Answers to follow-up questions
Will my .JAR file built via swing automatically have JavaFX added to it once I add it to the libraries in netbeans?
Note: info in this follow-up answer on packaging is likely dated now and other preferred packaging options exist at this time (e.g https://github.com/openjfx/javafx-maven-plugin).
Technically, Swing doesn't build Jar files but the jar of javafx packaging commands do.
If your app contains JavaFX, then, it's best to use the JavaFX packaging tools. Without them, you may have some deployment issues issues as the Java runtime jar (jfxrt.jar) is not automatically on the java boot classpath for jdk7u7. Users can manually add it to their runtime classpath, but it could be a bit of a pain. In future jdk versions (perhaps jdk7u10 or jdk8), jfxrt.jar will be on the classpath. Even then, use of the JavaFX packaging tools would still be recommended as it will be the best way to ensure that your deployment package will work in the most compatible way.
The SwingInterop NetBeans project is a sample NetBeans project which utilizes JavaFX deployment tools for a Swing project embedding JavaFX components. Source for SwingInterop is part of the JDK 7 and JavaFX Demos and Samples download.

Categories