+1 para uma solução que usa a API pública. Porém, a criação de um novo thread é desnecessária (redundante)?
Jataro
4
Thanx .. É redundante? Transformei em um novo tópico para poder reproduzir o som novamente antes do término do primeiro clipe.
pek 29/07/09
4
Eu sei que clip.start () gera um novo thread, por isso tenho certeza de que é desnecessário.
Jataro
44
1) O Threadé desnecessário. 2) Para um bom exemplo de uso Clip, consulte as informações do JavaSound. página . 3) Se um método requer um URL(ou File), dê a ele um dang URL(ou File) em vez de aceitar um Stringque represente um. (Apenas uma 'abelha no meu chapéu'.) 4) e.printStackTrace();fornece mais informações com menos digitação do que System.err.println(e.getMessage());.
Andrew Thompson
18
Um mau exemplo:
import sun.audio.*;//import the sun.audio packageimport java.io.*;//** add this into your application code as appropriate// Open an input stream to the audio file.InputStream in =newFileInputStream(Filename);// Create an AudioStream object from the input stream.AudioStream as =newAudioStream(in);// Use the static class member "player" from class AudioPlayer to play// clip.AudioPlayer.player.start(as);// Similarly, to stop the audio.AudioPlayer.player.stop(as);
@GregHurlman O pacote sun. * Não foi feito para não ser usado pelos desenvolvedores?
Tom Brito
36
Este exemplo vem de um artigo do JavaWorld de 1997. Muito desatualizado, você NÃO deve usar pacotes sun. *.
Sproketboy
3
você precisa fechar "in"?
Rogerdpack
6
+1 por não usar o sol. * Pacotes. Eles têm bugs estranhos como não lidar com arquivos> 1MB e não ser capaz de jogar um clipe se o anterior não terminou ainda, etc.
rogerdpack
10
Eu não queria ter tantas linhas de código apenas para tocar um som maldito simples. Isso pode funcionar se você tiver o pacote JavaFX (já incluído no meu jdk 8).
privatestaticvoid playSound(String sound){// cl is the ClassLoader for the current class, ie. CurrentClass.class.getClassLoader();
URL file = cl.getResource(sound);finalMedia media =newMedia(file.toString());finalMediaPlayer mediaPlayer =newMediaPlayer(media);
mediaPlayer.play();}
Aviso: Você precisa inicializar o JavaFX . Uma maneira rápida de fazer isso é chamar o construtor de JFXPanel () uma vez no seu aplicativo:
Para reproduzir som em java, você pode consultar o código a seguir.
import java.io.*;import java.net.URL;import javax.sound.sampled.*;import javax.swing.*;// To play sound using Clip, the process need to be alive.// Hence, we use a Swing application.publicclassSoundClipTestextendsJFrame{publicSoundClipTest(){this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setTitle("Test Sound Clip");this.setSize(300,200);this.setVisible(true);try{// Open an audio input stream.
URL url =this.getClass().getClassLoader().getResource("gameover.wav");AudioInputStream audioIn =AudioSystem.getAudioInputStream(url);// Get a sound clip resource.Clip clip =AudioSystem.getClip();// Open audio clip and load samples from the audio input stream.
clip.open(audioIn);
clip.start();}catch(UnsupportedAudioFileException e){
e.printStackTrace();}catch(IOException e){
e.printStackTrace();}catch(LineUnavailableException e){
e.printStackTrace();}}publicstaticvoid main(String[] args){newSoundClipTest();}}
Por qualquer motivo, a resposta principal do wchargin estava me dando um erro de ponteiro nulo quando eu estava chamando this.getClass (). GetResourceAsStream ().
Olá Anrew, seu código funcionou para mim, mas notei que leva um pouco de tempo extra na execução ... cerca de 1,5 seg.
getResourceAsStream()retornará nullse o recurso não for encontrado ou lançará a exceção se namefor null- não é uma falha da resposta principal se o caminho especificado não for válido
user85421
3
Eu criei uma estrutura de jogo há algum tempo para trabalhar no Android e no Desktop, a parte da área de trabalho que manipula o som pode ser usada como inspiração para o que você precisa.
Na verdade, eu resolvi isso usando raw.mark(raw.available()+1)depois de inicializar rawe depois no loop while e usando em raw.reset()vez de stream.reset(). Meu problema agora é que, quando se trata de redefinir, há uma lacuna entre as jogadas. Eu quero alcançar um loop contínuo como você obtém Clip. Não estou usando Clipporque manipular controles como MASTER_GAIN tem um atraso notável de ~ 500ms. Provavelmente, essa deve ser a sua própria pergunta, que vou fazer mais tarde.
driima 10/01
Não é do { ... } while?
Andreas
2
Existe uma alternativa para importar os arquivos de som que funcionam em applets e aplicativos: converta os arquivos de áudio em arquivos .java e simplesmente use-os no seu código.
Eu desenvolvi uma ferramenta que facilita muito esse processo. Simplifica bastante a API Java Sound.
Eu usei seu sistema para criar uma classe a partir de um arquivo wav, no entanto, quando eu faço my_wave.play (); não reproduzir o áudio .. Existe um sistema de áudio que eu preciso para inicializar ou algo assim ..?
Nathan F.
isso seria muito legal se realmente funcionasse. Ao executar o play (), a linha de áudio get falha (exceção "java.lang.IllegalArgumentException: Nenhuma interface de correspondência de linha SourceDataLine suporta o formato PCM_UNSIGNED 44100.0 Hz, 16 bits, estéreo, 4 bytes / quadro, little-endian é suportado." jogado). Triste.
phil294
2
Estou surpreso que ninguém tenha sugerido o uso do Applet. UseApplet . Você precisará fornecer o arquivo de áudio como um wavarquivo, mas ele funciona. Eu tentei isso no Ubuntu:
package javaapplication2;import java.applet.Applet;import java.applet.AudioClip;import java.io.File;import java.net.MalformedURLException;import java.net.URL;publicclassJavaApplication2{publicstaticvoid main(String[] args)throwsMalformedURLException{File file =newFile("/path/to/your/sounds/beep3.wav");
URL url =null;if(file.canRead()){url = file.toURI().toURL();}System.out.println(url);AudioClip clip =Applet.newAudioClip(url);
clip.play();System.out.println("should've played by now");}}//beep3.wav was available from: http://www.pacdv.com/sounds/interface_sound_effects/beep-3.wav
Este tópico é bastante antigo, mas eu determinei uma opção que pode ser útil.
Em vez de usar a AudioStreambiblioteca Java , você pode usar um programa externo como o Windows Media Player ou VLC e executá-lo com um comando do console por meio do Java.
String command ="\"C:/Program Files (x86)/Windows Media Player/wmplayer.exe\" \"C:/song.mp3\"";try{Process p =Runtime.getRuntime().exec(command);catch(IOException e){
e.printStackTrace();}
Isso também criará um processo separado que pode ser controlado no programa.
p.destroy();
É claro que isso levará mais tempo para ser executado do que o uso de uma biblioteca interna, mas pode haver programas que podem ser iniciados mais rapidamente e possivelmente sem uma GUI, devido a determinados comandos do console.
Embora eu ache que essa seja uma solução objetivamente ruim (em termos de confiabilidade, eficiência e outras métricas), é pelo menos uma solução interessante em que eu não pensaria!
Respostas:
Eu escrevi o seguinte código que funciona bem. Mas acho que só funciona com
.wav
formato.fonte
Thread
é desnecessário. 2) Para um bom exemplo de usoClip
, consulte as informações do JavaSound. página . 3) Se um método requer umURL
(ouFile
), dê a ele um dangURL
(ouFile
) em vez de aceitar umString
que represente um. (Apenas uma 'abelha no meu chapéu'.) 4)e.printStackTrace();
fornece mais informações com menos digitação do queSystem.err.println(e.getMessage());
.Um mau exemplo:
fonte
Eu não queria ter tantas linhas de código apenas para tocar um som maldito simples. Isso pode funcionar se você tiver o pacote JavaFX (já incluído no meu jdk 8).
Aviso: Você precisa inicializar o JavaFX . Uma maneira rápida de fazer isso é chamar o construtor de JFXPanel () uma vez no seu aplicativo:
fonte
Para reproduzir som em java, você pode consultar o código a seguir.
fonte
Por qualquer motivo, a resposta principal do wchargin estava me dando um erro de ponteiro nulo quando eu estava chamando this.getClass (). GetResourceAsStream ().
O que funcionou para mim foi o seguinte:
E eu tocava o som com:
sounds / effects / sheep1.wav estava localizado no diretório base do meu projeto no Eclipse (portanto, não dentro da pasta src).
fonte
getResourceAsStream()
retornaránull
se o recurso não for encontrado ou lançará a exceção sename
fornull
- não é uma falha da resposta principal se o caminho especificado não for válidoEu criei uma estrutura de jogo há algum tempo para trabalhar no Android e no Desktop, a parte da área de trabalho que manipula o som pode ser usada como inspiração para o que você precisa.
https://github.com/hamilton-lima/jaga/blob/master/jaga%20desktop/src-desktop/com/athanazio/jaga/desktop/sound/Sound.java
Aqui está o código para referência.
fonte
stream.reset();
levar aResetting to invalid mark
. O que você propõe fazer para corrigir isso?raw.mark(raw.available()+1)
depois de inicializarraw
e depois no loop while e usando emraw.reset()
vez destream.reset()
. Meu problema agora é que, quando se trata de redefinir, há uma lacuna entre as jogadas. Eu quero alcançar um loop contínuo como você obtémClip
. Não estou usandoClip
porque manipular controles como MASTER_GAIN tem um atraso notável de ~ 500ms. Provavelmente, essa deve ser a sua própria pergunta, que vou fazer mais tarde.do { ... } while
?Existe uma alternativa para importar os arquivos de som que funcionam em applets e aplicativos: converta os arquivos de áudio em arquivos .java e simplesmente use-os no seu código.
Eu desenvolvi uma ferramenta que facilita muito esse processo. Simplifica bastante a API Java Sound.
http://stephengware.com/projects/soundtoclass/
fonte
Estou surpreso que ninguém tenha sugerido o uso do Applet. Use
Applet
. Você precisará fornecer o arquivo de áudio como umwav
arquivo, mas ele funciona. Eu tentei isso no Ubuntu:fonte
Applet
foi descontinuado a partir do Java 9.Este tópico é bastante antigo, mas eu determinei uma opção que pode ser útil.
Em vez de usar a
AudioStream
biblioteca Java , você pode usar um programa externo como o Windows Media Player ou VLC e executá-lo com um comando do console por meio do Java.Isso também criará um processo separado que pode ser controlado no programa.
É claro que isso levará mais tempo para ser executado do que o uso de uma biblioteca interna, mas pode haver programas que podem ser iniciados mais rapidamente e possivelmente sem uma GUI, devido a determinados comandos do console.
Se o tempo não é essencial, isso é útil.
fonte