无法在java代码中截取视频截图

时间:2014-03-23 14:26:01

标签: java media vlcj

我使用vlcj编写了一个代码,用于定期截取视频的屏幕截图。当我尝试输出视频的长度时,它会打印0.问题是什么?

import uk.co.caprica.vlcj.binding.LibVlc;
import uk.co.caprica.vlcj.player.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;

import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;

public class ScreenShotCapture {

    public static void main(String[] args){
        NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), "C:\\Program Files\\VideoLAN\\VLC");
        Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
        MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory();
        final EmbeddedMediaPlayer mediaPlayer =mediaPlayerFactory.newEmbeddedMediaPlayer();
        mediaPlayer.playMedia("E:\\videos\\Avenged Sevenfold - So Far Away [Music Video].mp4");
        mediaPlayer.setSnapshotDirectory("E:\\vidoes");
        long length = mediaPlayer.getTime();
        long interval = length / 21;
        for(long  i = 1;i <= length;i+= interval){
            mediaPlayer.setTime(i);
            mediaPlayer.saveSnapshot();
        }
    }
}

2 个答案:

答案 0 :(得分:2)

媒体长度不是立即可用的,当媒体开始播放时,当解码器计算出长度是多少时,媒体长度将可用。这本质上就是VLC的工作方式。

几乎所有东西都是异步工作的,这意味着你必须将代码建立在事件上,而不是仅仅以程序方式编写代码。

当长度发生变化时,会生成本机事件,最终导致MediaPlayerEventListener#lengthChanged事件触发。当该事件被触发时,对mediaPlayer.getLength()的调用应返回非零值。

下一个问题是您在调用saveSnapshot后立即调用setTime。同样,setTime异步工作,因此您不能假设媒体播放器已经达到该方法返回时所需的时间。您必须等待timeChanged事件并检查您的时间是否已经到达(实际已经过去)。

根据您的用例,最后一个问题可能是也可能不重要,因为对saveSnapshot的调用本身是异步的,所以基本上您已经请求了快照,但尚未生成快照。这次你需要等待snapshotTaken事件。只有在收到该事件时,才会将快照实际保存到磁盘中。

所以基本上你需要以不同的方式思考并实现基于事件的方法。

其中一个示例是在此vlcj示例中生成快照:https://github.com/caprica/vlcj/blob/vlcj-3.0.1/src/test/java/uk/co/caprica/vlcj/test/condition/ConditionTest.java

如果你不喜欢这个例子,那么你可以通过回应你自己的MediaPlayerEventListener实现中的事件来实现它。

另外:您还可以使用VLC“场景”过滤器以可靠的方式生成快照。

答案 1 :(得分:0)

我认为它不是由设置快照目录时的拼写错误引起的?