【问题标题】:android mute camera shutter sound?android静音相机快门声音?
【发布时间】:2013-01-06 18:14:02
【问题描述】:

我正在使用这个

camera.takePicture(null, rawCallback, jpegCallback);

但在某些设备上,当相机拍摄图像时会发出声音。

请任何人帮忙,我怎样才能使相机快门声音静音?

【问题讨论】:

  • 我认为这有点不可撤销。至少在美国,立法强制要求所有相机设备都发出快门声。 AFAIK 在其他一些国家也是如此。
  • harism 在某些设备中会导致问题,我在 nexus、s2、nexus 表中测试过所有设备静默捕获,但 htc desicer 和某些设备会导致问题。
  • 使用静音文件的方法是否可行?

标签: android android-camera


【解决方案1】:

您可以从 4.2 开始以编程方式将其关闭:

Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(id, info);
if (info.canDisableShutterSound) {
    mCamera.enableShutterSound(false);
}

【讨论】:

    【解决方案2】:

    要静音,请在捕获图像之前输入此代码

     AudioManager mgr = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
     mgr.setStreamMute(AudioManager.STREAM_SYSTEM, true);
     camera.takePicture(null, rawCallback, jpegCallback);
    

    1秒后它会通过输入以下代码取消静音:

     final Handler handler = new Handler();
     Timer t = new Timer();
     t.schedule(new TimerTask() {
        public void run() {
            handler.post(new Runnable() {
                public void run() {
                AudioManager mgr = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
                mgr.setStreamMute(AudioManager.STREAM_SYSTEM, false);
                        }
                    });
                }
        }, 1000); 
    

    【讨论】:

    • 既然可以在处理程序上调用 postDelayed,为什么还要使用计时器?
    【解决方案3】:

    在点击按钮之前使用下面两行

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

    这两个在图像被捕获后的孤独:

    AudioManager mgr = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
    mgr.setStreamMute(AudioManager.STREAM_SYSTEM, false);
    

    我只知道这个解决方案,我个人在我的应用程序中使用过它

    【讨论】:

    • 感谢它的工作,但在 1 秒后取消静音,因此在捕获时不会发出声音。
    【解决方案4】:

    正如 harism 所提到的,这在某些设备上是不可能的,因为在某些市场(例如日本)有法律要求,要求拍照总是会产生可听见的快门声。

    用于这些类型声音的流类型是STREAM_SYSTEM_ENFORCED,并且有一个只读系统属性决定您是否可以将此类流静音。

    【讨论】:

    • 感谢 micheal 和 harism,它通过这种方式解决了静音问题:AudioManager mgr =(AudioManager)context.getSystemService(context.AUDIO_SERVICE); mgr.setStreamMute(AudioManager.STREAM_SYSTEM, true);取消静音:最终处理程序处理程序=新处理程序();定时器 t = new Timer(); t.schedule(new TimerTask() { public void run() { handler.post(new Runnable() { public void run() { AudioManager mgr = (AudioManager)context.getSystemService(context.AUDIO_SERVICE); mgr.setStreamMute(AudioManager .STREAM_SYSTEM, false); } }); } }, 1000);
    • @PankajJolapara 您可以发布自己的解决方案作为答案并接受解决您问题的答案。这可以帮助任何有同样问题的人。 :)
    • 建议的解决方案不适用于某些设备,因为它们被设置为始终将快门声音传送到扬声器并且不允许静音。同样,这在很大程度上取决于设备的销售市场。
    【解决方案5】:

    好吧,所有这些解决方案都很好,但我更喜欢在之前将音量设置为 0(不仅是系统,因为某些设备使用其他流然后是系统和/或并非所有流都包括系统):

    这样的事情会完美无缺:

    Camera mCamera = null;
    
    function takePicture() {
       storeSoundSettings();
       setMuteAll(true);
       // init camera and such.
       Camera.CameraInfo info = new Camera.CameraInfo();
       Camera.getCameraInfo(IdOfCameraBackOrFront, info);
           if (info.canDisableShutterSound) {
               camera.enableShutterSound(false);
           }
       setMuteAll(false);
       recoverSoundSettings();
    }
    

    并像这样存储、恢复和设置静音:

    int[] streams = new int[]{
                    AudioManager.STREAM_ALARM,
                    AudioManager.STREAM_DTMF,
                    AudioManager.STREAM_MUSIC,
                    AudioManager.STREAM_NOTIFICATION,
                    AudioManager.STREAM_RING,
                    AudioManager.STREAM_SYSTEM,
                    AudioManager.STREAM_VOICE_CALL};
    JSONObject json;
    AudioManager manager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    
    public void storeSoundSettings() {
            json = new JSONObject();
            json.put("mode", manager.getMode());
            json.put("ringermode", manager.getRingerMode());
    
            for (int stream : streams) {
                json.put("stream_" + stream, manager.getStreamVolume(stream));
             }
    }
    
    
    public void recoverSoundSettings() {
            json = new JSONObject(readString("last_audio_setting", null));
            manager.setMode(json.getInt("mode"));
            manager.setRingerMode(json.getInt("ringermode"));
    
            for (int stream : streams) {
                manager.setStreamVolume(stream, json.getInt("stream_" + stream), AudioManager.FLAG_ALLOW_RINGER_MODES);
    }
    
    public void setMuteAll(boolean mute) {
    
        for (int stream : streams) {
            manager.setStreamMute(stream, mute);
            if (mute) {
                manager.setStreamVolume(stream, 100, AudioManager.FLAG_ALLOW_RINGER_MODES);
            } else {
                manager.setStreamVolume(stream, 0, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
            }
        }
    }
    

    不要忘记捕获异常。我删除了它们以便更好地突出显示。

    【讨论】:

    • 你错过了 setStreamVolume,它应该被颠倒
    猜你喜欢
    • 2012-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-20
    • 1970-01-01
    相关资源
    最近更新 更多