我使用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();
}
}
}
答案 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)
我认为它不是由设置快照目录时的拼写错误引起的?