Android - 录制视频时将麦克风静音
Android - mute microphone while recording video
我正在使用 MediaRecorder class 用相机录制视频,然后学习了与此类似的教程
而且我希望在录音时能够将麦克风静音/取消静音。
怎么可能?
我在开始时设置音频源
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
但是如果我想在某个时候录制无声怎么办?
((AudioManager)context.getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_SYSTEM,true);
试试,把所有声音都静音。
试试下面的代码:
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);
}
要处理有声(麦克风)或无声(麦克风)的视频,请在 mediaRecorder 中使用 AudioSource 录制视频剪辑,如果不需要声音则不使用它。
使用 mp4 parser 合并所有剪辑。
要使用 AudioSource 和 AudioEncoder 录制视频,需要获取相机参数,获取配置文件并将参数设置为 MediaRecorder。
这里我给出了可能有助于录制有声和无声视频的代码(我从 link 中获取的视频录制可能会拉伸在你的问题中被 gven 但是静音和取消静音可以正常工作)
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;
}
}
布局
<?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实例。
并在录制停止后释放。
如果视频需要声音(麦克风),请在 MediaRecorder 中添加音频源和音频编码器,如下所示。
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
因为我没有太多时间,所以我没有编写适当的代码来删除视频拉伸部分,但 mute/unmute 根据你的问题可以正常工作。
视频录制请参考this
有什么事请告诉我
我正在使用 MediaRecorder class 用相机录制视频,然后学习了与此类似的教程
而且我希望在录音时能够将麦克风静音/取消静音。 怎么可能?
我在开始时设置音频源
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
但是如果我想在某个时候录制无声怎么办?
((AudioManager)context.getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_SYSTEM,true);
试试,把所有声音都静音。
试试下面的代码:
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);
}
要处理有声(麦克风)或无声(麦克风)的视频,请在 mediaRecorder 中使用 AudioSource 录制视频剪辑,如果不需要声音则不使用它。 使用 mp4 parser 合并所有剪辑。
要使用 AudioSource 和 AudioEncoder 录制视频,需要获取相机参数,获取配置文件并将参数设置为 MediaRecorder。
这里我给出了可能有助于录制有声和无声视频的代码(我从 link 中获取的视频录制可能会拉伸在你的问题中被 gven 但是静音和取消静音可以正常工作)
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;
}
}
布局
<?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实例。 并在录制停止后释放。
如果视频需要声音(麦克风),请在 MediaRecorder 中添加音频源和音频编码器,如下所示。
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
因为我没有太多时间,所以我没有编写适当的代码来删除视频拉伸部分,但 mute/unmute 根据你的问题可以正常工作。
视频录制请参考this
有什么事请告诉我