QML Audio stops 400 milliseconds before the end - qt

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)

Related

Qml menu popup latency

When my mouse event happened,the menu can popup,but not immediately,it seems a little latency. this is my code, is anything wrong?
My Qt version is 5.15, my system is Windows 10.
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.12
Window {
visible: true
width: 450
height: 350
title: qsTr("ListView")
property bool refreshFlag: false
Rectangle {
id: rightview
width: 60
height: 300
x: 100
color: "#EEEEEE"
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton | Qt.LeftButton
onClicked: {
console.log(width)
if (mouse.button === Qt.RightButton)
contextMenus.popup()
}
Menu {
id: contextMenus
MenuItem { text: "open" }
MenuItem { text: "save " }
MenuItem { text: "else..." }
}
}
Text {
font.pointSize: 12
text: "content"
}
}
}
this is my screenshot
A couple of issues with your program snippet:
Don't mix QtQuick.Controls 1.x with QtQuick.Controls 2.x
Recommend you update all your references to versions to 2.15
Do not declare Menu inside MouseArea, it doesn't make sense
The MouseArea can be optimized to only accept the RightButton
Declare the Menu at the "top level"
Here's a cleanup of your code:
import QtQuick 2.15
import QtQuick.Controls 2.15
Page {
anchors.fill: parent
Rectangle {
x: 100
width: 60
height: 300
color: "#EEEEEE"
Text {
font.pointSize: 12
text: "content"
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: contextMenus.popup()
}
}
Menu {
id: contextMenus
MenuItem { text: "open" }
MenuItem { text: "save " }
MenuItem { text: "else..." }
}
}
You can Try it Online!
There appears to be no performance issue when I run the above snippet using qmlonline. I don't think the code is an issue. I think we need to get an understanding of:
Your version of Qt
Your platform (i.e. OS, hardware, etc)

Transport QML Image via Bridge

I have at the moment a simple PySide6 app which uses qml for image capturing. I want to transport the image to our app but cannot figure out how. I am not sure, if saving QML image is an attempt in the right direction.
My PySide App
import sys
from pathlib import Path
from PySide6.QtCore import QObject, Slot
from PySide6.QtGui import QGuiApplication, QImage
from PySide6.QtQml import QQmlApplicationEngine, QmlElement
QML_IMPORT_NAME = "io.qt.textproperties"
QML_IMPORT_MAJOR_VERSION = 1
#QmlElement
class Bridge(QObject):
#Slot(QImage)
def capture(self, preview):
# Do something with the preview
print(type(preview))
if __name__ == "__main__":
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
# Get the path of the current directory, and then add the name
# of the QML file, to load it.
qml_file = Path(__file__).parent / "simpleCam.qml"
engine.load(qml_file)
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec())
MY QML File
import QtQuick
import QtQuick.Controls
import QtMultimedia
import io.qt.textproperties
ApplicationWindow {
id: mainFrame
width: 640
height: 480
visible: true
title: qsTr("Cam Test")
Bridge {
id: bridge
}
Rectangle {
width: 640
height: 400
MediaDevices {
id: mediaDevices
}
CaptureSession {
imageCapture: ImageCapture {
id: capture
}
camera: Camera {
id: camera
}
videoOutput: output
}
VideoOutput {
id: output
anchors.fill: parent
}
Button {
id: startCamButton
text: "Start Cam"
anchors.top: output.bottom
anchors.left: output.left
onClicked: {
camera.start()
camImage.opacity = 0
}
}
Button {
id: takePicButton
text: "take pic"
anchors.top: output.bottom
anchors.left: startCamButton.right
onClicked: {
capture.capture()
camImage.opacity = 1
}
}
Image {
id: camImage
anchors.fill: parent
source: capture.preview
}
}
}
The Result
What is missing?
In the Button with id: takePicButton I want to transport the image to the PySide6 Bridge. If I add to theonClicked Signal bridge.capture(capture.preview) I got the Error:
TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed.`
How can I solve this problem?
You should use the imageCaptured signal.
Change:
imageCapture: ImageCapture {
id: capture
}
To:
imageCapture: ImageCapture {
id: capture
onImageCaptured: function(req_id, preview){bridge.capture(req_id, preview)}
}
And change in main.py:
#Slot(QImage)
def capture(self, preview):
# Do something with the preview
print(type(preview))
To:
#Slot(int, QImage)
def capture(self,req_id, preview):
print(req_id)
print(type(preview))
Working example here.
You might want to look at this answer for other use cases.

requestService(): no service found for - "org.qt-project.qt.camera"

I tried this example from one of the qml camera tutorials.
The camera is being detected through "cheese", but is not shown through this code.
This code results in "defaultServiceProvider::requestService(): no service found for - "org.qt-project.qt.camera"
Am using Qt 5.4 with QtGstreamer 1.2
What should I look into?
import QtQuick 2.1
import QtQuick.Window 2.2
import QtMultimedia 5.4
Window
{
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Camera {
id: camera
imageProcessing.whiteBalanceMode: CameraImageProcessing.WhiteBalanceFlash
exposure {
exposureCompensation: -1.0
exposureMode: Camera.ExposurePortrait
}
flash.mode: Camera.FlashRedEyeReduction
imageCapture {
onImageCaptured: {
photoPreview.source = preview // Show the preview in an Image
}
}
}
VideoOutput {
source: camera
anchors.fill: parent
focus : visible // to receive focus and capture key events when visible
}
Image {
id: photoPreview
}
}

How to use QML Connect{} with Qt Creator Design Mode

The below code works fine in Qt Creator Edit Mode, but when I try to switch to Design Mode it gives an error:
"Can not open this qml document because of an error in the qml file."
And then I can't edit the layout graphically. If I comment out the Connect{} item then Design Mode works again and I can edit graphically.
Anybody see what the error might be.
What am I doin wrong? Thanks for looking.
import QtQuick 2.4
import QtQuick.Window 2.2
Window {
id: window1
visible: true
Rectangle {
id: rect
color: "#ffffff"
width: 100; height: 100
MouseArea {
id: mouseArea
anchors.fill: parent
}
Connections {
target: mouseArea
onClicked: {
print("clicked")
}
}
}
}

Take snapshot of video in Qt Multimedia

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

Resources