简体   繁体   English

从HttpUrlConnection的inputstream读取速度慢

[英]Slow read from HttpUrlConnection's inputstream

I have a URL that links to a livestream - the live stream itself is in a ".ts" file. 我有一个链接到实时流的URL-实时流本身在“ .ts”文件中。

I'm using vlcj to display the video using Java, but the network code is in pure Java. 我正在使用vlcj使用Java显示视频,但是网络代码使用的是纯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. 主要瓶颈出现在StreamMedia类中的onRead()方法上,因为我的程序必须阻塞直到收到更多数据为止。 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. 但是,当我使用VLC程序播放流时,它可以很好地播放,因此我认为服务器没有问题。

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. 完全不建议使用Java来读取流的这种方法。

If you have a network stream to play, then play it using the standard network MRL using mediaPlayer.playMedia. 如果您要播放网络流,请使用mediaPlayer.playMedia使用标准网络MRL播放它。 So, if VLC can play your stream, use the same MRL when you use vlcj. 因此,如果VLC可以播放您的流,请在使用vlcj时使用相同的MRL。

With a network stream and a .ts file, you will need to deal with sub-items in vlcj. 使用网络流和.ts文件,您将需要处理vlcj中的子项目。 There are numerous examples in the vlcj test sources that play network streams. vlcj测试源中有许多播放网络流的示例。

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. 如果必须坚持这种方法,我不确定512字节是否适合缓冲区大小,因此可以尝试增加该大小。 vlcj's default buffer size for this was 10k, but even so this approach is sub-optimal. vlcj的默认缓冲区大小是10k,但是即使这样,这种方法也不是很理想。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM