Skip to content

Commit

Permalink
Audio recording is optional
Browse files Browse the repository at this point in the history
  • Loading branch information
yrom committed Jan 9, 2018
1 parent 11e0c8b commit 17abc38
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 65 deletions.
46 changes: 34 additions & 12 deletions app/src/main/java/net/yrom/screenrecorder/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import android.widget.Button;
import android.widget.SpinnerAdapter;
import android.widget.Toast;
import android.widget.ToggleButton;

import net.yrom.screenrecorder.view.NamedSpinner;

Expand All @@ -67,6 +68,7 @@ public class MainActivity extends Activity {
// members below will be initialized in onCreate()
private MediaProjectionManager mMediaProjectionManager;
private Button mButton;
private ToggleButton mAudioToggle;
private NamedSpinner mVieoResolution;
private NamedSpinner mVideoFramerate;
private NamedSpinner mIFrameInterval;
Expand Down Expand Up @@ -113,6 +115,9 @@ protected void onCreate(Bundle savedInstanceState) {
mAudioCodec.setAdapter(codecsAdapter);
restoreSelections(mAudioCodec, mAudioChannelCount);
});
mAudioToggle.setChecked(
PreferenceManager.getDefaultSharedPreferences(getApplicationContext())
.getBoolean(getResources().getResourceEntryName(mAudioToggle.getId()), true));
}

@Override
Expand Down Expand Up @@ -142,8 +147,8 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
}

