Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. crash on iOS with camera
Forum Updated to NodeBB v4.3 + New Features

crash on iOS with camera

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
1 Posts 1 Posters 244 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    FrankiPL
    wrote on last edited by
    #1

    Hi
    I have mobile application on which I need to record and send some clip.
    Works fine on Android, but on iOS app crashes after I use camera and record some clip.
    Page with code, same page does pictures and video, no problem with pictures on Android and iOS

    import QtQuick 2.12
    import Felgo 3.0
    import QtMultimedia 5.12
    import QtQuick.Controls 2.12 as QtControls
    import Qt.labs.platform 1.1
    
    import "../constants"
    import "../components"
    import "../utility/utils.js" as Utils
    
    Page {
        id: root
        title: "New Page"
        navigationBarHidden: true
        backgroundColor: "black"
        property color statusBarColor: "black"
        property int statusBarTheme
        property Page returnPage
        signal closeClicked()
        onPushed: {
            cameraLoader.sourceComponent = cameraComponent
        }
        onPopped: {
            cameraLoader.item.stop()
            cameraLoader.sourceComponent = undefined
        }
        Component{
            id: cameraComponent
            Camera{
                captureMode: Camera.CaptureStillImage
                exposure.exposureMode: Camera.ExposurePortrait
                position: Camera.BackFace
                flash.mode: Camera.FlashOff
                focus{
                    focusMode: Camera.FocusContinuous
                    focusPointMode: Camera.FocusPointCenter
                }
                videoRecorder.outputLocation: StandardPaths.writableLocation(StandardPaths.AppDataLocation)
            }
        }
        Loader{
            id: cameraLoader
            onLoaded: {
                if(item !== undefined) item.start()
            }
        }
        VideoOutput{
            id: cameraOutput
            source: cameraLoader.item
            anchors.top: parent.top
            anchors.topMargin: dp(20)
            anchors.horizontalCenter: parent.horizontalCenter
            width: parent.width
            height: 0.82 * parent.height
            autoOrientation: true
            Rectangle{
                id: topGradientRect
                anchors.top: parent.top
                width: parent.width
                height: 0.1 * parent.height
                anchors.horizontalCenter: parent.horizontalCenter
                radius: dp(4)
                opacity: 0.75
                gradient: Gradient{
                    GradientStop{
                        position: 0.0
                        color: Qt.rgba(0, 0, 0, 1)
                    }
                    GradientStop{
                        position: 1.0
                        color: Qt.rgba(0, 0, 0, 0)
                    }
                }
            }
            ColorableImage{
                id: closeButtonImage
                anchors.top: parent.top
                anchors.topMargin: dp(20)
                anchors.left: parent.left
                anchors.leftMargin: dp(15)
                width: dp(24)
                height: dp(24)
                imageSource: "qrc:/assets/ic_controls_24_navigation_arrows_collapse_element.svg"
                imageColor: "white"
                z: 2
                MouseArea{
                    anchors.fill: parent
                    anchors.margins: -dp(5)
                    onClicked: {
                        closeClicked()
                    }
                }
            }
            Rectangle{
                id: bottomGradientRect
                anchors.bottom: parent.bottom
                anchors.horizontalCenter: parent.horizontalCenter
                height: 0.1 * parent.height
                radius: dp(4)
                opacity: 0.75
                width: parent.width
                gradient: Gradient{
                    GradientStop{
                        position: 0.0
                        color: Qt.rgba(0, 0, 0, 0)
                    }
                    GradientStop{
                        position: 1.0
                        color: Qt.rgba(0, 0, 0, 1)
                    }
                }
            }
            Image{
                id: cameraChangeImage
                anchors.verticalCenter: closeButtonImage.verticalCenter
                anchors.horizontalCenter: parent.horizontalCenter
                anchors.horizontalCenterOffset: -(sourceSize.width/2 + dp(12))
                source: "qrc:/assets/icActions24CameraChange.svg"
                sourceSize: Qt.size(dp(24), dp(24))
                MouseArea{
                    anchors.fill: parent
                    anchors.margins: -dp(5)
                    onClicked: {
                        cameraLoader.item.position = (cameraLoader.item.position === Camera.FrontFace) ? Camera.BackFace : Camera.FrontFace
                    }
                }
            }
            Image{
                id: flashOffImage
                anchors.verticalCenter: closeButtonImage.verticalCenter
                anchors.horizontalCenter: parent.horizontalCenter
                anchors.horizontalCenterOffset: -(cameraChangeImage.anchors.horizontalCenterOffset)
                source: "qrc:/assets/icActions24FlashOff.svg"
                sourceSize: Qt.size(dp(24), dp(24))
                MouseArea{
                    anchors.fill: parent
                    anchors.margins: -dp(5)
                    onClicked: {
                        cameraLoader.item.flash.mode = cameraLoader.item.flash.mode === Camera.FlashOn ? Camera.FlashOff : Camera.FlashOn
                    }
                }
            }
            Text {
                id: currentRecordingDuration
                visible: videoButton.checked
                anchors.verticalCenter: flashOffImage.verticalCenter
                anchors.right: parent.right
                anchors.rightMargin: dp(20)
                text: getDurationString(Math.floor(cameraLoader.item !== null ? cameraLoader.item.videoRecorder.duration/1000 : 0))
                font.bold: true
                color: if(cameraLoader.item !== null) cameraLoader.item.videoRecorder.recorderState === CameraRecorder.StoppedState ? "white" : Style.appYellow
                font.pixelSize: sp(14)
            }
        }
        Rectangle{
            id: horizontalDivider
            anchors.horizontalCenter: parent.horizontalCenter
            visible: false
        }
        QtControls.Button{
            id: photoButton
            text: qsTr("Photo")
            anchors.bottom: cameraOutput.bottom
            anchors.bottomMargin: dp(14)
            anchors.right: horizontalDivider.left
            anchors.rightMargin: dp(10)
            padding: 0
            checkable: true
            checked: true
            width: implicitWidth
            height: implicitHeight
            background: Rectangle{
                color: "transparent"
            }
            contentItem: Text{
                text: parent.text
                color: parent.checked ? Style.appYellow : "white"
                horizontalAlignment: Qt.AlignHCenter
                verticalAlignment: Qt.AlignVCenter
                font.pixelSize: sp(14)
                font.bold: true
            }
            onCheckedChanged:{
                if(checked){
                    cameraLoader.item.captureMode = Camera.CaptureStillImage
                }
            }
        }
        QtControls.Button{
            id: videoButton
            text: qsTr("Video")
            anchors.bottom: photoButton.bottom
            anchors.left: horizontalDivider.right
            anchors.leftMargin: dp(10)
            padding: 0
            checkable: true
            width: implicitWidth
            height: implicitHeight
            background: Rectangle{
                color: "transparent"
            }
            contentItem: Text{
                text: parent.text
                color: parent.checked ? Style.appYellow : "white"
                horizontalAlignment: Qt.AlignHCenter
                verticalAlignment: Qt.AlignVCenter
                font.pixelSize: sp(14)
                font.bold: true
            }
            onCheckedChanged: {
                if(checked){
                    cameraLoader.item.captureMode = Camera.CaptureVideo
                }
            }
        }
        QtControls.ButtonGroup{
            buttons: [photoButton, videoButton]
        }
        Rectangle{
            anchors.bottom: photoButton.top
            anchors.bottomMargin: dp(15)
            anchors.horizontalCenter: parent.horizontalCenter
            width: dp(70)
            height: width
            radius: height/2
            color: Qt.rgba(1, 1, 1, 0.3)
            Rectangle{
                anchors.fill: parent
                anchors.margins: dp(10)
                radius: height/2
                color: videoButton.checked ? Style.critical :  "white"
            }
            MouseArea{
                anchors.fill: parent
                onClicked: {
                    if(videoButton.checked){
                        if(cameraLoader.item.videoRecorder.recorderState === CameraRecorder.StoppedState)
                            cameraLoader.item.videoRecorder.record()
                        else{
                            cameraLoader.item.videoRecorder.stop()
                            addImageAndBack(cameraLoader.item.videoRecorder.actualLocation, true, true)
                        }
                    }else if(photoButton.checked){
                        cameraLoader.item.searchAndLock()
                        captureTimer.start()
                    }
                }
    
            }
            Timer{
                id: captureTimer
                running: false
                repeat: false
                interval: 400
                onTriggered: {
                    if(cameraLoader.item.imageCapture.ready){
                        cameraLoader.item.imageCapture.capture()
                        cameraLoader.item.unlock()
                    }else{
                        start()
                    }
                }
            }
        }
        Rectangle{
            anchors.fill: cameraOutput
            radius: dp(4)
            color: "transparent"
        }
        Connections{
            target: cameraLoader.item.imageCapture
            enabled: cameraLoader.status === Loader.Ready
            onCaptureFailed:{
                NativeDialog.confirm(qsTr("Error"), message, ok => {}, false)
            }
            onImageSaved:{
                console.debug(path)
                //cameraLoader.item.stop()
                addImageAndBack("file:" + path, false, true)
            }
        }
        function getDurationString(seconds){
            const fullMinutes = Math.floor(seconds/60)
            const secondsInActualMinute = seconds % 60
            return `${Utils.makeDoubleDigitString(fullMinutes)}:${Utils.makeDoubleDigitString(secondsInActualMinute)}`
        }
    }
    

    Crash is alway a few seconds after I record clip

    Thread 26 Queue : com.apple.root.default-qos (concurrent)
    #0      0x000000019e8b21e0 in objc_msgSend ()
    #1      0x0000000103474d54 in __27-[AVFMediaAssetWriter stop]_block_invoke_3 ()
    #2      0x000000018b159de8 in __111+[__NSOperationInternalObserver _observeValueForKeyPath:ofObject:changeKind:oldValue:newValue:indexes:context:]_block_invoke_2 ()
    #3      0x000000010716c0b4 in _dispatch_call_block_and_release ()
    #4      0x000000010716dde0 in _dispatch_client_callout ()
    #5      0x0000000107170918 in _dispatch_queue_override_invoke ()
    #6      0x0000000107181e30 in _dispatch_root_queue_drain ()
    #7      0x00000001071827ec in _dispatch_worker_thread2 ()
    #8      0x00000001d5a3e768 in _pthread_wqthread ()
    

    I have changed

    videoRecorder.outputLocation: StandardPaths.writableLocation(StandardPaths.AppDataLocation)
    

    To different paths but it does not make any difference.
    When I leave this unset then
    videoRecorder.outputLocation
    is empty on iOS, and on Android it has value
    Im using Qt 5.15.2 with Felgo.
    Any idea what causing the problem?

    Best Regards
    Marek

    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved