Adding Video to Desktop App - java

I'm working on a project for a programming class, and I want to add a video file. I've tried using JMF, except when I try to play a video (using one of the formats listed on the Java website), it gives me the error:
Unable to handle format: XVID, 320x213, FrameRate=29.9, Length=204480 0 extra bytes
Unable to handle format: mpeglayer3, 22050.0 Hz, 0-bit, Stereo, Unsigned, 8000.0 framerate,FrameSize=4608 bits
Failed to realize: com.sun.media.PlaybackEngine#39b27b
Error: Unable to realize com.sun.media.PlaybackEngine#39b27b
Could not realize media player
This is the code I use to test the player:
public MediaPanel(String path) {
try {
videoPath = new File(path).toURI().toURL();
} catch (MalformedURLException e) {
e.printStackTrace();
}
setLayout(new BorderLayout());
Manager.setHint(Manager.LIGHTWEIGHT_RENDERER, true);
try {
Player mediaPlayer = Manager.createRealizedPlayer(videoPath);
Component video = mediaPlayer.getVisualComponent();
Component controls = mediaPlayer.getControlPanelComponent();
if (video != null)
add(video, BorderLayout.CENTER);
if (controls != null)
add(controls, BorderLayout.SOUTH);
mediaPlayer.start();
} catch (NoPlayerException NoPlayerException) {
System.err.println("No media player found");
} catch (CannotRealizeException CannotRealizeException) {
System.err.println("Could not realize media player");
} catch (IOException IOException) {
System.err.println("Error reading from the source");
}
}
MediaPanel player = new MediaPanel("intro.avi");
I assume my two options are to make a video with the exact specifications listed on the Java website (because apparently just the file extension isn't enough), or use another method to display video.
How can I fix this? Do I need to make a video exactly as the specifications note (see link at bottom)?
NOTE: The class I'm in uses and older version of java that DOESN'T contain javaFX. Please don't recommend this unless there is a way I can add it without having the school reinstall a newer version of Java.

Related

Decode h264 video to java.awt.image.BufferedImage in java

I am trying to make an AirPlay server in java with this library. I am able to start the server and connect to it and I am getting video input, however the input is in h264 format and I tried decoding it with JCodec but it always says I need an sps/pps and I don't know how to create/find this with just a byte[]. This is the onVideo method which is pretty much just copy-pasted from some websites:
#Override
public void onVideo(byte[] video) {
try {
videoFileChannel.write(ByteBuffer.wrap(video));
ByteBuffer bb = ByteBuffer.wrap(video);
H264Decoder decoder = new H264Decoder();
decoder.addSps(List.of(ByteBuffer.wrap(video)));
Picture out = Picture.create(1920, 1088, ColorSpace.YUV420);
var real = decoder.decodeFrame(bb, out.getData());
// decoder.decodeFrame prints "[WARN] . (:0): Skipping frame as no SPS/PPS have been seen so far..." in console and returns null => NullPointer in next line
var img = AWTUtil.toBufferedImage(real.createCompatible());
// ...
} catch (IOException e) {
e.printStackTrace();
}
}
Edit: I've uploaded a ("working") version to github, but the decoded image is discolored and doesn't update all pixels so when something is on the screen and the frame changes, that something can still be on the image.

Java replacing JMF with an mp4 media player

this is a really newbie-ish question. So any information I have missed please tell me and I will add it.
I really have no idea about java, I received a project from my predecessor at work.
It actually has the classic media player on that doesn't support mp4, the volume of the videos is large so I wanted to change it and make it able to play .mp4
I have downloaded the openjfx but I am not really sure on how to implement that on the existing code I could really use some help/guidelines because I am kind of at a loss.
Here is an images of the player and the preview buttons. Also this is the code he's using (I think) for the media player.
private void previewClip(String path) {
try {
URL pathToUrl = new File(path).toURI().toURL(); // Manager and player recognize urls not paths or strings
Manager.setHint( Manager.LIGHTWEIGHT_RENDERER, true ); // the creation of the player manager
if(isPreviewActive) { // check if a video is already added to jPanel22
previewPanel.removeAll();
// previewPanel.remove(0); // removing previous video
}
Player previewPlayer = Manager.createRealizedPlayer(pathToUrl); // creation of the player
Component video = previewPlayer.getVisualComponent(); // adding visual (drawing) of the video
previewPanel.add(video, BorderLayout.CENTER); // adding video to jPanel22
pack(); // packing the assembly
previewPlayer.start(); // start the video
isPreviewActive = true; // change the check variable from 0 to 1
} catch (IOException | NoPlayerException | CannotRealizeException ex) {
showMessage("There is an error with preview Video.\nPlease contact support team\n" + ex.toString());
// Logger.getLogger(Chroma_boilerplate.class.getName()).log(Level.SEVERE, null, ex);
}
}

Get current governor using RandomAccessFile

I have a problem in the development of a simple application to get some information about the installed kernel. More precisely, the problem is retrieving the current governor. This information is stored in this path /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor and to read it I've written this code:
public String currentGovernor() {
try {
random = new RandomAccessFile(GOVERNOR_CUR, "r");
currentGovernor = random.readLine();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
return currentGovernor;
}
This code works for getting other information like list of all governors, cpu frequency and some other.
In my opinion the problem is that the scaling_governor file has these permissions: **rw-rw----** while the other files (like cpu frequency) have these permissions: **r--r--r--**. The currentGovernor() method works on some device like Samsung Galaxy S2 but dosent work in Galaxy Nexus (perhaps because the file has different permissions depending on the device).
Do you have any solution that I could use to make it work on all devices?

Android Mediarecorder: Getting 3GP instead of MPEG4

I want to record video only in android with MPEG4 format. I want the container and codec to be MPEG4. So here is what I have done for that.
Thread video = new Thread(new Runnable() {
public void run() {
videoRecorder = new MediaRecorder();
videoRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
videoRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
videoRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
videoRecorder.setVideoEncodingBitRate(56 * 8 * 1024);
videoRecorder.setVideoSize(176, 144);
videoRecorder.setVideoFrameRate(12);
videoRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
videoRecorder.setOutputFile("/sdcard/video.m4e");
try {
videoRecorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
videoRecorder.start();
}
});
video.start();
Now, after recording, I got the video recorded into video.m4e file. But when I check its information, I got the following:
At the same time I used the following to record audio:
Thread audio = new Thread(new Runnable() {
public void run() {
audioRecorder = new MediaRecorder();
audioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
audioRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
audioRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
audioRecorder.setOutputFile("/sdcard/audio.amr");
try {
audioRecorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
audioRecorder.start();
}
});
audio.start();
and I got the container format and codec as AMR as I intended:
So, what causes MediaRecorder to record video in 3GP format? I haven't specified 3GP anywhere in my program. I am testing this code on my Samsung Galaxy tab running Android 2.2
MPEG-4 is a method of defining compression of audio and visual (AV) digital data.A file format for storing time-based media content. It is a general format forming the basis for a number of other more specific file formats (e.g. 3GP, Motion JPEG 2000, MPEG-4 Part 14).So there is no conspiracy in the result you got, the compression method (OR "Codec") you used was MPEG4 and the video format generated by your phone is 3gp, which in actual is a part of the video formats of the suite of the MPEG4 compression scheme for the media.
This is defined by the frameworks. Specifically it has a set of parameters that are found in the MediaRecorder class that define what all is supported.
I do not understand akkilis's explanation.
In the official Android tutorial "MediaRecorder.OutputFormat",
MPEG_4 is one of options of "media file formats", parallel to THREE_GPP.
int AAC_ADTS AAC ADTS file format
int AMR_NB AMR NB file format
int AMR_WB AMR WB file format
int DEFAULT
int MPEG_4 MPEG4 media file format
int RAW_AMR This constant was deprecated in API level 16. Deprecated in favor of MediaRecorder.OutputFormat.AMR_NB
int THREE_GPP 3GPP media file format
There is another parameter to specify the encoding format:
"MediaRecorder.VideoEncoder"
int DEFAULT
int H263
int H264
int MPEG_4_SP
In OP's code, he specified both file format and encoding format.
videoRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
videoRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
So it seems akkilis's explanation does not work for this example.

How to create a media player in Java without JMF?

How to create a media player in Java without using the JMF? Some blogs say it's an old version. I also tried using JMF - this is my code.
public class MediaPlayer {
public static void main(String[] args) {
Player p;
try {
p = Manager.createPlayer(new URL("http://192.168.1.113/asmitha/1.mp4"));
p.start();
} catch (NoPlayerException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is the message I am getting:
LINEAR, Unknown Sample Rate * out * LINEAR, 8000.0 Hz, 16-bit, Stereo, LittleEndian, Signed, class [S
JMF 2.1 is the latest version, and that was released a long time ago. JMF will probably not support all codec formats. That is probably why you are not able to play the file. There are also a lot of codec licensing issues.
There is a JMF performance pack for windows & *nix which will support more codecs than the default installation. Try that. If that doesn't work take a look at ffmpeg or VLC-J.

Categories

Resources