如何在win32编程中,在同一个窗口下播放多个音乐

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在win32编程中,在同一个窗口下播放多个音乐相关的知识,希望对你有一定的参考价值。

参考技术A 一.在程序中直接播放声音文件  在VC++中的多媒体动态连接库中提供了一组与音频设备有关的函数。利用这些函数可以方便地播放声音。最简单的播放声音方法就是直接调用VC++中提供的声音播放函数BOOLsndPlaySound(LPCSTRlpszSound,UINTfuSound);或BOOLPlaySound(LPCSTRlpszSound,HMODULEhmod,DWORDfuSound);其中参数lpszSound是需要播放声音的.W***文件的路径和文件名,hmod在这里为NULL,fuSound是播放声音的标志,详细说明请参考VC++中的帮助。例如播放C:soundmusic.wav可以用sndPlaySound("c:\sound\music.wav",SND_ASYNC);或PlaySound("c:\sound\music.wav",NULL,SND_ASYNC|SND_NODEFAULT);如果没有找到music.wav文件,第一种格式将播放系统默认的声音,第二种格式不会播放系统默认的声音。二.将声音文件加入到程序中  在VC++的程序设计中,可以利用各种标准的资源,如位图,菜单,对话框等。同时VC++也允许用户自定义资源,因此我们可以将声音文件作为用户自定义资源加入程序资源文件中,经过编译连接生成EXE文件,实现无.W***文件的声音播放。要实现作为资源的声音文件的播放,首先要在资源管理器中加入待播放的声音文件。具体步骤入下:  1.获得包含资源的模块句柄:  HMODULEhmod=AfxGetResourceHandle();  2.检索资源块信息:  HRSRChSndResource=FindResource(hmod,MAKEINTRESOURCE(IDR_W***E1),_T("W***E"));  3.装载资源数据并加锁:  HGLOBALhGlobalMem=LoadResource(hmod,hSndResource);LPCTSTRlpMemSound=(LPCSTR)LockResource(hGlobalMem);  4.播放声音文件:  sndPlaySound(lpMemSound,SND_MEMORY));  5.释放资源句柄:  FreeResource(hGlobalMem);

在 JFrame 窗口的背景中播放音乐

【中文标题】在 JFrame 窗口的背景中播放音乐【英文标题】:Playing music in the background of a JFrame window 【发布时间】:2015-09-25 22:39:04 【问题描述】:

我正在尝试在 Frame 窗口的背景中播放音频文件,但我发现它比添加图片要复杂得多。

我找到了一个关于如何添加音乐的“教程”,它看起来相当简单,至少在所需的代码量方面。但是,我无法播放音频文件,它说明了两件事......

第一个 - 我试图播放一个我复制到我的 java 项目中的音频文件,这告诉我它找不到那个文件或目录。

第二个 - 我给了方法一个音频文件的路径,它告诉我......

could not get audio input stream from input file

请记住我是新手,本教程并没有提供太多帮助,所以我不知道很多这种播放方法实际上在做什么。我很想学习如何做到这一点,但是对于这个项目,我所看到的一切都过于复杂,而且我没有时间投入,因为没有必要,只需增加一点天赋就可以了。

非常感谢任何帮助!我在有问题的代码周围加了星号。

public MultiForm() 
    super("Multi Form Program");        
    setLayout(new FlowLayout());
    menu = new JComboBox(fileName);
    add(menu);

    /*How to add a background image to the Menu.
     * add(new JLabel(new ImageIcon(getClass().getResource("MatrixPIC.png"))));
     */

    TheHandler handler = new TheHandler();
    menu.addItemListener(handler);  


public void matrixPanel() 

    TheHandler handler = new TheHandler();
    //Create a new window when "The Matrix" is clicked in the JCB
    newFrame = new JFrame();
    panel = new JPanel();
    panel2 = new JPanel();

    newFrame.setLayout(new FlowLayout());
    newFrame.setSize(500, 300);
    newFrame.setDefaultCloseOperation(newFrame.EXIT_ON_CLOSE);      

    matrixQuote = new JLabel("<html><center>After this, there is no turning back. "
            + "<br><center>You take the blue pill—the story ends, you wake up "
            + "<br><center>in your bed and believe whatever you want to believe."
            + "<br><center>You take the red pill—you stay in Wonderland, and I show"
            + "<br><center>you how deep the rabbit hole goes. "
            + "<br><center>Remember: all I'm offering is the truth. Nothing more.</html>");

    panel.add(matrixQuote);
    newFrame.add(panel, BorderLayout.NORTH);

    //Blue pill button and picture. 
    Icon bp = new ImageIcon(getClass().getResource("Blue Pill.png"));
    bluePill = new JButton("Blue Pill", bp);
    panel2.add(bluePill);   
    bluePill.addActionListener(handler);

    //Red pill button and picture
    Icon rp = new ImageIcon(getClass().getResource("Red Pill.png"));
    redPill = new JButton("Red Pill", rp);
    panel2.add(redPill);

    newFrame.add(panel2, BorderLayout.CENTER);      
    newFrame.setVisible(true);


