Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - mute microphone while recording video

I'm recording a video with the camera, using the MediaRecorder class, after following a tutorial similiar to this

http://androidcookbook.com/Recipe.seam;jsessionid=40151FCD26222877E151C3EEFB406EED?recipeId=1375&recipeFrom=ViewTOC

And I want while recording, to be able to mute / unmute the microphone. How's that possible?

I'm setting the audio source at start

 mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

But what if I want to record without sound at some point?

like image 682
Boldijar Paul Avatar asked Dec 12 '16 14:12

Boldijar Paul


People also ask

How do I mute my microphone on Android?

If you have an Android phone, you can mute your phone from the call screen. Your call screen has different buttons including a mute button (circled below). It is a microphone with a slash line through it.

Is there a way to record video without sound Android?

Click on the gear icon on your screen to find the "Settings" menu. Step 3. Tap the "Audio source" option and select "No audio" to record your screen without sound.


2 Answers

Try the following code:

private void setMicMuted(boolean state){
    AudioManager myAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);

    // get the working mode and keep it
    int workingAudioMode = myAudioManager.getMode();

    myAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);

    // change mic state only if needed
    if (myAudioManager.isMicrophoneMute() != state) {
        myAudioManager.setMicrophoneMute(state);
    }

    // set back the original working mode
    myAudioManager.setMode(workingAudioMode);
}
like image 189
dogood Avatar answered Oct 10 '22 15:10

dogood


To handle videos with Sound(Mic) or without sound (Mic) record video clips with AudioSource in mediaRecorder and without it if dont required sound. Merge all the clips using mp4 parser .

To record video with AudioSource and AudioEncoder its required to get camera parameters , fetch the profile and set parameters to MediaRecorder.

Here I've given code which may help to record video with sound and without sound (Video recording may strech as I've taken from the link which is gven in your question But mute and unmute will work fine)

Activity

import android.app.Activity;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import android.widget.ToggleButton;

