草庐IT

android - MediaRecorder 在录制第二个音频剪辑时崩溃

coder 2023-12-15 原文

我正在尝试使用 MediaRecorder 录制音频剪辑,但是当我开始、停止和重新开始时,我的 Logcat 中不断出现这些错误;该 Activity 也将关闭:

INFO/DEBUG(1285): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
INFO/DEBUG(1285): Build fingerprint: 'LGE/thunderg/thunderg/thunderg:2.2.1/FRG83/eng.nikech.choi.20110126.134422:user/release-keys'
INFO/DEBUG(1285): signal 11 (SIGSEGV), fault addr 00000010
INFO/DEBUG(1285):  r0 00000000  r1 00000000  r2 a930cc98  r3 00000001
……
INFO/DEBUG(1285):          #00  pc 00033c28  /system/lib/libmedia.so
INFO/DEBUG(1285):          #01  pc 0000780e  /system/lib/libmedia_jni.so
……
INFO/DEBUG(1285): code around pc:
INFO/DEBUG(1285): a9033c08 2001e001 1c1861a0 46c0bd70 00029a58 
……
INFO/DEBUG(1285): code around lr:
INFO/DEBUG(1285): a93077f0 f7ffb510 bd10ffcf b082b570 ae011c05 
……
INFO/DEBUG(1285): stack:
INFO/DEBUG(1285):     bef054d0  00000001 
……

录制了一个音频 fragment ,可以在电脑上播放,但是如果我想再录制一个,就会出现上述情况。我已经在 list 中请求许可:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>

我使用了 Ben McCann 的这段代码:

import java.io.File;
import java.io.IOException;

import android.media.MediaRecorder;
import android.os.Environment;

/**
 * @author <a href="http://www.benmccann.com">Ben McCann</a>
 */

public class AudioRecorder {

  final MediaRecorder recorder = new MediaRecorder();
  final String path;

  /**
   * Creates a new audio recording at the given path (relative to root of SD card).
   */
  public AudioRecorder(String path) {
    this.path = sanitizePath(path);
  }

  private String sanitizePath(String path) {
    if (!path.startsWith("/")) {
      path = "/" + path;
    }
    if (!path.contains(".")) {
      path += ".3gp";
    }
    return Environment.getExternalStorageDirectory().getAbsolutePath() + path;
  }

  /**
   * Starts a new recording.
   */
  public void start() throws IOException {
    String state = android.os.Environment.getExternalStorageState();
    if(!state.equals(android.os.Environment.MEDIA_MOUNTED))  {
        throw new IOException("SD Card is not mounted.  It is " + state + ".");
    }

    // make sure the directory we plan to store the recording in exists
    File directory = new File(path).getParentFile();
    if (!directory.exists() && !directory.mkdirs()) {
      throw new IOException("Path to file could not be created.");
    }

    recorder.reset();
    System.out.println("reset");
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    System.out.println("setAudioSource");
    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    System.out.println("setOutputFormat");
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    System.out.println("setAudioEncoder");
    recorder.setOutputFile(path);
    System.out.println("setOutputFile");
    recorder.prepare();
    System.out.println("prepare");
    recorder.start();
    System.out.println("start");
  }

  /**
   * Stops a recording that has been previously started.
   */
  public void stop() throws IOException {
    recorder.stop();
    System.out.println("stopped");
    recorder.release();
    System.out.println("released");
  }

}

我的代码:

import java.io.IOException;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class TestActivity extends Activity implements OnClickListener {

    private final String TAG = TestActivity.class.getSimpleName();

    Button startRecord;
    Button stopRecord;
    boolean recordStarted = false;
    private static String fileName = "/Recordings/event.3gp";
    AudioRecorder audioRecorder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.record);

        startRecord = (Button)findViewById(R.id.buttonStartRecord);
        stopRecord = (Button)findViewById(R.id.buttonStopRecord);

        startRecord.setOnClickListener(this);
        stopRecord.setOnClickListener(this);
        audioRecorder = new AudioRecorder(fileName);
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "resumed");
    }

    @Override
    protected void onPause() {
    super.onPause();
    Log.d(TAG, "paused");
    }

    @Override
    public void onClick(View v) {
        if (v == startRecord){
            try {
                audioRecorder.start();
                Toast.makeText(this, R.string.msgRecordSuccessful,
                    Toast.LENGTH_SHORT).show();
                recordStarted = true;
                Log.e(TAG, String.format("recording: %s", recordStarted));
            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(this, R.string.msgRecordFail, Toast.LENGTH_SHORT).show();
            }
        } else if (v == stopRecord){
            if (recordStarted == true) {
                try {
                    audioRecorder.stop();
                    recordStarted = false;
                    Log.e(TAG, String.format("recording: %s", recordStarted));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                Toast.makeText(this, R.string.msgNotRecording, Toast.LENGTH_SHORT).show();
            }
        }
    } // end onClick

}

XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:text="start"
        android:id="@+id/buttonStartRecord"></Button>
    <Button android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:id="@+id/buttonStopRecord"
        android:text="Stop"></Button>

</LinearLayout>

字符串:

<string name="msgReset">reset</string>
<string name="msgSetAudioSource">setAudioSource</string>
<string name="msgSetOutputFormat">setOutputFormat</string>
<string name="msgSetAudioEncoder">setAudioEncoder</string>
<string name="msgSetOutputFile">setOutputFile</string>
<string name="msgPrepare">prepare</string>
<string name="msgStart">start</string>

