播放的音频超过 java 中设置的持续时间

audio played exceeds the set duration in java

我正在将来自用户的短信作为输入。根据短信中的字母,我维护了一个数组(在代码中命名为持续时间),用于存储必须播放 audio1 的时间。

我交替地在特定位置循环播放两个音频文件并停止它们。

第一个音频文件播放到第一个字母的持续时间,然后第二个音频文件设置位置值和持续时间值并播放到持续时间 + 2 秒。每次该值适当增加。

但是当我播放时它有时会停在正确的位置(就像前两次迭代一样)但有时它会超出设置的位置并开始完整播放音频文件直到结束。

为什么会这样?

我正在使用eclipse编写和运行 java代码。

我的 java 代码。

import java.util.Scanner;
import java.io.File;
import java.io.IOException;
import javax.sound.*; 
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

public class Stegano implements LineListener{

    /**
     * @param args
     */
    static long[] duration;
    static boolean playCompleted1;
    static boolean playCompleted2;
    static int ch;
    static float rate,r;

    //public static AudioFormat.Encoding PCM_SIGNED;
    public static AudioFormat getOutFormat(AudioFormat inFormat){
        ch = inFormat.getChannels();
        rate = inFormat.getSampleRate();
        r = rate;
    //  convertToFrames();
        return new AudioFormat(AudioFormat.Encoding.PCM_SIGNED ,7200,16,ch,ch*2,rate,inFormat.isBigEndian());
    }
    /*public static void convertToFrames(){
        int i ;
        for(i=0;i<duration.length;i++){
            duration[i] = (r*duration[i])/1000;
            System.out.println(duration[i]);
        }
    }*/
    void convertToAudio(){
        final File file1 = new File("E:/Jeena_Jeena_wapking.wav");
        final File file2 = new File("E:/Jeena_Jeena_wapking.wav");

        try {
            AudioInputStream in1 = AudioSystem.getAudioInputStream(file1);
            AudioInputStream in2 = AudioSystem.getAudioInputStream(file2);

            AudioFormat inForm1 = getOutFormat(in1.getFormat());
            AudioFormat inForm2 = getOutFormat(in2.getFormat());

            DataLine.Info info1 = new DataLine.Info(Clip.class,inForm1);
            DataLine.Info info2 = new DataLine.Info(Clip.class,inForm2);

            Clip clip1 = (Clip)AudioSystem.getLine(info1);
            Clip clip2 = (Clip)AudioSystem.getLine(info2);

            long d = 0;
            int i;
            long dt = clip1.getMicrosecondLength();
            System.out.println("Duration : " + (float)((dt / 1000000)/60.0) + "min");
            for(i=0;i< duration.length;i++){

                    System.out.println("i" + i);
                    in1 = AudioSystem.getAudioInputStream(file1);
                    inForm1 = getOutFormat(in1.getFormat());
                    info1 = new DataLine.Info(Clip.class,inForm1);
                    clip1 = (Clip)AudioSystem.getLine(info1);
                    clip1.addLineListener(this);
                    clip1.open(in1);
                    clip1.setMicrosecondPosition(d);

                    long pos = 0; 
                    clip1.start();


                    while(true){
                        pos = clip1.getMicrosecondPosition();
                        System.out.println("pos 1: " + pos);
                        if( pos == (d + duration[i])){
                            System.out.println("posFinal : " + pos);

                            clip1.stop();
                            break;
                        }   
                    }
                    while (!playCompleted1) {
                        // wait for the playback completes
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }
                    clip1.close();
                    playCompleted1 = false;
                    System.out.println("PLayback1 completed");
                    try {
                        Thread.sleep(8000);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                    d = d+pos;

                    in2 = AudioSystem.getAudioInputStream(file2);
                    inForm2 = in2.getFormat();
                    info2 = new DataLine.Info(Clip.class,inForm2);
                    clip2 = (Clip)AudioSystem.getLine(info2);
                    clip2.addLineListener(this);
                    clip2.open(in2);
                    clip2.setMicrosecondPosition(d);

                    d = d+2000000;
                    //pos = 0;
                    clip2.start();

                    while(true){
                        pos = clip2.getMicrosecondPosition();
                        System.out.println("pos 2: " + pos);
                        if( pos == d){
                            System.out.println("posFinal : " + pos);

                            clip2.stop();
                            break;
                        }   
                    }
                    while (!playCompleted1) {
                        // wait for the playback completes
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }
                    clip2.close();
                    System.out.println("PLayback2 completed");
                    try {
                        Thread.sleep(8000);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                    //d = pos + 2000000;
                    playCompleted1 = false;
                  //  playCompleted2 = false;
            }


        } catch (UnsupportedAudioFileException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (LineUnavailableException ex) {
            System.out.println("Audio line for playing back is unavailable.");
            ex.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



    }

    public void update(LineEvent event) {
        LineEvent.Type type = event.getType();

        if (type == LineEvent.Type.START) {
            System.out.println("Playback started.");

        } else if (type == LineEvent.Type.STOP) {
            playCompleted1 = true;
            System.out.println("Playback completed.");
           /* if(playCompleted1 == true){
                playCompleted2 = true;
                System.out.println("Playback2 completed.");
            }*/
        }

    }
    public static void convertMsgToAudio(String msg){

        int len = msg.length();
        duration = new long[len];
        msg = msg.toUpperCase();
        System.out.println("Msg 2 : " + msg);

        int i;
        //char ch;
        for(i=0;i<msg.length();i++){

            if(msg.charAt(i) == 'A'){
                duration[i] = 500000;
            }
            else if (msg.charAt(i) == 'B'){
                duration[i] = 510000;
            }
            else if (msg.charAt(i) == 'C'){
                duration[i] = 520000;
            }
            else if (msg.charAt(i) == 'D'){
                duration[i] = 530000;               
            }
            else if (msg.charAt(i) == 'E'){
                duration[i] = 540000;
            }
            else if (msg.charAt(i) == 'F'){
                duration[i] = 550000;
            }
            else if (msg.charAt(i) == 'G'){
                duration[i] = 560000;
            }
            else if (msg.charAt(i) == 'H'){
                duration[i] = 570000;
            }
            else if (msg.charAt(i) == 'I'){
                duration[i] = 580000;
            }
            else if (msg.charAt(i) == 'J'){
                duration[i] = 600000;
            }
            else if (msg.charAt(i) == 'K'){
                duration[i] = 650000;
            }
            else if (msg.charAt(i) == 'L'){
                duration[i] = 660000;
            }
            else if (msg.charAt(i) == 'M'){
                duration[i] = 680000;
            }
            else if (msg.charAt(i) == 'N'){
                duration[i] = 700000;
            }
            else if (msg.charAt(i) == 'O'){
                duration[i] = 750000;
            }
            else if (msg.charAt(i) == 'P'){
                duration[i] = 800000;
            }
            else if (msg.charAt(i) == 'Q'){
                duration[i] = 850000;
            }
            else if (msg.charAt(i) == 'R'){
                duration[i] = 900000;
            }
            else if (msg.charAt(i) == 'S'){
                duration[i] = 950000;
            }
            else if (msg.charAt(i) == 'T'){
                duration[i] = 9800000;
            }
            else if (msg.charAt(i) == 'U'){
                duration[i] = 970000;
            }
            else if (msg.charAt(i) == 'V'){
                duration[i] = 1200000;
            }
            else if (msg.charAt(i) == 'W'){
                duration[i] = 1300000;
            }
            else if (msg.charAt(i) == 'X'){
                duration[i] = 1400000;
            }
            else if (msg.charAt(i) == 'Y'){
                duration[i] = 960000;
            }
            else if (msg.charAt(i) == 'Z'){
                duration[i] = 1600000;
            }
            else if (msg.charAt(i) == ' '){
                duration[i] = 1000000;
            }   
        }
        /*for(i=0;i<duration.length;i++){
            System.out.println(duration[i]);
        }*/
        Stegano s = new Stegano();
        s.convertToAudio();
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner s = new Scanner(System.in);
        String msg;
        System.out.print("Enter message: ");
        msg = s.nextLine();
        s.close();
        System.out.println("Msg " + msg);
        convertMsgToAudio(msg);
    }

}

请帮忙。我是新手

这是你想要的吗?

pos = clip1.getMicrosecondPosition();
System.out.println("pos 1: " + pos);
if( pos == (d + duration[i])){
    System.out.println("posFinal : " + pos);
    clip1.stop();
    break;
}  

当您检查 pos == (d + duration[i]) 时,您假设 clip1.getMicrosecondPosition() 将始终递增 1。如果它递增超过 1,它可能会跳过检查并且永远不会终止循环。尝试将该行更改为

if( pos >= (d + duration[i])){

进一步检查 clip2 也是如此。