Take snapshot of video in Qt Multimedia - qt

Is it possible to take snapshot of a video in Qt Multimedia? how?

It depends on the platform but what you can probably do is to use a QMediaPlayer, set a subclassed video surface via setVideoOutput, and get the frame data from the QVideoFrame passed in the present method. You'll then have to deal with the frame format and to map if those are not in CPU memory.
However, depending on your need, I would use ffmpeg/libav to get a frame from a specific position.

Try this (Documentation here: http://doc.qt.io/qt-5/qml-qtquick-item.html#grabToImage-method)
import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import QtMultimedia 5.0
Window {
id: mainWindow
visible: true
width: 480
height: 800
MediaPlayer {
id: player
source: "file:///location/of/some/video.mp4"
autoPlay: false
}
ColumnLayout {
anchors.fill: parent
VideoOutput {
id: output
source: player
Layout.fillHeight: true
Layout.fillWidth: true
}
Row {
id: buttonsRow
height: 100
spacing: 20
anchors.horizontalCenter: parent.horizontalCenter
Layout.margins: 10
Button {
id: playPauseButton
text: player.playbackState === MediaPlayer.PlayingState ? "Pause" : "Play"
onClicked: {
var playing = player.playbackState === MediaPlayer.PlayingState;
playing ? player.pause() : player.play();
}
}
Button {
text: "Snapshot"
onClicked: {
output.grabToImage(function(image) {
console.log("Called...", arguments)
image.saveToFile("screen.png"); // save happens here
});
}
}
}
}
}

Related

get cursor position in WebEngineView qml

I have a program in Qt and a WebEngineView in it .I want to when my user clicked on a inputbox in webEngine a keyboard have been loaded and the inputbox get its contents from my keyboard (i wrote my own keyboard) but i can't do it .i try codes in bellow but don't work
WebEngineView {
anchors.fill:parent
id:webEng
url: "https://example.com"
visible: true
MouseArea {
id : mousearea
anchors.fill: parent
onClicked: {
mykeyboard.visible=true;
}
}
}
This is not a complete answer but this code could help:
import QtQuick 2.10
import QtWebView 1.1
import QtQuick.Controls 1.4
import QtWebEngine 1.7
Item {
width: 1280
height: 720
WebView { // or WebEngineView {
id: webview
width: 1280
height: 720
url: "http://google.com"
visible: true
onLoadingChanged: {
if (loadRequest.status === WebView.LoadSucceededStatus) {
console.log("Loaded!!")
webview.runJavaScript('
var input = document.getElementById("lst-ib");
input.addEventListener("click", function() {
alert("Clicked!");
});
'
)
}
}
}
Rectangle {
id: myDummyKeyboard
anchors.bottom: parent.bottom
width: parent.width
height: 100
color: "gray"
visible: true
border.width: 20
Button {
anchors.centerIn: parent
text: "Dummy"
onClicked: {
webview.runJavaScript('document.getElementById("lst-ib").value += "' + text + '"');
}
}
}
}
The part in the WebView (or WebEnginView) allows to display an alert when the input is clicked. But, something is missing, to link it to a QML handler. The solution is maybe to use WebChannel or maybe WebEngineScript as said by #folibis in the comments.
The part defined by myDummyKeyboard allows to add a string into the input when the user is clicking the button in the rectangle (fake keyboard).

How to set an item property of one qml from main.qml

I waste my time to find how set the visible property to false, the delegate being in an another qml file.
For instance here is a simple example based on Places Map.
Marker.qml
import QtQuick 2.0
import QtLocation 5.6
MapQuickItem {
id: idPointsMarker
sourceItem: Loader{sourceComponent: idRect}
visible: true //if set manually to false, everything works correctly
Component{
id: idRect
Rectangle{
width: 20
height: 20
color: "blue"
}
}
}
and the main.qml
import QtQuick 2.0
import QtQuick.Window 2.0
import QtLocation 5.6
import QtPositioning 5.6
Window {
width: 512
height: 512
visible: true
PositionSource {
...
}
property variant locationOslo: QtPositioning.coordinate( 59.93, 10.76)
PlaceSearchModel {
...
}
Map {
id: map
anchors.fill: parent
plugin: Plugin {name: "osm"}
center: locationOslo
zoomLevel: 13
MouseArea {
id : mouseMap
anchors.fill: parent
onDoubleClicked: {
console.log("DoubleClicked")
Marker.idPointsMarker.visible = false // pb is here
}
}
MapItemView {
model: searchModel
delegate: Marker{
coordinate: place.location.coordinate
}
}
}
}
I wish to toggle the visibility to false on doubleclick. I am not able to access the property anyhow the way i write it. What is the correct syntax?
Sorry for a so simple question. Thanks for help.
You do not have to set the property in main.qml, you must do it in Marker.qml, since the elements of Marker.qml can access all the elements of main.qml. One solution is to establish a property of type bool that manages the visibility and that changes in the double click:
main.qml
Map {
[...]
property bool isVisibleItems: true
MouseArea {
id : mouseMap
anchors.fill: parent
onDoubleClicked: map.isVisibleItems = !map.isVisibleItems
}
[...]
Marker.qml
import QtQuick 2.0
import QtLocation 5.6
MapQuickItem {
id: idPointsMarker
sourceItem: Loader{sourceComponent: idRect}
visible: map.isVisibleItems
Component{
id: idRect
Rectangle{
width: 20
height: 20
color: "blue"
}
}
}
In the following link there is an example

How to setup my button component to open a window

Here is the code of the window I wanna be opened in file PopUpFreeCoins.qml:
import QtQuick 2.0
import QtQuick.Controls 2.1
Item {
property int t
property int c
ListModel{
id:ff
ListElement {
name: "ByFollow"
s: "Images/follow.png"
}
ListElement {
name: "ByLike"
s: "Images/care.png"
}
ListElement {
name: "ByComment"
s: "Images/chat.png"
}
}
ListView{
width:t-t/10
height: c/5
layoutDirection:Qt.LeftToRight
orientation: ListView.Horizontal
model: ff
spacing:50
delegate: Button{
contentItem: Image{
source: s
}}
}
}
property t is set equal to window width in main file and property c is set to window height. This is code of my Button.qml:
Button{//Below Right
width:profilePicture.width/2
height:profilePicture.width/2
x:profilePicture.x+profilePicture.width
y:profilePicture.y+profilePicture.height
contentItem: Image {
source: "Images/freecoins.png"
anchors.fill: parent
}
onClicked: PopUp{height:100;width:300;PopUpFreeCoins{t:a;c:b;}}
}
property a is window width and b is window height.
this line onClicked: PopUp{height:100;width:300;PopUpFreeCoins{t:a;c:b;}} has an error I don't know how to handle!
Here is the error:
Cannot assign object type PopUpFreeCoins_QMLTYPE_0 with no default
method
You need to create the Object somehow. You have multiple ways for dynamically create Objects. One way is to use Component.createObject(parent) which requires you to have a Component instantiated in your file.
Here you can also pass a Object ({property0 : value, property1:value ... }) as second argument, to set the properties of the Component to be instantiated. You should not set the parent to null as it might happen, that the JS-garbage collector is too aggressive once again.
Alternatively you can use the Loader to load it from either a source (QML-file) or sourceComponent. Here you won't have problems with the garbage collector.
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
width: 1024
height: 800
visible: true
Button {
text: 'create'
onClicked: test.createObject(this)
}
Button {
x: 200
text: 'load'
onClicked: loader.active = !loader.active
}
Loader {
id: loader
source: 'TestObj.qml'
active: false
}
Component {
id: test
TestObj {}
}
}
TestObj.qml includes the Window to be opened.
Alternatively you can have the Window created from the beginning, and just change the visible to true or false.

QML BusyIndicator while loading a heavy qml file

I've been trying to run a BusyIndicator (http://doc.qt.io/qt-5/qml-qtquick-controls-busyindicator.html) while I am loading a qml file (http://doc.qt.io/qt-5/qml-qtquick-loader.html), but the BusyIndicator doesn't appear.
What I am trying to do is:
1- The user emits a "handlerLoader(name)", where "name" is the url of the next qml page.
2- In "onHandlerLoader" I run the busyIndicator.
3- Then, I change the Loader source.
The problem is that no matter the time I spent between steps 2 and 3, the BusyIndicator does not appear.
Moreover, when I comment step 3, the busyIndicator appears correctly.
What I am doing wrong?
Thanks!!
This is the code:
Rectangle {
visible: true
width: 800
height: 480
signal handlerLoader (string name)
Loader {
id: pageLoader;
source: "init.qml";
}
BusyIndicator {
id: busyIndicator_inicio
width: 100
height: 100
anchors.centerIn: parent
running: false
}
Connections {
target: pageLoader.item
onHandlerLoader: {
busyIndicator_inicio.running = true
pageLoader.source = name;
}
}
}
The reason is, that your heavy-loading Loader is blocking the thread.
Set it to asynchronous mode, to allow the rest of the program to run.
Further, I'd recommend to prefer declarative bindings to imperative assignments in handlers. See my example:
main.qml:
import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
Window {
width: 1000
height: 800
visible: true
Button {
text: 'load'
onClicked: {
loader.source = "TestObj.qml"
}
}
Loader {
anchors.fill: parent
id: loader
active: true
asynchronous: true
visible: status == Loader.Ready
}
BusyIndicator {
id: ind
anchors.fill: parent
running: loader.status == Loader.Loading
}
}
TestObj.qml:
import QtQuick 2.0
Item {
Grid {
anchors.fill: parent
columns: width
rows: height
Repeater {
model: 100
Rectangle {
width: { for (var i = 0; i < 10000; i++) console.log(i); return 1 }
height: 1
color: 'green'
}
}
}
}
Since the asynchronous Loader might display incomplete files for some time, I set it to be visible only when its status changes to ready.

QML Audio stops 400 milliseconds before the end

Can someone, please, explain this odd behavior of my application.
I am using Qt 5.1.0 and msvc2010.
This is my code:
import QtQuick 2.1
import QtQuick.Window 2.1
import QtMultimedia 5.0
Window {
visible: true
width: 360
height: 360
MouseArea {
anchors.fill: parent
onClicked: {
playAudio.play()
}
}
Audio {
id: playAudio
source: "zvuky/1.mp3"
}
}
Your code doesn't have any error. Maybe it's due to the mp3 file and Qt is not able to load it.
Did you try to convert the mp3 file to wav? Sometimes it's better to use SoundEffect instead of Audio.
You could also try the MediaPlayer type.
Here you have an example. It's in GitHub where you can download the audio clips.
import QtQuick 2.5
import QtQuick.Window 2.2
import QtMultimedia 5.4
Window {
visible: true
width: 360
height: 360
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if (mouse.button == Qt.RightButton)
playMP3.play()
else
playWAV.play()
}
}
SoundEffect {
id: playWAV
source: "res/kid_giggle.wav"
onPlayingChanged: {
console.log("SoundEffect - onPlayingChanged - category: " + category)
}
}
MediaPlayer {
id: playMP3
source: "res/kid_giggle.mp3"
onPlaying: {
console.log("MediaPlayer - onPlaying - duration: " + duration)
}
}
}
Finelly I found solution.
Everything works perfect with Audio element when I used Qt 5.2.1(msvc2012)

Resources