我没有太多的编程经验,我不知道这意味着什么,甚至不知道如何在谷歌中搜索这个问题......如果有人能给我指明一个大方向,那就太好了:D

谢谢!!

------------更新----------------

@蒂姆 来自 logcat 的调试 block 之后的几行:

INFO/ActivityManager(1362): Process com.bcit.chairlogger (pid 26461) has died.
INFO/WindowManager(1362): WIN DEATH: Window{44f04e20 com.bcit.chairlogger/com.bcit.chairlogger.TestActivity paused=false}
INFO/ActivityManager(1362): Displayed activity com.bcit.chairlogger/.TestActivity: 106629 ms (total 106629 ms)
INFO/UsageStats(1362): Unexpected resume of com.lge.launcher while already resumed in com.bcit.chairlogger
WARN/Flex(1456): getString FLEX_OPERATOR_CODE TLS
WARN/Flex(1456): getString FLEX_OPERATOR_CODE TLS
INFO/#LGIME(1442): #### onStartInput: restarting=false, fieldId=-1
WARN/InputManagerService(1362): Got RemoteException sending setActive(false) notification to pid 26461 uid 10071

最佳答案

我有同样的错误,解决方案对我有用“并且 MediaRecorder recorder = new MediaRecorder(); 在 start() 的开头”(Several audio recording in Android)

关于android - MediaRecorder 在录制第二个音频剪辑时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7522768/

有关android - MediaRecorder 在录制第二个音频剪辑时崩溃的更多相关文章

  1. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  2. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  3. 屏幕录制为什么没声音?检查这2项,轻松解决 - 2

    相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声

  4. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  5. ruby - 如何跳过 CSV 文件的第一行并将第二行作为标题 - 2

    有没有办法跳过CSV文件的第一行,让第二行作为标题?我有一个CSV文件,第一行是日期,第二行是标题,所以我需要能够在遍历它时跳过第一行。我尝试使用slice但它会将CSV转换为数组,我真的很想将其读取为CSV,以便我可以利用header。 最佳答案 根据您的数据,您可以使用另一种方法和skip_lines-option此示例跳过所有以#开头的行require'csv'CSV.parse(DATA.read,:col_sep=>';',:headers=>true,:skip_lines=>/^#/#Markcomments!)do|

  6. ruby - 在多个线程中引用类方法会导致自动加载循环依赖崩溃 - 2

    代码:threads=[]Thread.abort_on_exception=truebegin#throwexceptionsinthreadssowecanseethemthreadseputs"EXCEPTION:#{e.inspect}"puts"MESSAGE:#{e.message}"end崩溃:.rvm/gems/ruby-2.1.3@req/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:478:inload_missing_constant':自动加载常量MyClass时检测到循环依赖稍加研究后,

  7. ruby - `respond_to_missing?` 的第二个参数有什么用吗? - 2

    使用method_missing时在Ruby中,它是almostalwaysagoodidea定义respond_to_missing?respond_to_missing?接受两个参数;我们正在检查的方法的名称(symbol),以及一个指示我们是否应该在检查中包含私有(private)方法的bool值(include_all)。现在我感到困惑的是:method_missing不接受任何可能指示它是否应该调用私有(private)方法的参数,如respond_to_missing?做。此外,method_missing无论原始方法调用是在公共(public)上下文还是私有(privat

  8. ruby - 执行过期异常使 Ruby 线程崩溃,但处理了 Timeout::Error - 2

    任何人都可以解释为什么当对方法的调用看起来像这样时我可能会看到这个堆栈(由HTTParty::post请求引起):beginresponse=HTTParty::post(url,options)rescuelogger.warn("Couldnotpostto#{url}")rescueTimeout::Errorlogger.warn("Couldnotpostto#{url}:timeout")end堆栈:/usr/local/lib/ruby/1.8/timeout.rb:64:in`timeout'/usr/local/lib/ruby/1.8/net/protocol.rb

  9. ruby - vim 使用 AutoComplPop 插件崩溃 - 2

    我使用vim编辑ruby​​文件,但是当我输入“.”时它崩溃了。我发现它是由AutoComplPop插件引起的。我该怎么办? 最佳答案 我找到了一种使用autocomplpop和filetype=ruby来防止vim崩溃的方法。将以下行放入您的.vimrcletg:acp_behaviorRubyOmniMethodLength=-1这将防止在您键入“.”时触发autocomplpop。(期间)这不是解决办法。(我不是vim插件程序员)祝你好运! 关于ruby-vim使用AutoComp

  10. ruby-on-rails - 自动加载路径和嵌套服务类在 Ruby 中崩溃 - 2

    我在Rails5项目的app/services文件夹下有多个加载/需要类的问题,我开始放弃这个问题。首先要明确的是,services/是我在整个项目中使用的简单PORO类,用于从Controller、模型等中抽象出大部分业务逻辑。树看起来像这样app/services/my_service/base.rbfunny_name.rbmy_service.rbmodels/funny_name.rb失败#1首先,当我尝试使用MyService.const_get('FunnyName')时,它从我的模型目录中获取了FunnyName。当我直接执行MyService::FunnyName时,

随机推荐