2009-03-21 4 views

답변

4
 AudioInputStream audioIn = AudioSystem.getAudioInputStream(url); 
    Clip clip = AudioSystem.getClip(); 
    clip.loop((int)(Math.ceil(timeRequested/audioIn.getFrameLength()))); 
+0

I 몇 가지 질문이 있습니다 - 내가 사용하고있는 기존 DataLine에 루프를 "부착"하는 방법은 무엇입니까? 클립으로 무엇을해야합니까? 그걸 SourceDataLine에 보내는 방법? – Tim

+0

자동으로 현재 활성화 된 DataLine에 연결됩니다. 클립은 다른 플레이어 인스턴스와 동일하거나 시작하거나 중지 할 수 있습니다. 대문자를 쿼리하여 동시에 재생할 수있는 대문자의 수를 확인할 수 있습니다. 필요한 경우 대기열을 정의하십시오. 하지만 혼자서 사용하는 것은 좋지 않습니다. –

+0

해보 겠지만, 코드가 존재하는 방식으로 데이터 라인과 함께 작동하는지 확실하지 않습니다. 감사 – Tim

0

솔루션 구현에 대한 정확한 제한 사항을 잘 모르겠지만 가장 깨끗한 방법은 파일을 처음 재생할 때 버퍼에 오디오 데이터를 저장하는 것입니다. 그런 다음 사용자가 원하는 반복 (전체 또는 부분)이 더 많이 발생하면 캐시 한 데이터를 원하는 횟수만큼 SourceDataLine에 다시 작성하기 만하면됩니다.

매우 쉽게 수정할 수있는 코드가있는 샘플 사운드 파일 플레이어 (PCM)에 대한 link입니다. 또한 위에서 설명한 논리를 보여주는 코드 (참고 : 테스트되지 않음)를 해킹했습니다. (아래에서 설명하는 내용을 수정하여 여러 크기의 데이터 청크 작성과 관련된 규칙을 준수하기를 원할 수도 있습니다.)

public void playSoundFile(SourceDataLine line, InputStream inputStream, AudioFormat format, long length, float times) 
{ 
    int index = 0; 
    int size = length * format.getFrameSize(); 
    int currentSize = 0; 
    byte[] buffer = new byte[size]; 
    AudioInputStream audioInputStream = new AudioInputStream(inputStream, format, length); 
    while (index < size) 
    { 
     currentSize = audioInputStream.read(buffer, index, size - index); 
     line.write(buffer, index, currentSize); 
     index += currentSize; 
    } 

    float currentTimes = 1.0; 
    while (currentTimes < times) 
    { 
     float timesLeft = times - currentTimes; 
     int writeBlockSize = line.available(); 
     index = 0; 

     if (timesLeft >= 1.0) 
     { 
      while (index < size) 
      { 
       currentSize = ((size - index) < writeBlockSize) ? size - index : writeBlockSize; 
       line.write(buffer, index, currentSize); 
       index += currentSize; 
      } 
      currentTimes += 1.0; 
     } 
     else 
     { 
      int partialSize = (int)(timesLeft * ((float) size) + 0.5f); 
      while (index < partialSize) 
      { 
       currentSize = ((partialSize - index) < writeBlockSize) ? partialSize - index : writeBlockSize; 
       line.write(buffer, index, currentSize); 
       index += currentSize; 
      } 
      currentTimes += timesLeft; 
     } 
    } 
} 

희망이 있습니다!

+0

가능성이 있습니다. 그러나 찾고자하는 것이 아닙니다. 데이터가 비동기 적으로 플레이어에게 보내지고 호출 스레드가 파일/사운드의 길이를 알 수 없습니다. – Tim

+0

상황에 대한 자세한 정보를 제공해 주시겠습니까? 몇 가지 지정되지 않은 것들이 있습니다 (예 : 파일/사운드의 길이를 알고있는 사람과 연주 할 시간을 알고있는 사람, 플레이어 인 경우 플레이어는 위에서 설명한 캐싱 방법을 수행 할 수 있습니다). –

0

초당 프레임을 사용하고 오디오 입력 스트림의 프레임 크기 정보를 사용하여 계산해 봅니다. 다른 유용한 정보는 SourceDataLine 객체의 getMicrosecondPosition() 메서드에서 지금까지 재생 된 시간/기간을 결정하는 데 있습니다.

오디오 입력 스트림의 mark 및 reset 메소드와 함께이 기능이 모두 처리됩니다.

관련 문제