12#include <QtCore/qcoreapplication.h>
13#include <QtCore/qlogging.h>
14#include <QtCore/qurl.h>
18Q_STATIC_LOGGING_CATEGORY(lcMediaRecorder,
"qt.multimedia.mediarecorder.android");
21 "org/qtproject/qt/android/multimedia/QtAudioDeviceManager");
29 return QStringLiteral(
"%1-%2");
34 if (g_camcorderProfiles->contains(profileKey().arg(cameraId).arg(quality)))
37 return QJniObject::callStaticMethod<jboolean>(
"android/media/CamcorderProfile",
46 const QString key = profileKey().arg(cameraId).arg(quality);
47 QMap<QString, QJniObject>::const_iterator it = g_camcorderProfiles->constFind(key);
49 if (it != g_camcorderProfiles->constEnd())
52 QJniObject camProfile = QJniObject::callStaticObjectMethod(
"android/media/CamcorderProfile",
54 "(II)Landroid/media/CamcorderProfile;",
58 return AndroidCamcorderProfile((*g_camcorderProfiles)[key] = camProfile);
65 return m_camcorderProfile.getField<jint>(
"audioBitRate");
67 return m_camcorderProfile.getField<jint>(
"audioChannels");
69 return m_camcorderProfile.getField<jint>(
"audioCodec");
71 return m_camcorderProfile.getField<jint>(
"audioSampleRate");
73 return m_camcorderProfile.getField<jint>(
"duration");
75 return m_camcorderProfile.getField<jint>(
"fileFormat");
77 return m_camcorderProfile.getField<jint>(
"quality");
79 return m_camcorderProfile.getField<jint>(
"videoBitRate");
81 return m_camcorderProfile.getField<jint>(
"videoCodec");
82 case videoFrameHeight:
83 return m_camcorderProfile.getField<jint>(
"videoFrameHeight");
85 return m_camcorderProfile.getField<jint>(
"videoFrameRate");
87 return m_camcorderProfile.getField<jint>(
"videoFrameWidth");
95 m_camcorderProfile = camcorderProfile;
99 "org/qtproject/qt/android/multimedia/QtMediaRecorderListener";
107 emit obj->error(what, extra);
114 emit obj->info(what, extra);
121 m_mediaRecorder = QJniObject(
"android/media/MediaRecorder");
122 if (m_mediaRecorder.isValid()) {
123 QJniObject listener(QtMediaRecorderListenerClassName,
"(J)V", m_id);
124 m_mediaRecorder.callMethod<
void>(
"setOnErrorListener",
125 "(Landroid/media/MediaRecorder$OnErrorListener;)V",
127 m_mediaRecorder.callMethod<
void>(
"setOnInfoListener",
128 "(Landroid/media/MediaRecorder$OnInfoListener;)V",
130 mediaRecorders->insert(m_id,
this);
136 if (m_isVideoSourceSet || m_isAudioSourceSet)
140 mediaRecorders->remove(m_id);
145 m_mediaRecorder.callMethod<
void>(
"release");
151 auto methodId = env->GetMethodID(m_mediaRecorder.objectClass(),
"prepare",
"()V");
152 env->CallVoidMethod(m_mediaRecorder.object(), methodId);
154 if (env.checkAndClearExceptions())
161 m_mediaRecorder.callMethod<
void>(
"reset");
162 m_isAudioSourceSet =
false;
163 m_isVideoSourceSet =
false;
169 auto methodId = env->GetMethodID(m_mediaRecorder.objectClass(),
"start",
"()V");
170 env->CallVoidMethod(m_mediaRecorder.object(), methodId);
172 if (env.checkAndClearExceptions())
179 m_mediaRecorder.callMethod<
void>(
"stop");
184 m_mediaRecorder.callMethod<
void>(
"setAudioChannels",
"(I)V", numChannels);
190 m_mediaRecorder.callMethod<
void>(
"setAudioEncoder",
"(I)V",
int(encoder));
195 m_mediaRecorder.callMethod<
void>(
"setAudioEncodingBitRate",
"(I)V", bitRate);
200 m_mediaRecorder.callMethod<
void>(
"setAudioSamplingRate",
"(I)V", samplingRate);
205 if (!m_isAudioSourceSet) {
207 auto methodId = env->GetMethodID(m_mediaRecorder.objectClass(),
"setAudioSource",
"(I)V");
208 env->CallVoidMethod(m_mediaRecorder.object(), methodId, source);
209 if (!env.checkAndClearExceptions())
210 m_isAudioSourceSet =
true;
212 qCWarning(lcMediaRecorder) <<
"Audio source already set. Not setting a new source.";
218 return m_isAudioSourceSet;
223 using namespace QtJniTypes;
225 AudioDeviceInfo deviceInfo = QtAudioDeviceManager::callStaticMethod<AudioDeviceInfo>(
226 "getAudioInputDeviceInfo", id.toInt());
228 if (!m_mediaRecorder.callMethod<jboolean>(
"setPreferredDevice", deviceInfo))
232 QtAudioDeviceManager::callStaticMethod<jboolean>(
"prepareAudioInput", id.toInt());
235 qCWarning(lcMediaRecorder) <<
"No default input device was set.";
242 QJniObject cam = camera->getCameraObject();
243 m_mediaRecorder.callMethod<
void>(
"setCamera",
"(Landroid/hardware/Camera;)V", cam.object());
248 m_mediaRecorder.callMethod<
void>(
"setVideoEncoder",
"(I)V",
int(encoder));
253 m_mediaRecorder.callMethod<
void>(
"setVideoEncodingBitRate",
"(I)V", bitRate);
258 m_mediaRecorder.callMethod<
void>(
"setVideoFrameRate",
"(I)V", rate);
263 m_mediaRecorder.callMethod<
void>(
"setVideoSize",
"(II)V", size.width(), size.height());
270 auto methodId = env->GetMethodID(m_mediaRecorder.objectClass(),
"setVideoSource",
"(I)V");
271 env->CallVoidMethod(m_mediaRecorder.object(), methodId, source);
273 if (!env.checkAndClearExceptions())
274 m_isVideoSourceSet =
true;
279 m_mediaRecorder.callMethod<
void>(
"setOrientationHint",
"(I)V", degrees);
285 auto methodId = env->GetMethodID(m_mediaRecorder.objectClass(),
"setOutputFormat",
"(I)V");
286 env->CallVoidMethod(m_mediaRecorder.object(), methodId, format);
288 if (!env.checkAndClearExceptions())
289 m_isAudioSourceSet =
true;
294 if (QUrl(path).scheme() == QLatin1String(
"content")) {
295 const QJniObject fileDescriptor = QJniObject::callStaticObjectMethod(
296 "org/qtproject/qt/android/QtNative",
297 "openFdObjectForContentUrl",
298 "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Ljava/io/FileDescriptor;",
299 QNativeInterface::QAndroidApplication::context().object(),
300 QJniObject::fromString(path).object(),
301 QJniObject::fromString(QLatin1String(
"rw")).object());
303 m_mediaRecorder.callMethod<
void>(
"setOutputFile",
304 "(Ljava/io/FileDescriptor;)V",
305 fileDescriptor.object());
307 m_mediaRecorder.callMethod<
void>(
"setOutputFile",
308 "(Ljava/lang/String;)V",
309 QJniObject::fromString(path).object());
315 m_mediaRecorder.callMethod<
void>(
"setPreviewDisplay",
316 "(Landroid/view/Surface;)V",
322 QJniObject surfaceHolder(holder->surfaceHolder());
323 QJniObject surface = surfaceHolder.callObjectMethod(
"getSurface",
324 "()Landroid/view/Surface;");
325 if (!surface.isValid())
328 m_mediaRecorder.callMethod<
void>(
"setPreviewDisplay",
329 "(Landroid/view/Surface;)V",
335 static const JNINativeMethod methods[] = {
336 {
"notifyError",
"(JII)V", (
void *)notifyError},
337 {
"notifyInfo",
"(JII)V", (
void *)notifyInfo}
340 const int size =
std::size(methods);
346#include "moc_androidmediarecorder_p.cpp"
int getValue(Field field) const
Combined button and popup list for selecting options.
Q_GLOBAL_STATIC(QReadWriteLock, g_updateMutex)
Q_DECLARE_JNI_CLASS(MotionEvent, "android/view/MotionEvent")