VideoEncodeConfig video = createVideoConfig();
AudioEncodeConfig audio = createAudioConfig();
if (video == null || audio == null) {
AudioEncodeConfig audio = createAudioConfig(); // audio can be null
if (video == null) {
toast("Create ScreenRecorder failure");
mediaProjection.stop();
return;
Expand Down Expand Up @@ -207,6 +212,7 @@ public void onRecording(long presentationTimeUs) {
}

private AudioEncodeConfig createAudioConfig() {
if (!mAudioToggle.isChecked()) return null;
String codec = getSelectedAudioCodec();
if (codec == null) {
return null;
Expand Down Expand Up @@ -246,11 +252,14 @@ private static File getSavingDir() {
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_PERMISSIONS) {
// we request 2 permissions
if (grantResults.length == 2
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
int granted = PackageManager.PERMISSION_GRANTED;
for (int r : grantResults) {
granted |= r;
}
if (granted == PackageManager.PERMISSION_GRANTED) {
startCaptureIntent();
} else {
toast("No Permission!");
}
}
}
Expand Down Expand Up @@ -285,6 +294,12 @@ private void bindViews() {
mAudioProfile = findViewById(R.id.aac_profile);
mAudioChannelCount = findViewById(R.id.audio_channel_count);

mAudioToggle = findViewById(R.id.with_audio);
mAudioToggle.setOnCheckedChangeListener((buttonView, isChecked) ->
findViewById(R.id.audio_format_chooser)
.setVisibility(isChecked ? View.VISIBLE : View.GONE)
);

if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
mOrientation.setSelectedPosition(1);
}
Expand Down Expand Up @@ -351,16 +366,22 @@ private void cancelRecorder() {

@TargetApi(M)
private void requestPermissions() {
if (!shouldShowRequestPermissionRationale(WRITE_EXTERNAL_STORAGE)
&& !shouldShowRequestPermissionRationale(RECORD_AUDIO)) {
requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE, RECORD_AUDIO}, REQUEST_PERMISSIONS);
String[] permissions = mAudioToggle.isChecked()
? new String[]{WRITE_EXTERNAL_STORAGE, RECORD_AUDIO}
: new String[]{WRITE_EXTERNAL_STORAGE};
boolean showRationale = false;
for (String perm : permissions) {
showRationale |= shouldShowRequestPermissionRationale(perm);
}
if (!showRationale) {
requestPermissions(permissions, REQUEST_PERMISSIONS);
return;
}
new AlertDialog.Builder(this)
.setMessage("Using your mic to record audio and your sd card to save video file")
.setCancelable(false)
.setPositiveButton(android.R.string.ok, (dialog, which) ->
requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE, RECORD_AUDIO}, REQUEST_PERMISSIONS))
requestPermissions(permissions, REQUEST_PERMISSIONS))
.setNegativeButton(android.R.string.cancel, null)
.create()
.show();
Expand All @@ -369,7 +390,7 @@ private void requestPermissions() {
private boolean hasPermissions() {
PackageManager pm = getPackageManager();
String packageName = getPackageName();
int granted = pm.checkPermission(RECORD_AUDIO, packageName)
int granted = (mAudioToggle.isChecked() ? pm.checkPermission(RECORD_AUDIO, packageName) : PackageManager.PERMISSION_GRANTED)
| pm.checkPermission(WRITE_EXTERNAL_STORAGE, packageName);
return granted == PackageManager.PERMISSION_GRANTED;
}
Expand Down Expand Up @@ -787,6 +808,7 @@ private void saveSelections() {
}) {
saveSelectionToPreferences(edit, spinner);
}
edit.putBoolean(getResources().getResourceEntryName(mAudioToggle.getId()), mAudioToggle.isChecked());
edit.apply();
}

Expand Down Expand Up @@ -817,7 +839,7 @@ public void onReceive(Context context, Intent intent) {
if (ACTION_STOP.equals(intent.getAction())) {
stopRecorder();
}
Toast.makeText(context, "Recorder stopped!", Toast.LENGTH_SHORT).show();
Toast.makeText(context, "Recorder stopped!\n Saved file " + file, Toast.LENGTH_LONG).show();
StrictMode.VmPolicy vmPolicy = StrictMode.getVmPolicy();
try {
// disable detecting FileUriExposure on public file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ private Notification.Builder getBuilder() {
@TargetApi(O)
private void createNotificationChannel() {
NotificationChannel channel =
new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
channel.setShowBadge(false);
getNotificationManager().createNotificationChannel(channel);
}
Expand Down
21 changes: 13 additions & 8 deletions app/src/main/java/net/yrom/screenrecorder/ScreenRecorder.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public ScreenRecorder(VideoEncodeConfig video,
mMediaProjection = mp;
mDstPath = dstPath;
mVideoEncoder = new VideoEncoder(video);
mAudioEncoder = new MicRecorder(audio);
mAudioEncoder = audio == null ? null : new MicRecorder(audio);

}

Expand Down Expand Up @@ -331,12 +331,13 @@ private void resetAudioOutputFormat(MediaFormat newFormat) {
}

private void startMuxerIfReady() {
if (mMuxerStarted || mVideoOutputFormat == null || mAudioOutputFormat == null) {
if (mMuxerStarted || mVideoOutputFormat == null
|| (mAudioEncoder != null && mAudioOutputFormat == null)) {
return;
}

mVideoTrackIndex = mMuxer.addTrack(mVideoOutputFormat);
mAudioTrackIndex = mMuxer.addTrack(mAudioOutputFormat);
mAudioTrackIndex = mAudioEncoder == null ? INVALID_INDEX : mMuxer.addTrack(mAudioOutputFormat);
mMuxer.start();
mMuxerStarted = true;
if (VERBOSE) Log.i(TAG, "Started media muxer, videoIndex=" + mVideoTrackIndex);
Expand All @@ -349,9 +350,11 @@ private void startMuxerIfReady() {
int index = mPendingVideoEncoderBufferIndices.poll();
muxVideo(index, info);
}
while ((info = mPendingAudioEncoderBufferInfos.poll()) != null) {
int index = mPendingAudioEncoderBufferIndices.poll();
muxAudio(index, info);
if (mAudioEncoder != null) {
while ((info = mPendingAudioEncoderBufferInfos.poll()) != null) {
int index = mPendingAudioEncoderBufferIndices.poll();
muxAudio(index, info);
}
}
if (VERBOSE) Log.i(TAG, "Mux pending video output buffers done.");
}
Expand Down Expand Up @@ -390,6 +393,8 @@ public void onOutputFormatChanged(BaseEncoder codec, MediaFormat format) {
}

private void prepareAudioEncoder() throws IOException {
final MicRecorder micRecorder = mAudioEncoder;
if (micRecorder == null) return;
AudioEncoder.Callback callback = new AudioEncoder.Callback() {
boolean ranIntoError = false;

Expand Down Expand Up @@ -422,8 +427,8 @@ public void onError(Encoder codec, Exception e) {


};
mAudioEncoder.setCallback(callback);
mAudioEncoder.prepare();
micRecorder.setCallback(callback);
micRecorder.prepare();
}

private void signalStop(boolean stopWithEOS) {
Expand Down
104 changes: 60 additions & 44 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
Expand Down Expand Up @@ -79,57 +79,73 @@
android:layout_marginTop="8dp"
android:entries="@array/orientations" />

<TextView
style="?android:attr/titleTextStyle"
<LinearLayout
android:id="@+id/audio_format_chooser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Audio Encode Config (H.264 AAC)" />

<net.yrom.screenrecorder.view.NamedSpinner
android:id="@+id/audio_codec"
android:name="Audio Encoder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" />

<net.yrom.screenrecorder.view.NamedSpinner
android:id="@+id/audio_channel_count"
android:name="Channels"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:entries="@array/audio_channels" />

<net.yrom.screenrecorder.view.NamedSpinner
android:id="@+id/sample_rate"
android:name="Sample Rate (HZ)"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" />

<net.yrom.screenrecorder.view.NamedSpinner
android:id="@+id/audio_bitrate"
android:name="Bitrate (kbps)"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" />

<net.yrom.screenrecorder.view.NamedSpinner
android:id="@+id/aac_profile"
android:name="AAC Profile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" />

android:orientation="vertical">

<TextView
style="?android:attr/titleTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Audio Encode Config (H.264 AAC)" />

<net.yrom.screenrecorder.view.NamedSpinner
android:id="@+id/audio_codec"
android:name="Audio Encoder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" />

<net.yrom.screenrecorder.view.NamedSpinner
android:id="@+id/audio_channel_count"
android:name="Channels"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:entries="@array/audio_channels" />

<net.yrom.screenrecorder.view.NamedSpinner
android:id="@+id/sample_rate"
android:name="Sample Rate (HZ)"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" />

<net.yrom.screenrecorder.view.NamedSpinner
android:id="@+id/audio_bitrate"
android:name="Bitrate (kbps)"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" />

<net.yrom.screenrecorder.view.NamedSpinner
android:id="@+id/aac_profile"
android:name="AAC Profile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" />
</LinearLayout>
</LinearLayout>
</ScrollView>

<ToggleButton
android:id="@+id/with_audio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/record_button"
android:layout_alignParentEnd="true"
android:checked="true"
android:textOff="Without Audio"
android:textOn="With Audio" />

<Button
android:id="@+id/record_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:text="Start Recorder" />

</FrameLayout>
</RelativeLayout>

0 comments on commit 17abc38

Please sign in to comment.