1

Java アプリケーションで mp3 を再生しようとしています。ユーザーは、ボタンをクリックしてサウンドを変更することができます。

サウンドと切り替えは機能します...ただし、ユーザーがサウンドを切り替えようとすると、古い曲の再生が停止する前に、古い曲の上に新しい曲が約 1 秒間再生されます。スレッドを使用してすべてを処理しようとしています。

私のMP3クラス:

import java.applet.*;
import javazoom.jl.player.Player;
import java.io.*;
import java.io.FileInputStream;
import java.net.*;

public class mp3 extends Thread implements Runnable{

    private Player sound;
    private InputStream path;  
    public mp3(String file_name) {
        path = mp3.class.getClassLoader().getResourceAsStream(file_name);  
    }
    public void run(){
        try {
            Player sound=new Player(path);
            sound.play();
        } catch(Exception e) {System.out.println(e);}
    }
}

そして、これが私のメインゲームでコードを実行しようとする方法です。MP3 オブジェクトはソングと呼ばれます。

アプリケーションが初期化されると、次のコードが実行されます。

song = new mp3("default.mp3");
song.start();

誰かがそれを変更しようとすると、次のコードが実行されます。

song.stop();
song = new mp3(t+".mp3");
song.start();

ここで、t はファイル名のパラメーターです。

問題は MP3 オブジェクトの実行機能に依存していると確信しています。私はスレッドにまったく慣れていないので、助けていただければ幸いです。

繰り返しますが、「stop」が呼び出されてから実際に再生が停止するまでの遅延は約 1 秒です。それで、どこかで待っていませんか?

ありがとう!

編集: 私は今、ここに基づいたコードを使用しています:

http://introcs.cs.princeton.edu/java/faq/mp3/MP3.java.html

次のように定義された play および close 関数を作成しました。

    public void close() { if (player != null) player.close(); }

    // play the MP3 file to the sound card
    public void play() {
        try {
            FileInputStream fis     = new FileInputStream(filename);
            BufferedInputStream bis = new BufferedInputStream(fis);
            player = new Player(bis);
        } catch (Exception e) {
            System.out.println("Problem playing file " + filename);
            System.out.println(e);
        }

        // run in new thread to play in background
        new Thread() {
            public void run() {
                try { player.play(); }
                catch (Exception e) { System.out.println(e); }
            }
        }.start();

私の問題はクローズ機能にあります...プレーヤーオブジェクトは常にnullであり、クローズ機能は実行されません...再生機能がそれを初期化しても。なぜヌルなのですか?

4

1 に答える 1

1

編集:

編集で、複数のスレッドがplayerフィールドにアクセスしている場合は、それを作成する必要がありますvolatile。がどのようplayerに定義されているかを確認しないと、それ以外の問題を推測するのは困難です。


Player次の mp3 を開始する前に、前の mp3 が完了していることを確認する必要があると思います。javadocs をPlayer見ると、次のように表示されます。

`player.isComplete()`

引用するには:

利用可能なすべての MPEG オーディオ フレームがデコードされた場合は true、それ以外の場合は false を返します。

新しいサウンドが開始されたときに以前のオーディオを停止したい場合はclose()、古いプレーヤーで使用する必要があります。

このプレーヤーを閉じます。現在再生中のオーディオはすぐに停止します

Player現在実行中のオブジェクト (存在する場合)を閉じ、新しいPlayerオブジェクトを開始して新しいサウンドを再生する必要があるように思えます。これを複数のスレッドで実行している場合は、次のようにする必要があります。

  1. final Object lockオブジェクトをロックする
  2. 現在のサウンドを終了させたい場合は、現在のPlayerオブジェクト (存在する場合) がループで完了していることを確認します。sleep
  3. close()現在のオブジェクトを削除し、現在のサウンドを消したい場合Playerは新しいオブジェクトを作成しますPlayer
  4. 次のmp3を呼び出しplay()
  5. ロック オブジェクトのロックを解除します。

私の知る限り、このplay()メソッドはサウンドが再生されるのを待たず、サウンドをオーディオ バッファにロードした直後に戻ります。ただし、オーディオファイルが大きい場合はどうなるかわかりません。

于 2012-04-17T05:14:10.393 に答える