How to tell when AudioTrack object has finished playing?

杀马特。学长 韩版系。学妹 提交于 2020-01-20 05:40:24

问题


I'm trying to play a PCM file in Android using the AudioTrack class. I can get the file to play just fine, but I cannot reliably tell when playback has finished. AudioTrack.getPlayState says playback has stopped when it hasn't finished playing. I'm having the same problem with AudioTrack.setNotificationMarkerPosition, and I'm pretty sure my marker is set to the end of the file (although I'm not completely sure I'm doing it right). Likewise, playback continues when getPlaybackHeadPosition is at the end of the file and has stopped incrementing. Can anyone help?


回答1:


I found that using audioTrack.setNotificationMarkerPosition(audioLength) and audioTrack.setPlaybackPositionUpdateListener worked for me. See the following code:

    // Get the length of the audio stored in the file (16 bit so 2 bytes per short)
    // and create a short array to store the recorded audio.
    int audioLength = (int) (pcmFile.length() / 2);
    short[] audioData = new short[audioLength];
    DataInputStream dis = null;

    try {
        // Create a DataInputStream to read the audio data back from the saved file.
        InputStream is = new FileInputStream(pcmFile);
        BufferedInputStream bis = new BufferedInputStream(is);
        dis = new DataInputStream(bis);

        // Read the file into the music array.
        int i = 0;
        while (dis.available() > 0) {
            audioData[i] = dis.readShort();
            i++;
        }

        // Create a new AudioTrack using the same parameters as the AudioRecord.
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, RECORDER_SAMPLE_RATE, RECORDER_CHANNEL_OUT,
                                    RECORDER_AUDIO_ENCODING, audioLength, AudioTrack.MODE_STREAM);
        audioTrack.setNotificationMarkerPosition(audioLength);
        audioTrack.setPlaybackPositionUpdateListener(new OnPlaybackPositionUpdateListener() {
            @Override
            public void onPeriodicNotification(AudioTrack track) {
                // nothing to do
            }
            @Override
            public void onMarkerReached(AudioTrack track) {
                Log.d(LOG_TAG, "Audio track end of file reached...");
                messageHandler.sendMessage(messageHandler.obtainMessage(PLAYBACK_END_REACHED));
            }
        });

        // Start playback
        audioTrack.play();

        // Write the music buffer to the AudioTrack object
        audioTrack.write(audioData, 0, audioLength);

    } catch (Exception e) {
        Log.e(LOG_TAG, "Error playing audio.", e);
    } finally {
        if (dis != null) {
            try {
                dis.close();
            } catch (IOException e) {
                // don't care
            }
        }
    }



回答2:


This works for me:

            do{                                                     // Montior playback to find when done
                 x = audioTrack.getPlaybackHeadPosition(); 
        }while (x< pcmFile.length() / 2);


来源:https://stackoverflow.com/questions/3643338/how-to-tell-when-audiotrack-object-has-finished-playing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!