12#include <QtCore/qcoreapplication.h>
13#include <QtCore/qlogging.h>
14#include <QtCore/qurl.h>
18Q_STATIC_LOGGING_CATEGORY(lcMediaRecorder,
"qt.multimedia.mediarecorder.android");
25 return QStringLiteral(
"%1-%2");
30 if (g_camcorderProfiles->contains(profileKey().arg(cameraId).arg(quality)))
33 return QJniObject::callStaticMethod<jboolean>(
"android/media/CamcorderProfile",
42 const QString key = profileKey().arg(cameraId).arg(quality);
43 QMap<QString, QJniObject>::const_iterator it = g_camcorderProfiles->constFind(key);
45 if (it != g_camcorderProfiles->constEnd())
48 QJniObject camProfile = QJniObject::callStaticObjectMethod(
"android/media/CamcorderProfile",
50 "(II)Landroid/media/CamcorderProfile;",
54 return AndroidCamcorderProfile((*g_camcorderProfiles)[key] = camProfile);
61 return m_camcorderProfile.getField<jint>(
"audioBitRate");
63 return m_camcorderProfile.getField<jint>(
"audioChannels");
65 return m_camcorderProfile.getField<jint>(
"audioCodec");
67 return m_camcorderProfile.getField<jint>(
"audioSampleRate");
69 return m_camcorderProfile.getField<jint>(
"duration");
71 return m_camcorderProfile.getField<jint>(
"fileFormat");
73 return m_camcorderProfile.getField<jint>(
"quality");
75 return m_camcorderProfile.getField<jint>(
"videoBitRate");
77 return m_camcorderProfile.getField<jint>(
"videoCodec");
78 case videoFrameHeight:
79 return m_camcorderProfile.getField<jint>(
"videoFrameHeight");
81 return m_camcorderProfile.getField<jint>(
"videoFrameRate");
83 return m_camcorderProfile.getField<jint>(
"videoFrameWidth");
91 m_camcorderProfile = camcorderProfile;
95 "org/qtproject/qt/android/multimedia/QtMediaRecorderListener";
103 emit obj->error(what, extra);
110 emit obj->info(what, extra);
117 m_mediaRecorder = QJniObject(
"android/media/MediaRecorder");
118 if (m_mediaRecorder.isValid()) {
119 QJniObject listener(QtMediaRecorderListenerClassName,
"(J)V", m_id);
120 m_mediaRecorder.callMethod<
void>(
"setOnErrorListener",
121 "(Landroid/media/MediaRecorder$OnErrorListener;)V",
123 m_mediaRecorder.callMethod<
void>(
"setOnInfoListener",
124 "(Landroid/media/MediaRecorder$OnInfoListener;)V",
126 mediaRecorders->insert(m_id,
this);
132 if (m_isVideoSourceSet || m_isAudioSourceSet)
136 mediaRecorders->remove(m_id);
141 m_mediaRecorder.callMethod<
void>(
"release");
147 auto methodId = env->GetMethodID(m_mediaRecorder.objectClass(),
"prepare",
"()V");
148 env->CallVoidMethod(m_mediaRecorder.object(), methodId);
150 if (env.checkAndClearExceptions())
157 m_mediaRecorder.callMethod<
void>(
"reset");
158 m_isAudioSourceSet =
false;
159 m_isVideoSourceSet =
false;
165 auto methodId = env->GetMethodID(m_mediaRecorder.objectClass(),
"start",
"()V");
166 env->CallVoidMethod(m_mediaRecorder.object(), methodId);
168 if (env.checkAndClearExceptions())
175 m_mediaRecorder.callMethod<
void>(
"stop");
180 m_mediaRecorder.callMethod<
void>(
"setAudioChannels",
"(I)V", numChannels);
186 m_mediaRecorder.callMethod<
void>(
"setAudioEncoder",
"(I)V",
int(encoder));
191 m_mediaRecorder.callMethod<
void>(
"setAudioEncodingBitRate",
"(I)V", bitRate);
196 m_mediaRecorder.callMethod<
void>(
"setAudioSamplingRate",
"(I)V", samplingRate);
201 if (!m_isAudioSourceSet) {
203 auto methodId = env->GetMethodID(m_mediaRecorder.objectClass(),
"setAudioSource",
"(I)V");
204 env->CallVoidMethod(m_mediaRecorder.object(), methodId, source);
205 if (!env.checkAndClearExceptions())
206 m_isAudioSourceSet =
true;
208 qCWarning(lcMediaRecorder) <<
"Audio source already set. Not setting a new source.";
214 return m_isAudioSourceSet;
219 const bool ret = QJniObject::callStaticMethod<jboolean>(
220 "org/qtproject/qt/android/multimedia/QtAudioDeviceManager",
222 "(Landroid/media/MediaRecorder;I)Z",
223 m_mediaRecorder.object(),
226 qCWarning(lcMediaRecorder) <<
"No default input device was set.";
233 QJniObject cam = camera->getCameraObject();
234 m_mediaRecorder.callMethod<
void>(
"setCamera",
"(Landroid/hardware/Camera;)V", cam.object());
239 m_mediaRecorder.callMethod<
void>(
"setVideoEncoder",
"(I)V",
int(encoder));
244 m_mediaRecorder.callMethod<
void>(
"setVideoEncodingBitRate",
"(I)V", bitRate);
249 m_mediaRecorder.callMethod<
void>(
"setVideoFrameRate",
"(I)V", rate);
254 m_mediaRecorder.callMethod<
void>(
"setVideoSize",
"(II)V", size.width(), size.height());
261 auto methodId = env->GetMethodID(m_mediaRecorder.objectClass(),
"setVideoSource",
"(I)V");
262 env->CallVoidMethod(m_mediaRecorder.object(), methodId, source);
264 if (!env.checkAndClearExceptions())
265 m_isVideoSourceSet =
true;
270 m_mediaRecorder.callMethod<
void>(
"setOrientationHint",
"(I)V", degrees);
276 auto methodId = env->GetMethodID(m_mediaRecorder.objectClass(),
"setOutputFormat",
"(I)V");
277 env->CallVoidMethod(m_mediaRecorder.object(), methodId, format);
279 if (!env.checkAndClearExceptions())
280 m_isAudioSourceSet =
true;
285 if (QUrl(path).scheme() == QLatin1String(
"content")) {
286 const QJniObject fileDescriptor = QJniObject::callStaticObjectMethod(
287 "org/qtproject/qt/android/QtNative",
288 "openFdObjectForContentUrl",
289 "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Ljava/io/FileDescriptor;",
290 QNativeInterface::QAndroidApplication::context().object(),
291 QJniObject::fromString(path).object(),
292 QJniObject::fromString(QLatin1String(
"rw")).object());
294 m_mediaRecorder.callMethod<
void>(
"setOutputFile",
295 "(Ljava/io/FileDescriptor;)V",
296 fileDescriptor.object());
298 m_mediaRecorder.callMethod<
void>(
"setOutputFile",
299 "(Ljava/lang/String;)V",
300 QJniObject::fromString(path).object());
306 m_mediaRecorder.callMethod<
void>(
"setPreviewDisplay",
307 "(Landroid/view/Surface;)V",
313 QJniObject surfaceHolder(holder->surfaceHolder());
314 QJniObject surface = surfaceHolder.callObjectMethod(
"getSurface",
315 "()Landroid/view/Surface;");
316 if (!surface.isValid())
319 m_mediaRecorder.callMethod<
void>(
"setPreviewDisplay",
320 "(Landroid/view/Surface;)V",
326 static const JNINativeMethod methods[] = {
327 {
"notifyError",
"(JII)V", (
void *)notifyError},
328 {
"notifyInfo",
"(JII)V", (
void *)notifyInfo}
331 const int size =
std::size(methods);
337#include "moc_androidmediarecorder_p.cpp"
int getValue(Field field) const
Q_GLOBAL_STATIC(QReadWriteLock, g_updateMutex)