2016-12-12 118 views
10

我記錄與攝像機的視頻,使用MediaRecorder類,下面的教程類同此的Android - 靜音麥克風錄製視頻時

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

後,我要在錄音,爲了能夠使麥克風靜音/取消靜音。 這可能怎麼樣?

我在某些時候設置音頻源在啓動

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

但是,如果我想記錄沒有什麼聲音?

+0

不AudioManager.setMicrophoneMute(布爾)爲你工作? – Gil

+0

@Gil no。不注意注4。 –

+0

@BoldijarPaul **在某些時候沒有聲音記錄?**所以你想要第一個5秒鐘的聲音從6到10靜音視頻? – user1140237

回答

2

試試下面的代碼:

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

這對我有效。在Samsung Note 4&Htc M8上測試 –

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

試試,將所有聲音靜音。

2

有聲(MIC)或mediaRecorder用的AudioSource無聲音(麥克風)錄製視頻剪輯,視頻處理,沒有它,如果不要所需的聲音。 使用mp4 parser合併所有剪輯。

要使用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實例。 並在recodring停止後釋放。

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

mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 

mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); 

,因爲我已經沒有太多的時間,所以不HVE進行適當的代碼刪除視頻streching一部分,但靜音/取消靜音做工精細,按您的問題。

視頻錄製,請參考,this

讓我知道,如果有什麼