I have a URL that links to a livestream - the live stream itself is in a ".ts" file.
I'm using vlcj to display the video using Java, but the network code is in pure Java. Here's what I have so far:
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.discovery.NativeDiscovery;
import uk.co.caprica.vlcj.player.media.callback.DefaultCallbackMedia;
public class Main {
public static class StreamMedia extends DefaultCallbackMedia{
private InputStream stream;
public StreamMedia(InputStream stream, String[] mediaOptions) {
//512 bytes to read per call to onRead
super(false, 512, mediaOptions);
this.stream = stream;
}
@Override
protected int onRead(byte[] arg0, int arg1) throws IOException {
int amnt = stream.read(arg0);
return amnt;
}
@Override
protected void onClose() {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected long onGetSize() {
return 0;
}
@Override
protected boolean onOpen() {
return true;
}
@Override
protected boolean onSeek(long arg0) {
return false;
}
}
public static void main(String[] args) throws Exception{
//The url I'm streaming to my machine.
//It's a ".ts" resource
URL url = new URL("STREAM URL");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setUseCaches(false);
connection.connect();
StreamMedia test = new StreamMedia(connection.getInputStream(), new String[0]);
//Just sets up my VLC JFrame. Right from the vlc tutorials
new NativeDiscovery().discover();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("A GUI");
frame.setBounds(100, 100, 600, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
EmbeddedMediaPlayerComponent mediaPlayer = new EmbeddedMediaPlayerComponent();
frame.setContentPane(mediaPlayer);
frame.setVisible(true);
//play the StreamMedia object I've created
mediaPlayer.getMediaPlayer().playMedia(test);
}
});
}
}
The main bottleneck occurs at the method onRead() in the class StreamMedia since my program has to block until more data is received. This results in a choppy playback with significant freezes.
However, when I play the stream using VLC the program, it plays nicely so I don't think it's a problem with my server.
I've tried using buffered streams, but it only allowed for fluent playback at the initial stages. I also tried having a worker thread read from the input while another actually played it, but there was no change.
Anyway I can fix this? Thanks.
This approach using Java to read your stream is really NOT recommended at all.
If you have a network stream to play, then play it using the standard network MRL using mediaPlayer.playMedia. So, if VLC can play your stream, use the same MRL when you use vlcj.
With a network stream and a .ts file, you will need to deal with sub-items in vlcj. There are numerous examples in the vlcj test sources that play network streams.
If you must persist with this approach, I'm not sure 512 bytes is a good size for a buffer so you could try increasing that. vlcj's default buffer size for this was 10k, but even so this approach is sub-optimal.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.