使用VLCJ下载RTSP时会跳过帧

时间:2019-05-20 10:22:11

标签: java vlc rtsp libvlc vlcj

我正在尝试从RTSP流中下载视频。我大部分时间都能完美下载视频。 但是在某些情况下,在特定时间范围内,某些帧会被跳过。例如:一个6秒的视频,我只有大约4秒。跳过帧时,出现以下错误:

MultiFramedRTPSource::doGetNextFrame1(): The total received frame size exceeds the client's buffer size (250000).  17058 bytes of trailing data will be dropped!

有解决方案吗?

完整的VLC输出:

00000000212b5bc0] x264 encoder: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2

[00000000212b5bc0] x264 encoder: profile High, level 5.0

[0000000021303460] avcodec generic: Using D3D11VA (Intel(R) HD Graphics 630, vendor 8086(Intel), device 5912, revision 4) for hardware decoding
[00000000212b5bc0] x264 encoder: using SAR=1/1

[00000000212b5bc0] x264 encoder: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2

[00000000212b5bc0] x264 encoder: profile High, level 5.0

MultiFramedRTPSource::doGetNextFrame1(): The total received frame size exceeds the client's buffer size (250000).  17058 bytes of trailing data will be dropped!
[00000000212b5bc0] x264 encoder: frame I:1     Avg QP:17.27  size:265736

[00000000212b5bc0] x264 encoder: frame P:30    Avg QP:18.12  size: 29747

[00000000212b5bc0] x264 encoder: frame B:89    Avg QP:22.63  size:  3406

[00000000212b5bc0] x264 encoder: consecutive B-frames:  0.8%  0.0%  2.5% 96.7%

[00000000212b5bc0] x264 encoder: mb I  I16..4: 40.8% 14.5% 44.7%

[00000000212b5bc0] x264 encoder: mb P  I16..4:  1.1%  0.5%  0.4%  P16..4: 36.4%  3.7%  3.7%  0.0%  0.0%    skip:54.3%

[00000000212b5bc0] x264 encoder: mb B  I16..4:  0.0%  0.0%  0.0%  B16..8: 12.9%  0.0%  0.0%  direct: 8.0%  skip:79.1%  L0:38.9% L1:59.0% BI: 2.0%

[00000000212b5bc0] x264 encoder: 8x8 transform intra:18.3% inter:40.4%

[00000000212b5bc0] x264 encoder: coded y,uvDC,uvAC intra: 65.4% 50.5% 10.4% inter: 2.9% 12.8% 0.1%

[00000000212b5bc0] x264 encoder: i16 v,h,dc,p: 34% 23% 28% 15%

[00000000212b5bc0] x264 encoder: i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 25% 20% 41%  2%  2%  3%  3%  2%  4%

[00000000212b5bc0] x264 encoder: i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 31% 29% 18%  3%  3%  4%  4%  3%  5%

[00000000212b5bc0] x264 encoder: i8c dc,h,v,p: 52% 25% 20%  2%

[00000000212b5bc0] x264 encoder: Weighted P-Frames: Y:0.0% UV:0.0%

[00000000212b5bc0] x264 encoder: ref P L0: 65.3%  3.1% 21.4% 10.2%

[00000000212b5bc0] x264 encoder: ref B L0: 87.7% 11.2%  1.0%

[00000000212b5bc0] x264 encoder: ref B L1: 92.7%  7.3%

[00000000212b5bc0] x264 encoder: kb/s:2922.60

从RTSP下载视频的代码:

String mrl = "rtsp://<URL>";
String videoName = "E:\\cam11558337161068.mp4";
String options = ":sout=#transcode{vcodec=mp4v,venc=x264{cfr=16},scale=1,acodec=mp4a,ab=160,channels=2,samplerate=44100}:file{dst=" + videoName + "}";

final CountDownLatch sync = new CountDownLatch(1);
MediaPlayerFactory factory = new MediaPlayerFactory();
final MediaPlayer mediaPlayer = factory.mediaPlayers().newMediaPlayer();

mediaPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
    @Override
    public void error(MediaPlayer mediaPlayer) {
        sync.countDown();
    }

    @Override
    public void finished(MediaPlayer mediaPlayer) {
        mediaPlayer.release();
        factory.release();
        try {
            Thread.sleep(1000);
        }
        catch(InterruptedException e) {
        }                
    }

    @Override
    public void buffering(MediaPlayer mediaPlayer, float newCache) {
        System.out.println("Buffering ...");
    }

    @Override
    public void playing(MediaPlayer mediaPlayer) {
        System.out.println("Playing ...");
    }

});

mediaPlayer.media().prepare(mrl, options);
mediaPlayer.controls().start();

try {
    sync.await();
}
catch (InterruptedException e) {
    e.printStackTrace();
}

System.out.println("Done");

1 个答案:

答案 0 :(得分:1)

假设原因与收到的丢弃消息有关:The total received frame size exceeds the client's buffer size (250000),则可能需要更改RTSP帧缓冲区的大小。这是通过传递以下选项来完成的:

"--rtsp-frame-buffer-size=500000"

当然,您可以将大小设置为您认为合适的任何大小。我没有使用libVLC和Java绑定的经验,但是我相信您可以在实例化MediaPlayerFactory时传递构造函数选项。这来自一些绑定代码:

public  MediaPlayerFactory(String... libvlcArgs) {
    this(LibVlcFactory.factory().atLeast("2.1.0").create(), libvlcArgs);
}

...所以我相信这是您以这种方式传递参数的地方:

String[] args = {
  "--rtsp-frame-buffer-size", 
  "500000",
};

mediaPlayerFactory = new MediaPlayerFactory(args);

您还可以传递许多其他选项。