1

PCMサウンドデータ(長いサウンド、つまり音楽トラック用)を処理するAndroidアプリを実装しています。AudioTrack クラスを使用して音楽を再生することにしましたが、アプリ全体をブロックしているため、アクティビティと同じスレッドに配置することはできません。非同期タスク(またはその他のオプション)で?最善の方法は何ですか?音楽ファイルの再生/一時停止/停止と変更が必要です。

今、私はそれをJavaスレッドで管理しようとしていますが、ほとんど問題ありません-再生は問題ありませんが、ほとんど一時停止しています(サウンドの一部が「ドロップ」しています)が、音楽ファイルを変更しているとき、前のものはそうではありません停止し、混合出力があります(スレッドの実装に問題があると思います)。

そして - いいえ、このアプリでは MediaPlayer を使用できません (その場で PCM データを変更したい)。

私はグーグルとここでスタックオーバーフローで助けを探していましたが、何も助けにはなりませんでした。

誰かが見たい場合は、これが私の現在の実装です。

public class AudioPlayerManager {

private AudioTrack track;
private Thread thread;
private AudioTrackThread trackThread = new AudioTrackThread();

public int getPlayState() {
    return track.getPlayState();
}

public int getAudioSession() {
    return track.getAudioSessionId();
}

class AudioTrackThread implements Runnable {
    private String filePath = "/music/wav/musicfile.wav";

    @Override
    public void run() {
        try {
            playWaveFile();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public void playWaveFile() throws FileNotFoundException {       
        int minSize = AudioTrack.getMinBufferSize(44100,
                AudioFormat.CHANNEL_OUT_STEREO,
                AudioFormat.ENCODING_PCM_16BIT);
        track = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,
                AudioFormat.CHANNEL_OUT_STEREO,
                AudioFormat.ENCODING_PCM_16BIT, minSize,
                AudioTrack.MODE_STREAM);

        File file = new File(FileListingUtils.getExternalStorageRootFile(),
                filePath);
        InputStream is = new FileInputStream(file);

        byte[] music = new byte[512];
        track.play();

        try {
            handleSound(is, music);
        } catch (IOException e) {
            e.printStackTrace();
        }

        track.stop();
        track.release();
    }

    private void handleSound(InputStream is, byte[] music)
            throws IOException {
        int i;
        while ((i = is.read(music)) != -1) {
            track.write(music, 0, i);
        }
    }
}

public void playNew() {
    if (track != null) {
        track.stop();
        //track.flush();
        track.release();
    }

    thread = new Thread(trackThread);
    thread.start();
}

public void playOrResume() {
    this.track.play();
}

public void pause() {
    this.track.pause();
}

}

いつも助けてくれてありがとう!

M.

4

1 に答える 1

1

あなたのスレッドのライフサイクルは正しくないようです。まず、再生が停止または終了するたびに現在のスレッドを閉じ(中断)、スレッドの新しいインスタンスを作成して古いスレッドを閉じる必要があります。

次に、track.stop()スレッドの外から呼び出しています。スレッド内に public stop メソッドを実装し、そこにファイナライズ コードを挿入してから、playNew() メソッドで yourthread.stop() を呼び出す必要があります。

したがって、ここに疑似コードがあります:

public void playNew() {

//the following if clause should go to thread's stop() method.
  // if (track != null) {
  //  track.stop();
 //track.flush();
 //    track.release();
// }
  //create a new thread if its null
if(thread ==null){
thread = new Thread(new AudioTrackThread());
thread.start();}
//stop the current thread
else{
thread.stop();
thread=null;}
}

あなたの実装について、どこかで音楽を再生するには、サービスとスレッドがより良いオプションになることを読んだ.アンドロイドドキュメントのサービスとスレッドについて読んでください。

于 2013-07-22T23:12:54.217 に答える