如何检查音频文件已完成在Android中播放

问题描述:

我正在开发一个Android录音应用程序。我面临的问题是我想知道正在播放的声音文件何时完成,我不知道如何检查。 MediaRecorder类有setOnCompleteListener,但我使用AudioRecorder类,因为我需要在录制过程中进行一些编辑,如改变扬声器的频率和音高。 以下是我的代码:如何检查音频文件已完成在Android中播放

public class MainActivity extends Activity { 

Integer[] freqset = {8000}; 
private ArrayAdapter<Integer> adapter; 

Spinner spFrequency; 
Button startRec, stopRec, playBack; 

Boolean recording; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     startRec = (Button)findViewById(R.id.startrec); 
     stopRec = (Button)findViewById(R.id.stoprec); 
     playBack = (Button)findViewById(R.id.playback); 

     startRec.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
        Thread recordThread = new Thread(new Runnable(){ 

         @Override 
         public void run() { 
         recording = true; 
         startRecord(); 
         } 

         }); 

         recordThread.start(); 

      } 
     }); 
     stopRec.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       recording = false; 

      } 
     }); 
     playBack.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 

        Log.i("Test","Play Record called");playRecord(); 


      } 
     }); 

     spFrequency = (Spinner)findViewById(R.id.frequency); 
     adapter = new ArrayAdapter<Integer>(this, android.R.layout.simple_spinner_item, freqset); 
     adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
     spFrequency.setAdapter(adapter); 

    } 

private void startRecord(){ 

    File file = new File(Environment.getExternalStorageDirectory(), "test.pcm"); 
    int BytesPerElement = 2; 
    int sampleFreq = (Integer)spFrequency.getSelectedItem(); 
    Log.e("Test","Start Recording"+sampleFreq); 
    try { 
    file.createNewFile(); 

    OutputStream outputStream = new FileOutputStream(file); 
    BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream); 
    DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream); 

    int minBufferSize = AudioRecord.getMinBufferSize(sampleFreq, 
    AudioFormat.CHANNEL_IN_MONO, 
    AudioFormat.ENCODING_PCM_16BIT); 
    Log.i("Test","Buffer Size is"+minBufferSize); 

    short[] audioData = new short[minBufferSize]; 
    Log.i("Test","audioData initialized"+audioData); 
    AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, 
    sampleFreq, 
    AudioFormat.CHANNEL_IN_MONO, 
    AudioFormat.ENCODING_PCM_16BIT, 
    minBufferSize*BytesPerElement); 
    Log.i("Test","audioRecord initialized"+audioRecord); 

    audioRecord.startRecording(); 

    while(recording){ 
    int numberOfShort = audioRecord.read(audioData, 0, minBufferSize); 
    for(int i = 0; i < numberOfShort; i++){ 
    dataOutputStream.writeShort(audioData[i]); 
     Log.i("Test","Recording buzzz"+recording); 

    } 
    } 
    Log.i("Test","Recording Value after stop"+recording); 

    audioRecord.stop(); 
    dataOutputStream.close(); 

    } catch (IOException e) { 
    e.printStackTrace(); 
    Log.e("Testing", "Esception Found"); 
    } 

} 

void playRecord(){ 

    File file = new File(Environment.getExternalStorageDirectory(), "test.pcm"); 

     int shortSizeInBytes = Short.SIZE/Byte.SIZE; 

    int bufferSizeInBytes = (int)(file.length()/shortSizeInBytes); 
    short[] audioData = new short[bufferSizeInBytes]; 

    try { 
    InputStream inputStream = new FileInputStream(file); 
    BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); 
    DataInputStream dataInputStream = new DataInputStream(bufferedInputStream); 

    int i = 0; 
    while(dataInputStream.available() > 0){ 
    audioData[i] = dataInputStream.readShort(); 
    i++; 
    } 

    dataInputStream.close(); 

    int sampleFreq = (Integer)spFrequency.getSelectedItem(); 
     Log.i("Test","Sab set hai"); 

    AudioTrack audioTrack = new AudioTrack(
    AudioManager.STREAM_MUSIC, 
    sampleFreq, 
    AudioFormat.CHANNEL_CONFIGURATION_MONO, 
    AudioFormat.ENCODING_PCM_16BIT, 
    bufferSizeInBytes, 
    AudioTrack.MODE_STREAM); 
    Log.i("Test","will start play"); 
    audioTrack.play(); 
    audioTrack.write(audioData, 0, bufferSizeInBytes); 

    Log.i("Test","does this print"); 
    } catch (FileNotFoundException e) { 
     Log.i("Test","Ye wali exception"); 
    e.printStackTrace(); 
    } catch (IOException e) { 
     Log.i("Test"," Ni Ye wali exception");   
    e.printStackTrace(); 
    } 
}} 

可以使用AudioTrack.OnPlaybackPositionUpdateListenerAudioTrack.setNotificationMarkerPosition已知音频播放完毕或不作为:

AudioTrack audioTrack = new AudioTrack(
    AudioManager.STREAM_MUSIC, 
    sampleFreq, 
    AudioFormat.CHANNEL_CONFIGURATION_MONO, 
    AudioFormat.ENCODING_PCM_16BIT, 
    bufferSizeInBytes, 
    AudioTrack.MODE_STREAM); 

// set setNotificationMarkerPosition accouding audio length 
audioTrack.setNotificationMarkerPosition(bufferSizeInBytes); 

// now add OnPlaybackPositionUpdateListener to audioTrack 
    audioTrack.setPlaybackPositionUpdateListener(
          new AudioTrack.OnPlaybackPositionUpdateListener() { 
     @Override 
     public void onMarkerReached(AudioTrack track) { 
      // do your work here.... 
     } 
    }); 
+0

根据文档,setNotificationMarkerPosition需要*帧数*,不字节数 – paleozogt 2013-12-18 22:41:36