web-dev-qa-db-ja.com

Android-ビデオの録画中にマイクをミュートする

これに似たチュートリアルに従った後、MediaRecorderクラスを使用してカメラでビデオを録画しています

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

そして、録音中にマイクをミュート/ミュート解除できるようにしたいです。どうしてそれが可能ですか?

開始時に音源を設定しています

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

しかし、ある時点で音声なしで録音したい場合はどうなりますか?

10
Boldijar Paul

次のコードを試してください。

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);
}
2
dogood

サウンドあり(マイク)またはサウンドなし(マイク)のビデオを処理するには、オーディオソースを使用してmediaRecorderにビデオクリップを記録し、サウンドが不要な場合はオーディオソースを使用しないでください。 mp4パーサー を使用してすべてのクリップをマージします。

カメラパラメーターを取得するために必要なAudioSourceおよびAudioEncoderを使用してビデオを録画するには、プロファイルをフェッチし、パラメーターをMediaRecorderに設定します。

ここで私は音声付きと音声なしでビデオを録画するのに役立つかもしれないコードを与えました(ビデオ録画は私が与えられたリンクから取ったように伸びるかもしれませんあなたの質問しかし、ミュートとミュート解除はうまくいきます)

アクティビティ

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;
    }
}

レイアウト

<?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
}

記録を開始する前に、毎回新しいMediaRecorderインスタンスを作成する必要があります。そして、回収が停止した後に解放します。

Sound(Mic)でビデオが必要な場合は、以下のようにMediaRecorderにオーディオソースとオーディオエンコーダーを追加します。

mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);

私はあまり時間がないので、ビデオストレッチ部分を削除するための適切なコードを作成していませんが、ミュート/ミュート解除はあなたの質問に従ってうまく機能します。

ビデオ録画については参照してください this

どちらかといえば教えてください

2
user1140237
((AudioManager)context.getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_SYSTEM,true);

すべての音をミュートしてみてください。

0
Rishabh Mahatha