*********************************************************************************
public void play(String path, int delay, int numberOfLoops) 
    for(int i = 0; i < numberOfLoops; i++) 
        new Thread() 
            @Override
            public void run() 
                try 
                    File file = new File(path);
                    Clip clip = AudioSystem.getClip();
                    clip.open(AudioSystem.getAudioInputStream(file));
                    clip.start();
                    Thread.sleep(clip.getMicrosecondLength());

                 catch (Exception e) 
                    System.out.println(e.getMessage());
                
            
        .start();
        try 
            Thread.sleep(delay);
         catch (InterruptedException e) 
            e.printStackTrace();
        
    

*********************************************************************************        

private class TheHandler implements ItemListener, ActionListener

    public void itemStateChanged(ItemEvent IE) 
        //listen for an item to be selected.
        if(IE.getStateChange() == ItemEvent.SELECTED) 
            Object selection = menu.getSelectedItem();

            if("The Matrix".equals(selection)) 
                matrixPanel();
            
            else if("Another Option".equals(selection))    
            
           
    


    public void actionPerformed(ActionEvent AE) 
        if(AE.getSource() == bluePill) 
            //Clear panels after button is clicked.
            newFrame.remove(panel);         
            newFrame.remove(panel2);
            newFrame.repaint();
    *********************************************************************************       
            play("/Users/SWD/Downloads/fail.mp3", 10, 30);
 *********************************************************************************  
            newFrame.setSize(600, 400);
            bpPanelLabel = new JPanel();
            bpLabel = new JLabel("<html><center>WELCOME TO THE BEGINING OF YOUR NEW LIFE!  " +
                     "<br><center>YOU'RE ABOUT TO SEE HOW DEEP THE RABBIT HOLE GOES!</html>");
            newFrame.add(bpLabel);
            newFrame.add(bpPanelLabel, BorderLayout.NORTH);
            bpPanelPic = new JPanel();
            newFrame.add(new JLabel(new ImageIcon(getClass().getResource("MatrixPIC.png"))));
            newFrame.add(bpPanelPic, BorderLayout.CENTER);  
            newFrame.validate();
        


       



//Main method sets up the main JFrame with the menu
public static void main(String[] args) 

    MultiForm go = new MultiForm();
    go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    go.setSize(400, 200);
    go.setVisible(true);


【问题讨论】:

Java 音频不支持(所有)mp3 编码。如果您必须播放 mp3,请查看 JavaZoom's JLayer API 我还尝试了一个 .wav,我认为我读过它会播放? 我会摆脱 Thread.sleep 重复音频请看this example 【参考方案1】:
    Java 的音频 API 不支持(全部)mp3 编码。如果你需要播放 mp3,那么你应该看看JavaZoom's JLayer API 如果您尝试播放的文件在项目的 src(或扩展名为 Jar 文件)中,则需要改用 Class#getResourceClass#getResourceAsStream Clipauto 本身支持循环,所以你不需要使用自己的循环,这可能会阻塞事件调度线程。 Thread 似乎有点过头了,恕我直言,虽然您仍然可以使用它来添加人为延迟,但我在示例中使用了 Swing Timer,因为它更简单:P

例如

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
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.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.filechooser.FileFilter;