import com.googlecode.mp4parser.BasicContainer;
import com.googlecode.mp4parser.authoring.Movie;
import com.googlecode.mp4parser.authoring.Track;
import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator;
import com.googlecode.mp4parser.authoring.tracks.AppendTrack;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class MediaRecorderRecipe extends Activity implements SurfaceHolder.Callback {
    private MediaRecorder mMediaRecorder;
    private Camera mCamera;
    private SurfaceView mSurfaceView;
    private SurfaceHolder mHolder;
    private View mToggleButton;
    private ToggleButton togglemute;
    private boolean mInitSuccesful;
    private File videoDirectory;
    private Button btn;
    private File mainDirectory, clipsDir, mergedDir;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test);
        videoDirectory = new File(Environment.getExternalStorageDirectory() + File.separator + "MuteUnMuteVideos");
        clipsDir = new File(videoDirectory.getAbsolutePath(), "Clips");
        clipsDir.mkdirs();
        mergedDir = new File(videoDirectory.getAbsolutePath(), "FinalMerged");
        mergedDir.mkdirs();
        deleteFilesDir(clipsDir.getAbsolutePath());
        // we shall take the video in landscape orientation

        mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
        mHolder = mSurfaceView.getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        togglemute = (ToggleButton) findViewById(R.id.togglemute);
        mToggleButton = (ToggleButton) findViewById(R.id.toggleRecordingButton);
        btn = (Button) findViewById(R.id.doneRecording);
        mToggleButton.setOnClickListener(new OnClickListener() {
            @Override
            // toggle video recording
            public void onClick(View v) {

                if (((ToggleButton) v).isChecked()) {
                    try {
                        if (!mInitSuccesful)
                            initRecorder(mHolder.getSurface());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    mMediaRecorder.start();
                    togglemute.setEnabled(false);
                    btn.setEnabled(false);
                } else {
                    mMediaRecorder.stop();
                    mMediaRecorder.reset();
                    togglemute.setEnabled(true);
                    btn.setEnabled(true);
                    mInitSuccesful = false;

                }
            }
        });
        btn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                new MergeVideosTask(MediaRecorderRecipe.this).execute();
            }
        });

    }

    private File outputFile;

    class MergeVideosTask extends AsyncTask {
        Activity activity;

        public MergeVideosTask(Activity activity) {
            this.activity = activity;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            /**
             * Show Progressbar
             */
        }

        @Override
        protected Object doInBackground(Object[] objects) {
            mergeVideos();
            return null;
        }

        @Override
        protected void onPostExecute(Object o) {
            super.onPostExecute(o);
            /**
             * Dismiss Progress
             */
            Toast.makeText(MediaRecorderRecipe.this, "Save Video : " + outputFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
        }

        public void mergeVideos() {
            try {
                File parentDir = new File(clipsDir.getAbsolutePath());
                List<String> videosPathList = new ArrayList<>();
                File[] files = parentDir.listFiles();
                for (File file : files) {
                    videosPathList.add(file.getAbsolutePath());
                }

                List<Movie> inMovies = new ArrayList<>();
                for (int i = 0; i < videosPathList.size(); i++) {
                    String filePath = videosPathList.get(i);
                    try {
                        Movie movie = MovieCreator.build(filePath);
                        if (movie != null)
                            inMovies.add(movie);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                List<Track> videoTracks = new LinkedList<Track>();
                List<Track> audioTracks = new LinkedList<Track>();
                for (Movie m : inMovies) {
                    for (Track t : m.getTracks()) {
                        try {
                            if (t.getHandler().equals("soun")) {
                                audioTracks.add(t);
                            }
                            if (t.getHandler().equals("vide")) {
                                videoTracks.add(t);
                            }
                        } catch (Exception e) {

                        }
                    }
                }
                Movie result = new Movie();
                if (audioTracks.size() > 0) {
                    result.addTrack(new AppendTrack(audioTracks.toArray(new Track[audioTracks.size()])));
                }
                if (videoTracks.size() > 0) {
                    result.addTrack(new AppendTrack(videoTracks.toArray(new Track[videoTracks.size()])));
                }
                BasicContainer out = (BasicContainer) new DefaultMp4Builder().build(result);
                File f = null;
                String finalVideoPath;
                try {
                    f = setUpVideoFile(mergedDir.getAbsolutePath());
                    finalVideoPath = f.getAbsolutePath();

                } catch (IOException e) {
                    e.printStackTrace();
                    f = null;
                    finalVideoPath = null;
                }
                WritableByteChannel fc = new RandomAccessFile(finalVideoPath, "rw").getChannel();
                out.writeContainer(fc);
                fc.close();
                outputFile = new File(finalVideoPath);
//                deleteFilesDir(getExternalFilesDir(null).getAbsolutePath());

            } catch (Exception e) {
                e.printStackTrace();

                finish();
            }
        }

        File setUpVideoFile(String directory) throws IOException {
            File videoFile = null;
            if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
                File storageDir = new File(directory);
                if (storageDir != null) {
                    if (!storageDir.mkdirs()) {
                        if (!storageDir.exists()) {
                            Log.d("CameraSample", "failed to create directory");
                            return null;
                        }
                    }
                }
                videoFile = File.createTempFile("video_" + System.currentTimeMillis() + "_", ".mp4", storageDir);
            }
            return videoFile;
        }


    }

    private void deleteFilesDir(String path) {
        File dir = new File(path);
        if (dir.isDirectory()) {
            String[] children = dir.list();
            for (int i = 0; i < children.length; i++) {
                new File(dir, children[i]).delete();
            }
        }
    }

    /* Init the MediaRecorder, the order the methods are called is vital to
     * its correct functioning */
    private void initRecorder(Surface surface) throws IOException {
        // It is very important to unlock the camera before doing setCamera
        // or it will results in a black preview
        if (mCamera == null) {
            mCamera = Camera.open();
        }
        if (mMediaRecorder != null) {
            mMediaRecorder.reset();   // clear recorder configuration
            mMediaRecorder.release(); // release the recorder object
            mMediaRecorder = null;
        }
        mMediaRecorder = new MediaRecorder();
        mMediaRecorder.setPreviewDisplay(surface);


        CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_720P);
        Camera.Parameters parameters = mCamera.getParameters();
        List<Camera.Size> mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
        List<Camera.Size> mSupportedVideoSizes = parameters.getSupportedVideoSizes();
        Camera.Size optimalSize = getOptimalVideoSize(mSupportedVideoSizes,
                mSupportedPreviewSizes, profile.videoFrameWidth, profile.videoFrameHeight);
        /**
         * Prepare video with proper size. Preview and video size
         */
        profile.videoFrameWidth = optimalSize.width;
        profile.videoFrameHeight = optimalSize.height;
        mCamera.unlock();
        mMediaRecorder.setCamera(mCamera);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        if (!togglemute.isChecked()) {
            /**
             * Add Audio Source if video required with sound
             */
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

        }
        mMediaRecorder.setOutputFormat(profile.fileFormat);
        mMediaRecorder.setVideoEncoder(profile.videoCodec);
        if (!togglemute.isChecked()) {
            /**
             * Add Audio Encoder if video required with sound
             */
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
        }
        mMediaRecorder.setVideoEncodingBitRate(profile.videoBitRate);
        mMediaRecorder.setVideoFrameRate(profile.videoFrameRate);
        mMediaRecorder.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
        File file = new File(clipsDir.getAbsolutePath(), System.currentTimeMillis() + ".mp4");
        // "touch" the file
        if (!file.exists()) {
            File parent = file.getParentFile();
            if (parent != null)
                if (!parent.exists())
                    if (!parent.mkdirs())
                        throw new IOException("Cannot create " +
                                "parent directories for file: " + file);

            file.createNewFile();
        }

        mMediaRecorder.setOutputFile(file.getAbsolutePath());
        mMediaRecorder.setPreviewDisplay(surface);

        try {
            mMediaRecorder.prepare();
        } catch (IllegalStateException e) {
            // This is thrown if the previous calls are not called with the
            // proper order
            e.printStackTrace();
        }

        mInitSuccesful = true;
    }

    public static Camera.Size getOptimalVideoSize(List<Camera.Size> supportedVideoSizes,
                                                  List<Camera.Size> previewSizes, int w, int h) {
        // Use a very small tolerance because we want an exact match.
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio = (double) w / h;

        // Supported video sizes list might be null, it means that we are allowed to use the preview
        // sizes
        List<Camera.Size> videoSizes;
        if (supportedVideoSizes != null) {
            videoSizes = supportedVideoSizes;
        } else {
            videoSizes = previewSizes;
        }
        Camera.Size optimalSize = null;

        // Start with max value and refine as we iterate over available video sizes. This is the
        // minimum difference between view and camera height.
        double minDiff = Double.MAX_VALUE;

        // Target view height
        int targetHeight = h;

        for (Camera.Size size : videoSizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                continue;
            if (Math.abs(size.height - targetHeight) < minDiff && previewSizes.contains(size)) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Camera.Size size : videoSizes) {
                if (Math.abs(size.height - targetHeight) < minDiff && previewSizes.contains(size)) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            if (!mInitSuccesful)
                initRecorder(mHolder.getSurface());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        shutdown();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
                               int height) {
    }


    private void shutdown() {
        // Release MediaRecorder and especially the Camera as it's a shared
        // object that can be used by other applications
        mMediaRecorder.reset();
        mMediaRecorder.release();
        mCamera.release();

        // once the objects have been released they can't be reused
        mMediaRecorder = null;
        mCamera = null;
    }
}

Layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <ToggleButton
        android:id="@+id/toggleRecordingButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textOff="Start Recording"
        android:textOn="Stop Recording" />
    <ToggleButton
        android:id="@+id/togglemute"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textOff="Mute Recording"
        android:textOn="UnMute Recording" />

    <Button
        android:id="@+id/doneRecording"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Finish Recording" />

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <SurfaceView
            android:id="@+id/surfaceView"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"></SurfaceView>

    </FrameLayout>
</LinearLayout>

build.gradle

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
    compile 'com.googlecode.mp4parser:isoparser:1.1.21' ///To MergeVideos
}

Need to create every time new MediaRecorder instance before recording start. And release after recodring stops.

If video required with Sound(Mic) add Audio Source and Audio Encoder in MediaRecorder as given below.

mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);

As i've not much time so hve not make proper code to remove video streching part but mute/unmute will work fine as per your question.

for video recording please refere this

Let me know if anything

like image 26
user1140237 Avatar answered Oct 10 '22 16:10

user1140237