I know this is a repeat question.
check original one here or here.
So my code is just the copy paste :
import javafx.scene.media.*;
class Gui {
public static void main(String[] args) {
try{
Media hit = new Media("skin.mp3");
MediaPlayer mediaPlayer = new MediaPlayer(hit);
mediaPlayer.play();
}catch(Exception e){
e.printStackTrace();
}
}
}
The exception which i'm getting is :
java.lang.IllegalArgumentException: uri.getScheme() == null!
at com.sun.media.jfxmedia.locator.Locator.<init>(Locator.java:217)
at javafx.scene.media.Media.<init>(Media.java:364)
at Gui.main(gui.java:6)
I'm compiling & running it correctly i.e. by including the jfxrt.jar file in classpath
Note: I'm just using notepad instead of any IDE.
So can anyone tell me the reason of IllegalArgumentException
Thankx
UPDATE : By using file://e:/skin.mp3 it worked fine but left me with another exception :
MediaException: MEDIA_INACCESSIBLE : e
at javafx.scene.media.Media.<init>(Unknown Source)
at Gui.main(gui.java:6)
So if you can put some light on this exception.
By the way i've checked the song, its not corrupt because it is playing nicely in vlc.
From the JavaFX API docs
The supplied URI must conform to RFC-2396 as required by java.net.URI.
Only HTTP, FILE, and JAR URIs are supported.
So, I suspect from reading the docs, you need to supply a URI path.
Something like file://path/to/file/skin.mp3 will probably work.
There are a few problems with the code in this question.
The class needs to be public.
JavaFX 2 applications need to extend the Application class.
JavaFX 2 applications should define a start method.
The locator for the media being created should be a full URI as noted by MadProgrammer.
Even though the question has a javafx-2 tag, I wonder if it is written for JavaFX 1.x JavaFX Script (which is now an unsupported programming language and incompatible with JavaFX 2). If so, I'd recommend coding in Java and using JavaFX 2.x for this rather than JavaFX Script.
On Windows a file representation of an absolute locator of a URI has three slashes after the file protocol. For example, the following is valid:
file:///C:/Users/Public/Music/skin.mp3
For some reason, a single slash will also work (I guess internally Java will interpolate the extra // for the protocol specifier on files or perhaps there is something I don't understand in the URL specification which means that you don't need a // after the protocol).
file:/C:/Users/Public/Music/skin.mp3
One way to check the file uri for something is valid to ask if the file uri exists
System.out.println("File " + filename + " exists? " + new File(filename).exists());
After you know your file uri is valid, you can convert it to a string using.
file.toURI().toURL().toExternalForm()
Here is a short sample program for playing some audio in JavaFX using a MediaPlayer with a little bit of error handling, so that it is easier to understand if something goes wrong.
import java.io.File;
import java.net.MalformedURLException;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.media.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/** plays an audio in JavaFX 2.x */
public class SimpleAudioPlayer extends Application {
public static void main(String[] args) { launch(args); }
#Override public void start(Stage stage) throws MalformedURLException {
final Label status = new Label("Init");
MediaPlayer mediaPlayer = createMediaPlayer(
"C:/Users/Public/Music/Sample Music/Future Islands - Before the Bridge.mp3",
status
);
StackPane layout = new StackPane();
layout.getChildren().addAll(status);
stage.setScene(new Scene(layout, 600, 100, Color.CORNSILK));
stage.show();
if (mediaPlayer != null) {
mediaPlayer.play();
}
}
/**
* creates a media player using a file from the given filename path
* and tracks the status of playing the file via the status label
*/
private MediaPlayer createMediaPlayer(final String filename, final Label status) throws MalformedURLException {
File file = new File(filename);
if (!file.exists()) {
status.setText("File does not exist: " + filename);
}
final String mediaLocation = file.toURI().toURL().toExternalForm();
Media media = new Media(mediaLocation);
MediaPlayer mediaPlayer = new MediaPlayer(media);
mediaPlayer.setOnError(new Runnable() {
#Override public void run() {
status.setText("Error");
}
});
mediaPlayer.setOnPlaying(new Runnable() {
#Override public void run() {
status.setText("Playing: " + mediaLocation);
}
});
mediaPlayer.setOnEndOfMedia(new Runnable() {
#Override public void run() {
status.setText("Done");
}
});
return mediaPlayer;
}
}
Here is a link to an additional example of a JavaFX 2.x media player which plays all of the mp3 files in a given directory sequentially.
Related
I am trying to load an image from a URL and this was very easy and works great. However, if the image doesnt exist I want it to default to a local image. The problem I am having is that it doesnt throw any exceptions. Instead it will just not display anything. I'm assuming I have to validate the URL some how, but I want to also be sure that its an image and not a webpage/script...etc
Here is my basic test code. This works:
public class DownloadImage extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
VBox root = new VBox();
String imageSource = "https://www.wbkidsgo.com/Portals/1/Content/Hero/HeroBugsCarrot/Source/Default/WB_LT_HeroImage_Bugs_v1.png";
ImageView imageView = new ImageView(new Image(imageSource));
root.getChildren().add(imageView);
primaryStage.setScene(new Scene(root, 1000, 1000));
primaryStage.show();
}
}
But if I load a bad URL i.e. (two s's in Portals):
String imageSource = "https://www.wbkidsgo.com/Portalss/1/Content/Hero/HeroBugsCarrot/Source/Default/WB_LT_HeroImage_Bugs_v1.png";
It will just be blank. I thought about creating an HTTP client and sending a request prior to creating the image, but generating the HTTP client takes a few seconds and I will be loading upwards of 300 or so images. I guess I can have one http client, and make one request for each image and check the response datatype to see if its an image, but is there a better way?
You can use the errorProperty and exceptionProperty to check the error status of the image:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.image.Image;
import javafx.stage.Stage;
public class ImageTest extends Application {
public static void main(String[] args) {
launch(args) ;
}
#Override
public void start(Stage primaryStage) {
String[] urls = new String[]{
"https://www.wbkidsgo.com/Portals/1/Content/Hero/HeroBugsCarrot/Source/Default/WB_LT_HeroImage_Bugs_v1.png",
"https://www.wbkidsgo.com/Portalss/1/Content/Hero/HeroBugsCarrot/Source/Default/WB_LT_HeroImage_Bugs_v1.png"
} ;
for (String url : urls) {
Image image = new Image(url);
if (image.isError()) {
System.out.println("Error loading image from "+url);
// if you need more details
// image.getException().printStackTrace();
} else {
System.out.println("Successfully loaded image from " + url);
}
}
Platform.exit();
}
}
Which gives the following output:
Successfully loaded image from https://www.wbkidsgo.com/Portals/1/Content/Hero/HeroBugsCarrot/Source/Default/WB_LT_HeroImage_Bugs_v1.png
Error loading image from https://www.wbkidsgo.com/Portalss/1/Content/Hero/HeroBugsCarrot/Source/Default/WB_LT_HeroImage_Bugs_v1.png
You can use the ImageView.setImage() method to change the image. I recommend initializing the ImageView using your default image in the form of a BufferedImage, then setting it later with your actual image. You can load this from your filesystem or classpath using ImageIO.
As for the actual image, I would also use ImageIO to load the url as a BufferedImage. This throws an IOException, so if it errors or does not link to a supported image type, nothing will happen.
If you know much about threads and concurrency, I would load the image on another thread so it doesn't freeze your main thread.
First of all I'm sorry if this question has been asked before or if there is documentation about the topic but i didn't found anything.
I want to make a windows app that open windows file explorer and you can browse for and then select a mp3 file, so you can play it (and replay it) in this program. I know how to open file explorer, this is my code :
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
public class Main
{
public static void main(String[] args) throws IOException {
Desktop desktop = Desktop.getDesktop();
File dirToOpen = null;
try {
dirToOpen = new File("c:\\");
desktop.open(dirToOpen);
} catch (IllegalArgumentException iae) {
System.out.println("File Not Found");
}
}
}
But i don't know how to select an mp3 file and then get the path of the file, so i can play it later.
I don't think you are approaching this right. You should use something like a FileDialog to choose a file:
FileDialog fd = new FileDialog(new JFrame());
fd.setVisible(true);
File[] f = fd.getFiles();
if(f.length > 0){
System.out.println(fd.getFiles()[0].getAbsolutePath());
}
Since you are only getting 1 MP3 file, you only need the first index of the File array returned from the getFiles() method. Since it is a modal dialog, the rest of your application will wait until after you choose a file. If you want to get multiple files at once, just loop through this aforementioned Files array.
See the documentation here: https://docs.oracle.com/javase/7/docs/api/java/awt/FileDialog.html
I'm using OpenCV for a object detection project. I'm trying to read frames from a stored video file using VideoCapture, but in OpenCV Java there is no current implementation. I followed instructions in this post: open video file with opencv java, to edit the source files of OpenCV Java to allow this functionality. The problem is I don't know how to recompile the files? - since I just added the downloaded opencv jar file into my eclipse project originally.
You should probably try JavaCV, an OpenCV wrapper for Java.
This post shows what you need to download/install to get things working on your system, but I'm sure you can find more updated posts around the Web.
One of the demos I present during my OpenCV mini-courses contains a source code that uses JavaCV to load a video file and display it on a window:
import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import static com.googlecode.javacv.cpp.opencv_highgui.*;
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.FrameGrabber;
public class OpenCV_tut4
{
public static void main(String[] args)
{
FrameGrabber grabber = new OpenCVFrameGrabber("demo.avi");
if (grabber == null)
{
System.out.println("!!! Failed OpenCVFrameGrabber");
return;
}
cvNamedWindow("video_demo");
try
{
grabber.start(); // initialize video capture
IplImage frame = null;
while (true)
{
frame = grabber.grab(); // capture a single frame
if (frame == null)
{
System.out.println("!!! Failed grab");
break;
}
cvShowImage("video_demo", frame);
int key = cvWaitKey(33);
if (key == 27) // ESC was pressed, abort!
break;
}
}
catch (Exception e)
{
System.out.println("!!! An exception occurred");
}
}
}
I want to get a frame sample (jpeg) from a video file (mov) with java. Is there an easy way to do this. When I search in google all I can find is to make mov from multiple jpgs. I dont know maybe I cannot find the right keywords.
I know that the original question is solved, nevertheless, I am posting this answer in case anyone else got stuck like I did.
Since yesterday, I have tried everything, and I mean everything to do this. All available Java libraries are either out of date, not maintained anymore or lack any kind of usable documentation (seriously??!?!)
I tried JFM (old and useless), JCodec (no documentation whatsoever), JJMpeg (looks promising but is very difficult and cumbersome to use due to lack of Java-class documentation), OpenCV auto-Java builds and a few bunch of other libraries that I cannot remember.
Finally, I decided to take a look at JavaCV's (Github link) classes and voila! It contains FFMPEG bindings with detailed documentations.
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.0</version>
</dependency>
Turns out there is a very easy way to extract video frames from a video file to a BufferedImage and by extension a JPEG file. The class FFmpegFrameGrabber could be easily used for grabbing individual frames and converting them to BufferedImage. A code sample is as follows:
FFmpegFrameGrabber g = new FFmpegFrameGrabber("textures/video/anim.mp4");
g.start();
Java2DFrameConverter converter = new Java2DFrameConverter();
for (int i = 0 ; i < 50 ; i++) {
Frame frame = g.grabImage(); // It is important to use grabImage() to get a frame that can be turned into a BufferedImage
BufferedImage bi = converter.convert(frame);
ImageIO.write(bi, "png", new File("frame-dump/video-frame-" + System.currentTimeMillis() + ".png"));
}
g.stop();
Basically, this code dumps the first 50 frames of the video and saves them as a PNG file. The good thing is that the internal seek function, works on actual frames not keyframes (a problem that I had with JCodec)
You can refer to the JavaCV's homepage to find out more about other classes that can be used for capturing frames from WebCams etc. Hope this answer helps :-)
Xuggler does the job. They even give a sample code which does exactly what I need. Link is below
http://xuggle.googlecode.com/svn/trunk/java/xuggle-xuggler/src/com/xuggle/mediatool/demos/DecodeAndCaptureFrames.java
And I've modified the code in this link such that it saves only the first frame of the video.
import javax.imageio.ImageIO;
import java.io.File;
import java.awt.image.BufferedImage;
import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.MediaListenerAdapter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.xuggler.Global;
/**
* * #author aclarke
* #author trebor
*/
public class DecodeAndCaptureFrames extends MediaListenerAdapter
{
private int mVideoStreamIndex = -1;
private boolean gotFirst = false;
private String saveFile;
private Exception e;
/** Construct a DecodeAndCaptureFrames which reads and captures
* frames from a video file.
*
* #param filename the name of the media file to read
*/
public DecodeAndCaptureFrames(String videoFile, String saveFile)throws Exception
{
// create a media reader for processing video
this.saveFile = saveFile;
this.e = null;
IMediaReader reader = ToolFactory.makeReader(videoFile);
// stipulate that we want BufferedImages created in BGR 24bit color space
reader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);
// note that DecodeAndCaptureFrames is derived from
// MediaReader.ListenerAdapter and thus may be added as a listener
// to the MediaReader. DecodeAndCaptureFrames implements
// onVideoPicture().
reader.addListener(this);
// read out the contents of the media file, note that nothing else
// happens here. action happens in the onVideoPicture() method
// which is called when complete video pictures are extracted from
// the media source
while (reader.readPacket() == null && !gotFirst);
if (e != null)
throw e;
}
/**
* Called after a video frame has been decoded from a media stream.
* Optionally a BufferedImage version of the frame may be passed
* if the calling {#link IMediaReader} instance was configured to
* create BufferedImages.
*
* This method blocks, so return quickly.
*/
public void onVideoPicture(IVideoPictureEvent event)
{
try
{
// if the stream index does not match the selected stream index,
// then have a closer look
if (event.getStreamIndex() != mVideoStreamIndex)
{
// if the selected video stream id is not yet set, go ahead an
// select this lucky video stream
if (-1 == mVideoStreamIndex)
mVideoStreamIndex = event.getStreamIndex();
// otherwise return, no need to show frames from this video stream
else
return;
}
ImageIO.write(event.getImage(), "jpg", new File(saveFile));
gotFirst = true;
}
catch (Exception e)
{
this.e = e;
}
}
}
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.bytedeco.javacpp.opencv_core.IplImage;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FrameGrabber.Exception;
public class Read{
public static void main(String []args) throws IOException, Exception
{
FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber("C:/Users/Digilog/Downloads/Test.mp4");
frameGrabber.start();
IplImage i;
try {
i = frameGrabber.grab();
BufferedImage bi = i.getBufferedImage();
ImageIO.write(bi,"png", new File("D:/Img.png"));
frameGrabber.stop();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Here's how with BoofCV:
String fileName = UtilIO.pathExample("tracking/chipmunk.mjpeg");
MediaManager media = DefaultMediaManager.INSTANCE;
ConfigBackgroundBasic configBasic = new ConfigBackgroundBasic(30, 0.005f);
ImageType imageType = ImageType.single(GrayF32.class);
BackgroundModelMoving background = FactoryBackgroundModel.movingBasic(configBasic, new PointTransformHomography_F32(), imageType);
SimpleImageSequence video = media.openVideo(fileName, background.getImageType());
ImageBase nextFrame;
while(video.hasNext()) {
nextFrame = video.next();
// Now do something with it...
}
maybe this will help you:
Buffer buf = frameGrabber.grabFrame();
// Convert frame to an buffered image so it can be processed and saved
Image img = (new BufferToImage((VideoFormat) buf.getFormat()).createImage(buf));
buffImg = new BufferedImage(img.getWidth(this), img.getHeight(this), BufferedImage.TYPE_INT_RGB);
//TODO saving the buffImg
for more informations:
How to take single snapshots from a webcam?
Below it is shown the essential code to request frames from media files.
For the complete source code and video demo:
"Media File Processing" example using Marvin Framework..
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();
}
}
is it possible to download file from database through browser (ex: mozilla,chrome) in java desktop application (non web app) ? can you explain me with an example code ?
thanks in advance,
Use Desktop#browse() wherein you just specify the URI of that file (exactly the one as you would enter in the address bar of a normal webbrowser).
Desktop.getDesktop().browse(new URI("http://example.com/download/file.ext"));
The other side has just to set Content-Disposition: attachment on this response to force a Save As dialogue (and of course fill the response body with the necessary data from the DB).
Anything that is available through a browser should be available to a Java desktop app. At least unless the server (e.g. Google) goes to measures to block 'programmatic access'.
can you explain me with an example code?
Sure, adapted from the Java Sound info. page.
import java.net.URL;
import javax.swing.*;
import javax.sound.sampled.*;
public class LoopSound {
public static void main(String[] args) throws Exception {
// imagine a DB is preparing/serving this - same difference.
URL url = new URL(
"http://pscode.org/media/leftright.wav");
Clip clip = AudioSystem.getClip();
AudioInputStream ais = AudioSystem.
getAudioInputStream( url );
clip.open(ais);
clip.loop(-1);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JOptionPane.showMessageDialog(null, "Close to exit!");
}
});
}
}