使用AndroidRecord API录制的音频无法播放 [英] Recorded audio Using AndroidRecord API fails to play

查看:151
本文介绍了使用AndroidRecord API录制的音频无法播放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一款具有录制用户语音功能的android应用。为此,我使用了AndroidRecord Audio API。

Am developing an android app that has the feature to record the user speech. For this I have used the AndroidRecord Audio API.

当前在SD卡中成功生成了pcm文件(已录制的音频文件-recordedAudio.pcm)。但是无法播放该文件。我也在PC上尝试了Windows Media Palyer和其他一些播放器。但是没有任何帮助。

Currently the pcm file(recorded audio file - recordedAudio.pcm) getting generated successfully in the sd card. But am not able to play that file. I tried in PC also with windows media palyer and some other players. But nothing helps.

以下是我的代码段

private int minBufSize;
private AudioRecord recorder;
private int sampleRate = 44100;
private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
private boolean status;

minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig,
            audioFormat);
status = true;
startStreaming();

public void startStreaming() {
Thread streamThread = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            String filePath = Environment.getExternalStorageDirectory()
                    .getPath() + "/audioRecord.pcm";
            FileOutputStream fileOutputStreamObj = null;
            try {
                fileOutputStreamObj = new FileOutputStream(filePath);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                Log.e(TAG, "Exception" + e.getMessage());
            }

                // short[] sData = new short[minBufSize];
                byte[] buffer = new byte[minBufSize];

                // recorder = findAudioRecord();
                recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
                        sampleRate, channelConfig, audioFormat, minBufSize);
                Log.d(TAG, "Recorder initialized");

                recorder.startRecording();

                while (status) {
                    // reading data from MIC into buffer
                    minBufSize = recorder.read(buffer, 0, buffer.length);
                    try {
                        // writes the data to file from buffer
                        // stores the voice buffer
                        // byte bData[] = short2byte(sData);

                        fileOutputStreamObj.write(buffer, 0, buffer.length);
                    } catch (IOException e) {
                        e.printStackTrace();
                        Log.e(TAG, "Exception" + e.getMessage());
                    }
                    // mConnection.sendBinaryMessage(buffer);
                    System.out.println("MinBufferSize: " + minBufSize);
                }

            } catch (Exception e) {
                e.printStackTrace();
                Log.e(TAG, "Exception" + e.getMessage());
            }
        }

    });
    streamThread.start();
}

请帮助我。提前致谢。

Please help me on this. Thanks in advance.

推荐答案

是的,我终于找到了上面迈克尔评论的线索的答案。

Yes finally I found the answer with the clue of Michael's Comment above.

在此处张贴工作代码。

客户端代码,如下所示,
从客户端将音频数据流传输到Web套接字服务器。

The Client Side Code as Follow's, From the client side am streaming the audio data to the web socket server.

private int minBufSize;
private AudioRecord recorder;
private int sampleRate = 44100;
private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;

minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig,
                audioFormat);
startStreaming();

public void startStreaming() {
        Thread streamThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {

                    byte[] buffer = new byte[minBufSize];

                    recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
                            sampleRate, channelConfig, audioFormat, minBufSize);
                    Log.d(TAG, "Recorder initialized");

                    recorder.startRecording();

                    while (status) {

                        // reading data from MIC into buffer
                        minBufSize = recorder.read(buffer, 0, buffer.length);

                        mConnection.sendBinaryMessage(buffer);
                        System.out.println("MinBufferSize: " + minBufSize);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                    Log.e(TAG, "Exception" + e.getMessage());
                }
            }

        });
        streamThread.start();
    }

服务器端代码添加了以下实现,
首先,服务器将根据流数据创建.pcm。然后从该pcm文件中,通过添加标题来创建wave文件。

The Server Side Code added implementation as follows, First the server will create the .pcm from the streamed data. Then from that pcm file it will create the wave file by adding header.

  @OnMessage
  public void onMessage(byte[] data, boolean arg1)
  {
    if ((!this.currentCommand.equals("stop")) && 
      (this.currentCommand.equals("start")))
      try {
        System.out.println("Starting new recording.");
        FileOutputStream fOut = new FileOutputStream(this.f2, true);
        fOut.write(data);
        fOut.close();

        properWAV(this.f2, 111133.0F);
      }
      catch (Exception e) {
        e.printStackTrace();
      }
  }

private void properWAV(File fileToConvert, float newRecordingID)
  {
    try {
      long mySubChunk1Size = 16L;
      int myBitsPerSample = 16;
      int myFormat = 1;
      long myChannels = 1L;
      long mySampleRate = 44100L;
      long myByteRate = mySampleRate * myChannels * myBitsPerSample / 8L;
      int myBlockAlign = (int)(myChannels * myBitsPerSample / 8L);

      byte[] clipData = getBytesFromFile(fileToConvert);

      long myDataSize = clipData.length;
      long myChunk2Size = myDataSize * myChannels * myBitsPerSample / 8L;
      long myChunkSize = 36L + myChunk2Size;

      OutputStream os = new FileOutputStream(new File("D:/audio/" + newRecordingID + ".wav"));
      BufferedOutputStream bos = new BufferedOutputStream(os);
      DataOutputStream outFile = new DataOutputStream(bos);

      outFile.writeBytes("RIFF");
      outFile.write(intToByteArray((int)myChunkSize), 0, 4);
      outFile.writeBytes("WAVE");
      outFile.writeBytes("fmt ");
      outFile.write(intToByteArray((int)mySubChunk1Size), 0, 4);
      outFile.write(shortToByteArray((short)myFormat), 0, 2);
      outFile.write(shortToByteArray((short)(int)myChannels), 0, 2);
      outFile.write(intToByteArray((int)mySampleRate), 0, 4);
      outFile.write(intToByteArray((int)myByteRate), 0, 4);
      outFile.write(shortToByteArray((short)myBlockAlign), 0, 2);
      outFile.write(shortToByteArray((short)myBitsPerSample), 0, 2);
      outFile.writeBytes("data");
      outFile.write(intToByteArray((int)myDataSize), 0, 4);
      outFile.write(clipData);

      outFile.flush();
      outFile.close();
    }
    catch (IOException e) {
      e.printStackTrace();
    }
  }

  private static byte[] intToByteArray(int i)
  {
    byte[] b = new byte[4];
    b[0] = (byte)(i & 0xFF);
    b[1] = (byte)(i >> 8 & 0xFF);
    b[2] = (byte)(i >> 16 & 0xFF);
    b[3] = (byte)(i >> 24 & 0xFF);
    return b;
  }

  public static byte[] shortToByteArray(short data)
  {
    return new byte[] { (byte)(data & 0xFF), (byte)(data >>> 8 & 0xFF) };
  }

  public byte[] getBytesFromFile(File file)
    throws IOException
  {
    byte[] buffer = new byte[(int)file.length()];
    InputStream ios = null;
    try {
      ios = new FileInputStream(file);
      if (ios.read(buffer) == -1)
        throw new IOException("EOF reached while trying to read the whole file");
    }
    finally {
      try {
        if (ios != null)
          ios.close();
      }
      catch (IOException localIOException)
      {
      }
    }
    try
    {
      if (ios != null)
        ios.close();
    }
    catch (IOException localIOException1)
    {
    }
    return buffer;
  }

希望这可以节省很多开发人员的时间。

Hope this one saves many of the developer's time.

这篇关于使用AndroidRecord API录制的音频无法播放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