diff options
10 files changed, 105 insertions, 7 deletions
diff --git a/.qmake.conf b/.qmake.conf index 0b51738b3..33171164d 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -2,4 +2,4 @@ load(qt_build_config) DEFINES += QT_NO_FOREACH QT_NO_JAVA_STYLE_ITERATORS QT_NO_LINKED_LIST -MODULE_VERSION = 5.15.12 +MODULE_VERSION = 5.15.13 diff --git a/examples/multimedia/video/qmlvideo/Info.plist b/examples/multimedia/video/qmlvideo/Info.plist new file mode 100644 index 000000000..92908df4b --- /dev/null +++ b/examples/multimedia/video/qmlvideo/Info.plist @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleIconFile</key> + <string></string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleExecutable</key> + <string>qmlvideo</string> + <key>CFBundleIdentifier</key> + <string>io.qt.${PRODUCT_NAME:rfc1034identifier}</string> + <key>CFBundleDisplayName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundleName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleVersion</key> + <string>1.0</string> + <key>NSCameraUsageDescription</key> + <string>Qt Multimedia Example</string> +</dict> +</plist> diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoItem.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoItem.qml index 8372acb7e..6614863ec 100644 --- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoItem.qml +++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/VideoItem.qml @@ -71,7 +71,7 @@ VideoOutput { MediaPlayer { id: mediaPlayer autoLoad: false - loops: Audio.Infinite + loops: MediaPlayer.Infinite onError: { if (MediaPlayer.NoError != error) { diff --git a/examples/multimedia/video/qmlvideo/qmlvideo.pro b/examples/multimedia/video/qmlvideo/qmlvideo.pro index dbd3a42a1..4a73d6883 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo.pro +++ b/examples/multimedia/video/qmlvideo/qmlvideo.pro @@ -20,6 +20,8 @@ include($$SNIPPETS_PATH/performancemonitor/performancemonitordeclarative.pri) target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/video/qmlvideo INSTALLS += target +macos: QMAKE_INFO_PLIST = Info.plist + EXAMPLE_FILES += \ qmlvideo.png \ qmlvideo.svg diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentVideo.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentVideo.qml index ade7012b1..7b3bba2b3 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentVideo.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentVideo.qml @@ -61,7 +61,7 @@ VideoOutput { id: mediaPlayer autoPlay: true volume: 0.5 - loops: Audio.Infinite + loops: MediaPlayer.Infinite } function play() { mediaPlayer.play() } diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp index 9b47d4650..c0484a139 100644 --- a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp @@ -188,19 +188,30 @@ void QAndroidCaptureSession::setState(QMediaRecorder::State state) start(); break; case QMediaRecorder::PausedState: - // Not supported by Android API - qWarning("QMediaRecorder::PausedState is not supported on Android"); + pause(); break; } } void QAndroidCaptureSession::start() { - if (m_state == QMediaRecorder::RecordingState || m_status != QMediaRecorder::LoadedStatus) + if (m_state == QMediaRecorder::RecordingState + || (m_status != QMediaRecorder::LoadedStatus && m_status != QMediaRecorder::PausedStatus)) return; setStatus(QMediaRecorder::StartingStatus); + if (m_state == QMediaRecorder::PausedState) { + if (!m_mediaRecorder || !m_mediaRecorder->resume()) { + emit error(QMediaRecorder::FormatError, QLatin1String("Unable to resume the media recorder.")); + if (m_cameraSession) + restartViewfinder(); + } else { + updateStartState(); + } + return; + } + if (m_mediaRecorder) { m_mediaRecorder->release(); delete m_mediaRecorder; @@ -289,7 +300,11 @@ void QAndroidCaptureSession::start() restartViewfinder(); return; } + updateStartState(); +} +void QAndroidCaptureSession::updateStartState() +{ m_elapsedTime.start(); m_notifyTimer.start(); updateDuration(); @@ -328,6 +343,7 @@ void QAndroidCaptureSession::stop(bool error) m_mediaRecorder->stop(); m_notifyTimer.stop(); updateDuration(); + m_previousElapsedTime = 0; m_elapsedTime.invalidate(); m_mediaRecorder->release(); delete m_mediaRecorder; @@ -358,6 +374,23 @@ void QAndroidCaptureSession::stop(bool error) setStatus(QMediaRecorder::LoadedStatus); } +void QAndroidCaptureSession::pause() +{ + if (m_state == QMediaRecorder::PausedState || m_mediaRecorder == 0) + return; + + setStatus(QMediaRecorder::PausedStatus); + + m_mediaRecorder->pause(); + m_notifyTimer.stop(); + updateDuration(); + m_previousElapsedTime = m_duration; + m_elapsedTime.invalidate(); + + m_state = QMediaRecorder::PausedState; + emit stateChanged(m_state); +} + void QAndroidCaptureSession::setStatus(QMediaRecorder::Status status) { if (m_status == status) @@ -514,7 +547,7 @@ void QAndroidCaptureSession::restartViewfinder() void QAndroidCaptureSession::updateDuration() { if (m_elapsedTime.isValid()) - m_duration = m_elapsedTime.elapsed(); + m_duration = m_elapsedTime.elapsed() + m_previousElapsedTime; emit durationChanged(m_duration); } diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.h b/src/plugins/android/src/mediacapture/qandroidcapturesession.h index 8cfb9ad2a..cee148a4c 100644 --- a/src/plugins/android/src/mediacapture/qandroidcapturesession.h +++ b/src/plugins/android/src/mediacapture/qandroidcapturesession.h @@ -136,7 +136,9 @@ private: CaptureProfile getProfile(int id); void start(); + void updateStartState(); void stop(bool error = false); + void pause(); void setStatus(QMediaRecorder::Status status); @@ -154,6 +156,7 @@ private: QElapsedTimer m_elapsedTime; QTimer m_notifyTimer; qint64 m_duration; + qint64 m_previousElapsedTime = 0; QMediaRecorder::State m_state; QMediaRecorder::Status m_status; diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp index 3ea7bc773..50baaed21 100644 --- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp +++ b/src/plugins/android/src/wrappers/jni/androidcamera.cpp @@ -797,6 +797,12 @@ void AndroidCamera::getCameraInfo(int id, AndroidCameraInfo *info) default: break; } + // Add a number to allow correct access to cameras on systems with two + // (and more) front/back cameras + if (id > 1) { + info->name.append(QByteArray::number(id)); + info->description.append(QString(" %1").arg(id)); + } } void AndroidCamera::startPreview() diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp index d607ab806..10508a358 100644 --- a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp +++ b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp @@ -213,6 +213,32 @@ void AndroidMediaRecorder::stop() } } +void AndroidMediaRecorder::pause() +{ + QJNIEnvironmentPrivate env; + m_mediaRecorder.callMethod<void>("pause"); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif + env->ExceptionClear(); + } +} + +bool AndroidMediaRecorder::resume() +{ + QJNIEnvironmentPrivate env; + m_mediaRecorder.callMethod<void>("resume"); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif + env->ExceptionClear(); + return false; + } + return true; +} + void AndroidMediaRecorder::setAudioChannels(int numChannels) { m_mediaRecorder.callMethod<void>("setAudioChannels", "(I)V", numChannels); diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.h b/src/plugins/android/src/wrappers/jni/androidmediarecorder.h index e4b3a80ea..55b370cf1 100644 --- a/src/plugins/android/src/wrappers/jni/androidmediarecorder.h +++ b/src/plugins/android/src/wrappers/jni/androidmediarecorder.h @@ -138,6 +138,8 @@ public: bool start(); void stop(); + void pause(); + bool resume(); void setAudioChannels(int numChannels); void setAudioEncoder(AudioEncoder encoder); |