Qt 如何在QML的最后一帧暂停视频?
我正在尝试停止QML视频,并在播放完成后显示其最后一帧。有人知道怎么做吗?(对不起,这似乎不像听起来那么琐碎……) 目前,我的问题是视频元素在播放完成后变得不可见/隐藏。(Qt 如何在QML的最后一帧暂停视频?,qt,video,qml,qt5,Qt,Video,Qml,Qt5,我正在尝试停止QML视频,并在播放完成后显示其最后一帧。有人知道怎么做吗?(对不起,这似乎不像听起来那么琐碎……) 目前,我的问题是视频元素在播放完成后变得不可见/隐藏。(onVisibleChanged从未被调用。) 当我在代码中使用hack inonStatusChanged时,视频在结束后消失片刻,然后显示视频的结束 我所做的只是: Video { anchors.fill: parent fillMode: VideoOutput.PreserveAspectFit;
onVisibleChanged
从未被调用。)
当我在代码中使用hack inonStatusChanged
时,视频在结束后消失片刻,然后显示视频的结束
我所做的只是:
Video {
anchors.fill: parent
fillMode: VideoOutput.PreserveAspectFit;
source: "path/to/file"
autoPlay: true
onStatusChanged: {
console.warn("StatusChanged:"+status+"|"+MediaPlayer.Loaded)
if (status == MediaPlayer.EndOfMedia)
{
// seek a bit before the end of the video since the last frames
// are the same here, anyway
seek(metaData.duration-200)
play()
pause()
}
}
onVisibleChanged:
{
console.log(visible)
}
}
可能我遗漏了什么,但我在文档中找不到关于这个主题的任何内容。另外,使用单独的MediaPlayer
和VideoOutput
不会改变行为
作为记录,我正在Windows上使用最新的Qt5.2(msvc2010+OpenGL构建)。我仍在寻找更好的解决方案。我想到的是在视频结束前暂停一秒钟:
MediaPlayer {
autoLoad: true
id: video
onPositionChanged: {
if (video.position > 1000 && video.duration - video.position < 1000) {
video.pause();
}
}
}
MediaPlayer{
自动加载:正确
id:视频
已更改的位置:{
如果(video.position>1000&&video.duration-video.position<1000){
video.pause();
}
}
}
为什么是一秒钟?在我的机器上,如果您尝试在结束前500毫秒左右暂停视频,视频会自动运行到结束并从视图中消失,甚至不会注册pause()
调用。因此,1秒对我来说是一个很好的安全值
坦率地说,我更希望有一种更明确的方式告诉媒体播放器在视频结束时该做什么。我知道一个事实,Qt在Linux和Mac上使用的GStreamer会在视频即将结束时通知您,以便您可以决定下一步要做什么,例如暂停视频或无缝地循环视频。我和您一样痛苦(主要对OSX和iOS感兴趣,同样的问题也会发生)。我唯一的解决方案是将每个视频(至少是“罐装”应用程序资源,而不是网上的动态内容)与最终帧的png图像配对。视频启动时,启用其下图像的显示(尽管此时图像实际上不可见)。当视频突然结束时,图像将保持可见
这在iOS上非常有效,但在(某些?)Mac上,视频和图像之间可能会有轻微的亮度跳变(猜测:与OSX显示首选项的屏幕校准有关,不影响视频?)
MediaPlayer或VideoOutput元素类型在最后一帧冻结的选项实际上要简单得多
我考虑过但没有尝试过的另一种可能性是叠加两个视频。上面的那个是主播放器,但下面的那个只会被搜索到视频的最后一毫秒并暂停。然后当主视频结束并消失时。。。下面是视频的最后一帧。这基本上与基于图像的解决方案相同,但是下面的图像是使用视频播放器动态创建的。我发现mobile HW的视频和Qt的包装足够喜怒无常(当然,在Qt5的早期,更多的是喜怒无常),所以我根本不想尝试用它做任何太聪明的事情。几年后,我也面临着同样的问题。但是,我找到了一个解决方法(对于Qt>=5.9),允许我在结束后100毫秒内暂停视频: 问题似乎与notifyInterval属性(在Qt5.9中引入)有关。默认设置为1000ms(与其他答案中观察到的1000ms相同,我相信这不是巧合)。因此,当视频几乎完成时,将其更改为一个非常小的值,可以捕捉到非常接近结尾的位置,并在那里暂停视频:
Video {
id: videoelem
source: "file:///my/video.mp4"
notifyInterval: videoelem.duration>2000 ? 1000 : 50
onPositionChanged: {
if(position > videoelem.duration-2*notifyInterval) {
if(notifyInterval == 1000)
notifyInterval = 50
else if(notifyInterval == 50)
videoelem.pause()
}
}
onStatusChanged: {
if(status == MediaPlayer.Loaded)
videoelem.play()
}
}
希望这对别人有帮助 在MediaPlayer元素中:根据持续时间在结束前100毫秒暂停视频
MediaPlayer {
id: video1
onPlaybackStateChanged: {
if(playbackState==1){
durTrig.stop();
durTrig.interval=duration-100;
durTrig.restart();
}
}
}
Timer:{
id:durTrig
running:false
repeat: false
onTriggered:{
video1.pause();
}
}
这正是我们使用的解决方法。我不确定是否接受你的回答,因为这只是一个解决办法,而不是真正的解决办法。就我个人而言,我会把它打开,希望有一个真正的解决办法出现!我很容易找到这个页面来搜索这个问题。在某个时刻,我可能会在Qt Jira中创建一个愿望列表项,以获得更有用的行为,如果那里似乎没有任何东西。当然,可以选择一个较低的值,而不是50,以捕获更接近结尾的视频。但是,值越小,CPU负载越高。这是一个平衡这两件事的问题…你可以使用一个着色器效果源,视频作为它的源,并在它停止播放时与视频元素交换