我正在尝试停止播放QML视频,并在播放完成后显示其最后一帧。有人知道怎么做这个吗? (对不起,这似乎并不像听起来那么简单......)
目前,我的问题是视频元素在播放完成后变得不可见/隐藏。 (onVisibleChanged
永远不会被调用。)
当我在代码中使用onStatusChanged
中的hack时,视频会在结束后消失一段时间,然后显示视频结束。
我正在做的只是:
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上使用最新的Qt 5.2(msvc2010 + OpenGL-build)。
答案 0 :(得分:4)
几年后,我面临着同样的问题。但是,我找到了一种解决方法(对于Qt> = 5.9),使我可以在结束后100毫秒内暂停视频:
问题似乎与notifyInterval属性有关(在Qt 5.9中引入)。默认情况下,它设置为1000毫秒(与其他答案中观察到的1000毫秒相同,我相信这不是巧合)。因此,在视频即将结束时将其更改为非常小的值,可以捕获到非常接近末端的位置并在那里暂停视频:
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()
}
}
希望这对某人有帮助!
答案 1 :(得分:3)
我仍然在寻找更好的解决方案。我提出的是在视频结束之前暂停一下视频:
MediaPlayer {
autoLoad: true
id: video
onPositionChanged: {
if (video.position > 1000 && video.duration - video.position < 1000) {
video.pause();
}
}
}
为什么一秒钟?在我的机器上,如果你试图在结束前大约500毫秒暂停它,视频会设法运行完成并从视图中消失,甚至没有注册pause()
电话。因此,1秒对我来说是一个很好的安全价值。
坦率地说,如果有更明确的方式告诉MediaPlayer在视频结尾处做什么,我更喜欢。我知道Gstreamer是Qt在Linux和Mac上使用的,它会在视频几乎结束时通知您,以便您可以决定下一步该做什么 - 例如暂停视频或无缝循环播放。
答案 2 :(得分:3)
我分享你的痛苦(主要是对OSX和iOS感兴趣,同样的问题发生在那里)。我唯一的解决方案是将每个视频(至少是“预制”应用资源,而不是网络上的动态内容)与最终帧的png图像配对。当视频开始时,启用它下面的图像显示(尽管在那时它实际上不可见)。当视频突然结束时,图像将保持可见。
这在iOS上运行得很好,但在(某些?)Mac上,视频和图像之间可能会有轻微的亮度跳跃(猜测:与OSX显示偏好有关的屏幕校准不会影响视频?)
要在最后一帧上冻结的MediaPlayer或VideoOutput元素类型的选项确实会简单得多。
我考虑但未尝试的另一种可能性是堆叠两个视频。顶部的那个是主要播放器,但是下面的那个将被视为,例如,视频的最后一毫秒并暂停。然后当主视频结束并消失时...就像在视频的最后一帧显示在下面一样好。这基本上与基于图像的解决方案相同,但下面的图像是使用视频播放器动态创建的。我发现移动硬件的视频和它的Qt包装足够气质(不可否认的是更早回到Qt5的早期)真的不想尝试做任何过于聪明的事情。
答案 3 :(得分:0)
在 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();
}
}