JavaでWAV再生、シンプルメディアプレーヤーの作成
広告
ズバット引越し比較
Posted on 2021/6/25 at 22:58
Javaで音声(WAV)ファイルを再生するサンプルはネット上にいくつもあったので、それを参考にしてSwingにてシンプルプレーヤーを作成してみました。主な機能は以下の3つだけです。
- 一時停止は無く「再生」か「停止」
- スライダーによるボリュームの調整
- 再生ファイルの選択
サンプルコード
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
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.FloatControl;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
public class SimplePlayer extends JFrame {
private VolumeChangeListener volumeChangeListener = null;
private Clip clip = null;
private JButton playBtn;
private JTextField mediaPathTxt;
private VolumeSlider slider;
public static void main(String[] args) {
new SimplePlayer();
}
public SimplePlayer() {
super("simple player");
this.setSize(700, 75);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
JPanel p = new JPanel();
p.setLayout(new FlowLayout(FlowLayout.LEADING));
playBtn = new JButton("再生");
playBtn.setPreferredSize(new Dimension(60, 25));
playBtn.setFont(new Font(playBtn.getFont().getFontName(), Font.PLAIN, 12));
playBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (mediaPathTxt.getText().isEmpty()) {
JOptionPane.showMessageDialog(
SimplePlayer.this, "音声ファイルを選択してください。", "エラー",
JOptionPane.ERROR_MESSAGE);
return;
}
JButton source = (JButton) e.getSource();
if (source.getText().equals("再生")) {
PlayWorker worker = new PlayWorker();
worker.execute();
return;
}
StopWorker worker = new StopWorker();
worker.execute();
}
});
mediaPathTxt = new JTextField();
mediaPathTxt.setPreferredSize(new Dimension(300, 25));
JButton fileBtn = new JButton("参照");
fileBtn.setPreferredSize(new Dimension(60, 25));
fileBtn.setFont(new Font(fileBtn.getFont().getFontName(), Font.PLAIN, 12));
fileBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser();
FileFilter filter = new FileNameExtensionFilter("wavファイル(.wav)", "wav");
chooser.setSelectedFile(new File(mediaPathTxt.getText()));
chooser.setFileFilter(filter);
int selected = chooser.showOpenDialog(SimplePlayer.this);
if (selected == JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
mediaPathTxt.setText(file.getAbsolutePath());
}
}
});
slider = new VolumeSlider();
p.add(playBtn);
p.add(mediaPathTxt);
p.add(fileBtn);
p.add(slider);
this.getContentPane().add(p);
this.setVisible(true);
}
class PlayWorker extends SwingWorker {
private AudioInputStream stream = null;
@Override
protected Void doInBackground() throws Exception {
AudioFormat format = null;
try {
playBtn.setText("停止");
stream = AudioSystem.getAudioInputStream(new File(mediaPathTxt.getText()));
format = stream.getFormat();
DataLine.Info cInfo = new DataLine.Info(Clip.class, format);
if (!AudioSystem.isLineSupported(cInfo))
return null;
clip = (Clip) AudioSystem.getLine(cInfo);
clip.open(stream);
float volume = (float) ((float)slider.getValue() / 100f);
FloatControl ctrl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
ctrl.setValue((float) Math.log10(volume) * 20);
volumeChangeListener = new VolumeChangeListener();
clip.addLineListener(volumeChangeListener);
clip.start();
clip.flush();
while (clip.isActive())
Thread.sleep(50);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
} catch (InterruptedException e1) {
}
return null;
}
@Override
public void done() {
try {
playBtn.setText("再生");
} finally {
if (clip != null && clip.isOpen())
clip.close();
try {
if(stream != null)
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class StopWorker extends SwingWorker {
@Override
protected Void doInBackground() throws Exception {
playBtn.setText("再生");
if (clip != null && clip.isOpen()) {
clip.stop();
clip.flush();
}
return null;
}
@Override
public void done() {
playBtn.setText("再生");
}
}
class VolumeSlider extends JSlider {
public VolumeSlider() {
super(0, 100, 20);
this.setMajorTickSpacing(25);
this.setPaintLabels(true);
this.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (volumeChangeListener != null)
volumeChangeListener.fireVolumeChange();
}
});
}
}
class VolumeChangeListener implements LineListener {
public void fireVolumeChange() {
float volume = (float) ((float)slider.getValue() / 100f);
FloatControl ctrl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
ctrl.setValue((float)Math.log10(volume) * 20);
}
@Override
public void update(LineEvent event) {}
}
}
プログラムの実行結果
関連記事
JavaでWAVファイルをリピート再生する
再生する音声ファイル、ボリューム(0~1)、リピートする回数、リピートの間隔(ms)を指定して再生するサンプルコードです。