如何在QML中的最后一帧暂停视频



我正在尝试停止QML视频,并在播放结束后显示其最后一帧。有人知道怎么做吗?(对不起,这似乎并不像听起来那么微不足道…)

目前,我的问题是视频元素在播放完成后会变得不可见/隐藏。(从未调用onVisibleChanged。)

当我在代码中使用onStatusChanged中的破解时,视频在结束后会消失一段时间,然后显示视频的结束。

我所做的只是:

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)
}
}

我可能遗漏了什么,但在文档中找不到任何关于这个主题的内容。此外,使用单独的MediaPlayerVideoOutput不会改变行为。

为了记录在案,我在Windows上使用最新的Qt 5.2(msvc2010+OpenGL构建)。

我仍在寻找更好的解决方案。我想到的是在视频结束前暂停一秒钟:

MediaPlayer {
autoLoad: true
id: video
onPositionChanged: {
if (video.position > 1000 && video.duration - video.position < 1000) {
video.pause();
}
}
}

为什么只有一秒钟?在我的机器上,如果你试图在结束前暂停约500毫秒,视频会成功运行到结束,甚至在没有注册pause()调用的情况下从视图中消失。因此,1秒对我来说是一个很好的安全值

坦率地说,我更希望有一种更明确的方式来告诉MediaPlayer在视频结束时该做什么。我知道一个事实,Qt在Linux和Mac上使用的GStreamer会在视频快结束时通知你,这样你就可以决定下一步该做什么,例如暂停视频或无缝循环。

我分享你的痛苦(主要对OSX和iOS感兴趣,在那里也会出现同样的问题)。我唯一的解决方案是将每个视频(至少是"罐装"的应用程序资源,而不是网络上的动态内容)与最终帧的png图像配对。当视频开始时,启用其下图像的显示(尽管此时它实际上不可见)。当视频突然结束时,图像仍然可见。

这在iOS上非常有效,但在(一些?)Mac上,视频和图像之间可能会有轻微的亮度跳跃(猜测:与OSX显示偏好的屏幕校准有关,不会影响视频?)

MediaPlayer或VideoOutput元素类型在最后一帧冻结的选项确实要简单得多。

我考虑过但没有尝试过的另一种可能性是叠加两个视频。上面的那个是主要播放器,但下面的那个只会被搜索到视频的最后一毫秒并暂停。然后当主视频结束并消失时。。。下面是视频的最后一帧。这基本上与基于图像的解决方案相同,但下面的图像是使用视频播放器动态创建的。我发现移动硬件的视频和Qt的包装很有气质(无可否认,在Qt5的早期更是如此),但我真的不想尝试用它做任何太聪明的事情。

几年后,我面临着同样的问题。然而,我找到了一个变通方法(对于Qt>=5.9),允许我在结束后100毫秒内暂停视频:

这个问题似乎与notifyInterval属性有关(在Qt 5.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();
}
}

相关内容

  • 没有找到相关文章

最新更新