Introducing: YUNPM (Y U NO play movie!) library name suggestions are welcome…
To put it mildly, Java movie playback is a joke, and waiting for JavaFX to become the defacto standard might take yet another decade. That’s why I’ve decided to bite the bullet and make a 2nd attempt (after VLC failed) to make a minimalistic Java Video Player implementation, using an external process to decode the video and audio in a media file: this time using ffmpeg.
Approach
- Launch ffmpeg: make it generate a
mjpeg
stream piped to stdout - Launch ffmpeg: make it generate a
wav
stream piped to stdout - Use Matthias Mann’s JPEG decoder (replacing ImageIO) to decode the chunked mjpeg stream
- Use the audio (if any) to sync the video stream per frame, otherwise syncs to video framerate
The media playback code is fairly OO, which means you can easily swap out the current OpenGL and OpenAL renderers, and tie the library to AWT + JavaSound if that floats your boat.
Download files
[x] http://indiespot.net/files/projects/medialib/ (source included)
The archives contain an example video and launch scripts, so testing it is simply a matter of extract + click!
Hilarious sample code
class VideoPlaybackTest {
public static void main(String[] args) throws Exception {
File movieFile = new File(args[0]);
boolean audioEnabled = true;
VideoRenderer videoRenderer = new OpenGLVideoRenderer(movieFile.getName());
AudioRenderer audioRenderer = audioEnabled ? new OpenALAudioRenderer() : null;
if (videoRenderer instanceof OpenGLVideoRenderer) {
OpenGLVideoRenderer opengl = (OpenGLVideoRenderer) videoRenderer;
opengl.setFullscreen(false); // uses current desktop resolution
opengl.setVSync(true);
opengl.setRenderRotatingQuad(true);
}
VideoPlayback playback = new FFmpegVideoPlayback(movieFile);
playback.setCoupleFramerateToVideo(false);
playback.startVideo(videoRenderer, audioRenderer);
/**
* oldskool controls!!
*/
BufferedReader br = new BufferedReader(
new InputStreamReader(new BufferedInputStream(System.in)));
while (true) {
String line = br.readLine();
if (line.equals("mute")) {
playback.setVolume(0.0f);
} else if (line.equals("half")) {
playback.setVolume(0.5f);
} else if (line.equals("full")) {
playback.setVolume(1.0f);
} else if (line.equals("pause")) {
playback.pause();
} else if (line.equals("resume")) {
playback.resume();
} else {
System.out.println("wait what?");
}
}
}
}