We’ve built a series of productivity apps, with some surrounding screen recording for Android. Our team of young developers at AtlasV is always looking to challenge themselves for better algorithm, modularity, and adaptability in their source code.
In this sharing, we will discuss how we achieve the basic function of a media recorder by walking you through Android’s related source code, the thought process and steps.
Some of these techniques we apply in our source code are Android Inter-process Communication (Binder), Android Java Native Interface (JNI), strong pointer and weak pointer. For simplicity, we will now discuss these topics in detail in this article. If you want to know more about them, feel free to email us/ comment below. If coding and app development is not your cup of tea, share this with someone who will be interested!
Step 1: Initialisation
We will first load our desired so library using System.loadLibrary to get the libmedia_jni.so library ready. Afterwards, we use native_init() to enter the native layer. Basically, we use Java reflection through JNI to access some essential variables. These variables will then be passed to native layer and become native object for further reference. This is a common tactic for Android developers.
Step 2: Object Creation
We create an object called mediaRecorder = MediaRecorder(). We then enter JNI by analysing the native_setup method. In this step, some of the important moves are creating a new listener and passing it to MediaRecorder, and saving the objects created in native layer in the Java end.
We then perform constructor analysis for MediaRecorder.
The actual source code for the following methods can be very long. For better viewing experience, we will only walk you through some important methods we used in this step.
- setMediaRecorder: The addresses of objects are passed and saved in respective Java objects/variables for strong reference.
- getMediaRecorder: Addresses are converted to object pointers.
- setListener: A listener is set for MediaRecorder in Native layer for future reference
JNIMediaRecorderListener is an interesting object for callbacks. Read the code below to see how we achieve callbacks using different references and pointers.
// ref-counted object for callbacks
// Hold onto the MediaRecorder class for use in calling the static method
// Using a weak reference
// Using a strong or weak pointer here
Step 3: Configuration Parameters
In our programme, all the configuration information is configured based on the following flow:
• Configuring interface for MediaRecorder.java
• Same configuring interface for android_media_MediaRecorder.cpp
• Same configuring interface for mediarecorder.cpp
• Corresponding interface at the mediaServer end
Step 4: Preparation
After configuration, we can now call prepare method using the following code:
// Surface not set yet when recording starts
// Application may misbehave and preview surface becomes unavailable
// Call for parameters and error handling
Next, we will enter Native layer and use the prepare method in MediaRecorder. The code is as follows:
// Set audio encoder and source
// Video encoder
// Passing everything to MediaServer for programme execution
Step 5: Start
Firstly, we will call start method using the following code:
Secondly, we call start method in MediaRecorder from Native layer.
In summary, our source code works in three steps:
- Pass all parameters to the server end using Java methods and native methods.
- Maintain the state of MediaRecorder and check the parameters.
- Messages and data from the server end will be passed to app end using native methods, followed by Java methods.
That is the end of our source code sharing on our Media Recorder. We hope that our sharing on the app end process is educational for computing enthusiasts. If you are an expert and you see anything potential for improvement in our source code, please email us and we will appreciate your contribution enormously.
See you again in our upcoming source code sharing articles!
For media or partnership enquiries, please reach out to us here.