Android – 录制video时将麦克风静音

我正在用相机录制video,使用MediaRecorder类,按照类似于此的教程

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

而我想录音时,可以将麦克风静音/取消静音。 那可能怎么样?

我正在开始设置audio

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

但是如果我想在某个时候没有声音地录音呢?

Solutions Collecting From Web of "Android – 录制video时将麦克风静音"

试试下面的代码:

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

使用声音(麦克风)或无声音(麦克风)处理video时使用mediaRecorder中的AudioSource录制video剪辑,如果不需要声音,则不使用它。 使用mp4parsing器合并所有剪辑。

要使用AudioSource和AudioEncoder录制video以获取摄像机参数,请获取configuration文件并将参数设置为MediaRecorder

在这里我给出的代码可能有助于录制声音和没有声音的video(video录制可能strech,因为我已经从你的问题gven链接采取但静音和取消静音将正常工作)

活动

 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 } 

在录制开始之前需要每次创build新的MediaRecorder实例。 并在recodring停止后释放。

如果Sound(Mic)所需的video在MediaRecorder中添加Audio Source和Audio Encoder,如下所示。

 mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); 

由于我没有太多的时间,所以没有正确的代码来删除video扩展部分,但静音/取消静音将按您的问题正常工作。

对于录像请参考这个

让我知道,如果有的话

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

试试,把所有的声音都静音。