我有一个链接到实时流的URL-实时流本身在“ .ts”文件中。
我正在使用vlcj使用Java显示视频,但是网络代码使用的是纯Java。这是我到目前为止的内容:
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);
}
});
}
}
主要瓶颈出现在StreamMedia类中的onRead()方法上,因为我的程序必须阻塞直到收到更多数据为止。这会导致断断续续的播放并出现明显的冻结。
但是,当我使用VLC播放该流时,该程序可以很好地播放,因此我认为服务器没有问题。
我已经尝试过使用缓冲流,但是它只允许在初始阶段进行流畅的播放。我还尝试过从输入中读取一个工作线程,而另一个则实际播放了该线程,但是没有任何变化。
无论如何我都可以解决这个问题?谢谢。
答案 0 :(得分:0)
完全不建议使用Java来读取流的这种方法。
如果要播放网络流,请使用mediaPlayer.playMedia使用标准网络MRL播放。因此,如果VLC可以播放您的流,请在使用vlcj时使用相同的MRL。
有了网络流和.ts文件,您将需要处理vlcj中的子项目。 vlcj测试源中有许多播放网络流的示例。
如果您必须坚持使用这种方法,那么我不确定512字节是否适合缓冲区大小,因此您可以尝试增加该大小。 vlcj的默认缓冲区大小为10k,但是即使这样,这种方法也不是很理想。