public class JavaApplication5 

    public static void main(String[] args) 
        new JavaApplication5();
    

    public JavaApplication5() 
        EventQueue.invokeLater(new Runnable() 
            @Override
            public void run() 
                try 
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                 catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) 
                    ex.printStackTrace();
                

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            
        );
    

    public class TestPane extends JPanel 

        private Clip clip = null;

        private JTextField audioFile;
        private JButton browse;
        private JSpinner loops;
        private JSpinner delay;
        private JFileChooser chooser;

        public TestPane() 
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            add(new JLabel("Audio File:"), gbc);

            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weightx = 1;
            gbc.gridx++;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.anchor = GridBagConstraints.WEST;
            audioFile = new JTextField(20);
            add(audioFile);

            gbc.gridwidth = 1;
            gbc.weightx = 0;
            gbc.gridx++;
            browse = new JButton("...");
            add(browse, gbc);

            gbc.gridx = 0;
            gbc.gridy++;
            add(new JLabel("Loops: "), gbc);

            loops = new JSpinner(new SpinnerNumberModel(1, 1, 100, 1));
            gbc.gridx++;
            gbc.fill = GridBagConstraints.NONE;
            add(loops, gbc);

            gbc.gridx = 0;
            gbc.gridy++;
            add(new JLabel("Delay (seconds): "), gbc);

            delay = new JSpinner(new SpinnerNumberModel(0, 0, 10, 1));
            gbc.gridx++;
            gbc.fill = GridBagConstraints.NONE;
            add(delay, gbc);

            gbc.anchor = GridBagConstraints.CENTER;
            gbc.gridx = 0;
            gbc.gridy++;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            JButton play = new JButton("Play");
            add(play, gbc);

            play.addActionListener(new ActionListener() 
                @Override
                public void actionPerformed(ActionEvent e) 
                    try 
                        play(
                                        audioFile.getText(),
                                        (int) delay.getValue(),
                                        (int) loops.getValue());
                     catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) 
                        ex.printStackTrace();;
                        JOptionPane.showMessageDialog(TestPane.this, "<html>Failed to play audio file:</br>" + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                    
                
            );

            browse.addActionListener(new ActionListener() 
                @Override
                public void actionPerformed(ActionEvent e) 
                    if (chooser == null) 
                        chooser = new JFileChooser();
                        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
                        chooser.setMultiSelectionEnabled(false);
                        chooser.addChoosableFileFilter(new FileFilter() 
                            @Override
                            public boolean accept(File f) 
                                System.out.println(f);
                                return f.getName().toLowerCase().endsWith(".wav");
                            

                            @Override
                            public String getDescription() 
                                return "Wave Files (.wav)";
                            
                        );
                    

                    if (chooser.showOpenDialog(TestPane.this) == JFileChooser.APPROVE_OPTION) 
                        File selected = chooser.getSelectedFile();
                        audioFile.setText(selected.getPath());
                    
                
            );

        

        public void play(String path, int delay, int numberOfLoops) throws LineUnavailableException, IOException, UnsupportedAudioFileException 
            if (clip != null) 
                clip.stop();
                clip = null;
            

            if (delay > 0) 
                System.out.println("Start with delay");
                Timer timer = new Timer(delay * 1000, new ActionListener() 
                    @Override
                    public void actionPerformed(ActionEvent e) 
                        try 
                            play(path, numberOfLoops);
                         catch (UnsupportedAudioFileException | LineUnavailableException | IOException ex) 
                            ex.printStackTrace();;
                            JOptionPane.showMessageDialog(TestPane.this, "<html>Failed to play audio file:</br>" + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                        
                    
                );
                timer.setRepeats(false);
                timer.start();
             else 
                play(path, numberOfLoops);
            
        

        private void play(String path, int numberOfLoops) throws UnsupportedAudioFileException, LineUnavailableException, IOException 
            File file = new File(path);
            if (file.exists()) 
                clip = AudioSystem.getClip();
                clip.open(AudioSystem.getAudioInputStream(file));
                clip.start();
            
        
    


【讨论】:

感谢 Mad,这对于我正在创建的这个愚蠢的程序来说有点矫枉过正哈哈。但是,这是一个很好的例子,可以帮助我学习如何播放音频,感谢您抽出时间来回答!

以上是关于如何在win32编程中,在同一个窗口下播放多个音乐的主要内容,如果未能解决你的问题,请参考以下文章

在网页中播放音乐时打开同步显示歌词窗口如何实现?

VC++ win32 API 编程:如何将图像从剪贴板中取出并显示在窗口中?

在 JFrame 窗口的背景中播放音乐

win32编辑框设置提示文字

是否可以在没有帮助应用程序的情况下远程控制 iOS 相机和音乐?

带有多个菜单栏的 Win32 中的 Windows 应用程序?