java - 从 HttpUrlConnection 的输入流读取速度缓慢

标签 java http networking vlc vlcj

我有一个链接到直播的 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 程序播放流时,它播放得很好,所以我不认为这是我的服务器的问题。

我尝试过使用缓冲流,但它只允许在初始阶段流畅播放。我还尝试让一个工作线程从输入中读取,而另一个工作线程实际播放它,但没有任何变化。

无论如何我可以解决这个问题吗?谢谢。

最佳答案

这种使用 Java 读取流的方法确实完全不推荐。

如果您有要播放的网络流,请使用 mediaPlayer.playMedia 使用标准网络 MRL 来播放它。因此,如果 VLC 可以播放您的流,请在使用 vlcj 时使用相同的 MRL。

有了网络流和.ts文件,您将需要处理vlcj中的子项。 vlcj测试源中有很多播放网络流的例子。

如果您必须坚持这种方法,我不确定 512 字节是否适合缓冲区大小,因此您可以尝试增加该大小。 vlcj 的默认缓冲区大小为 10k,但即使如此,这种方法也不是最优的。

关于java - 从 HttpUrlConnection 的输入流读取速度缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51856874/

相关文章:

java - 当我使用 Java youtube api 上传视频时,是否可以在视频中添加注释或 'end screen'?

java - 为 Julia 集生成自定义调色板

multithreading - 同步 HTTP 请求的最大合理超时

python - 为没有写入权限的用户在网络驱动器上安装 Python

java - Postgresql 与 Hibernate : could not determine LocalDate type in jpql query

Angular 7 上传到带有进度指示器的 blob 存储

java - 使用 Java Servlet 访问 post 变量

java.net.ConnectException : Connection refused

networking - 在 Linux 内核中创建数据包的教程

java - 使用 Java 连接 PostgreSQL 8.2