运用Java制作一个属于自己的音乐播放软件

运用Java制作一个属于自己的音乐播放软件

前言

上个寒假小编用python做了一个音乐播放软件(博客链接为:)运用tkinter、爬虫做了一个播放音乐的小程序(动态显示歌词【歌词向上翻滚】),觉得效果不怎么的,于是今天小编用Java做了一个播放软件,个人觉得这个有了一点质的飞跃,毕竟python图形界面从某些方面讲不如Java。在这里声明一下:本编文章仅供学习,切莫用于商业活动,一经被相关人员发现,本小编概不负责!希望读者切记!!

在这里插入图片描述

运用Java实现音乐播放器

在这里插入图片描述

1.需要的python模块

虽然我题目讲的是运用Java做的,但是还是用到了python,而且python的部分很重要,所以小编首先讲的是需要的python模块。
需要的模块有requests、sys、urllib.parse、json
其中requests和urllib.parse主要用于爬取歌曲信息用的,json数据用于解析得到的json数据,sys主要用于传递参数用的。
还记得如下这个吗?

from sys import argv

sum=int(argv[1])+int(argv[2])
print(sum)

运行结果:
在这里插入图片描述

2.实现的两个python代码

首先,在给出代码之前,我想讲一下具体是怎样实现这个播放软件的,小编是写了两个python代码程序,分别为music2.py和music.py,music2.py通过传入的歌曲名称,会产生两个.txt文件,分别存储搜索得到的歌曲信息和与之对应的歌曲id和hash值,music.py通过传入的歌曲id和hash值下载歌曲和歌词.
然后写了两个Java线程让播放歌曲和歌词流动同步(不设置线程只能等其中的任何一个结束之后才能执行另外一个)。
当然,读者在看小编下面的两个代码的时候,或许会存在一些疑问,小编在这里先给出另外一边博客的地址,看了这篇博客,读者应该会理解两个python代码程序的作用了。博客链接为:酷狗音乐

参考代码如下:

music2.py

from sys import argv
from urllib.parse import quote
import requests
import json


keyword=argv[1]
encodeName=quote(keyword)
url='https://songsearch.kugou.com/song_search_v2?callback=jQuery1124042761514747027074_1580194546707&keyword=%s&page=1&pagesize=30&userid=-1&clientver=&platform=WebFilter&tag=em&filter=2&iscorrection=1&privilege_filter=0&_=1580194546709'%(encodeName)
headers={
    
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3756.400 QQBrowser/10.5.4039.400'}
response=requests.get(url=url,headers=headers)
str2=response.text
str2 = str2[str2.find('(') + 1:str2.rfind(')')]
dict2 = json.loads(str2)
music_list = dict2['data']['lists']
hash_list = list()
musicNames=list()

for id in range(len(music_list)):
    music_name=music_list[id]['FileName'].replace('<em>', '').replace('</em>', '')
    musicNames.append(music_name)
    hash_list.append([music_list[id]['FileHash'],music_list[id]['AlbumID']])


with open(file='D:/intell/Clock/src/file/{}Names.txt'.format(keyword),mode='a',encoding='utf-8') as f:
    for i in range(len(musicNames)):
        f.writelines(musicNames[i]+"\n")

with open(file='D:/intell/Clock/src/file/{}hash.txt'.format(keyword),mode='a',encoding='utf-8') as f:
    for i in range(len(hash_list)):
        f.writelines(hash_list[i][0]+'\t'+hash_list[i][1]+"\n")

music.py

from sys import argv
import requests
import json

hash=argv[1]
id=argv[2]
keyword=argv[3]
if(id=="0"):
    id=""

url='https://wwwapi.kugou.com/yy/index.php?r=play/getdata&hash=%s&album_id=%s&dfid=2SSV0x4LWcsx0iylej1F6w7P&mid=44328d3dc4bfce21cf2b95cf9e76b968&platid=4'
headers={
    
    'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3756.400 QQBrowser/10.5.4039.400'}
url=url%(hash,id)
response=requests.get(url=url,headers=headers)
dict2=json.loads(response.text)
music_info=dict2['data']['lyrics']   # 歌曲信息
url2=dict2['data']['play_url']

with open(file="D:/intell/Clock/src/file2/{}.txt".format(keyword),mode="w",encoding="utf-8") as f:
    f.write(music_info)

response2=requests.get(url=url2,headers=headers)
with open(file="D:/intell/Clock/src/file2/{}.mp3".format(keyword),mode="wb") as f:
    f.write(response2.content)

print("1")

3.Java程序部分

在2的时候讲了Java调用python,那么具体怎样调用呢?
在这里插入图片描述
看了这张图片,读者是不是发现这个和第1点的运行结果是不是很相似,当然这个的完成小编觉得应该要配置python环境变量的(不过,小编想读者都应该配置好了吧!)
当然了,读者还需要再src文件夹下面新建两个如下的文件夹,另外,读者运行一次这个程序之后,最好把文件夹file里面的文件全部删除,否则下次运行的时候会出一定错误,file2不需要任何操作。
在这里插入图片描述

4.全部Java代码

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.URL;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import javax.sound.sampled.*;

public class music extends JFrame {
    
    
    private JPanel topPanel;
    private JPanel CenterPanel2;
    private JPanel centerPanel;
    private JPanel bottomPanel;

    private JLabel label;
    private JTextField textField;
    private JButton button;
    private DefaultListModel<String> listModel; // 列表框
    private JList<String> jList;
    private List<String> list;
    private List<String> list2;

    private Integer index=0;
    private String hash;     //歌曲的hash码
    private String id;  // 歌曲的id码
    private String musicName; // 歌曲名

    private Font font;
    private JToolBar toolBar; //工具栏
    private JButton ssButton;
    private JButton bfButton;
    private JButton zbButton;
    private JPanel textPanel2;
    private Integer num=0;
    private List<String> music_words2;
    private Timer timer;
    private int num2=0;
    private int num3=1;
    private Integer time;

    private JTextArea textArea;
    private JLabel label2;

    public music(){
    
    
        super("某某音乐");
        topPanel=new JPanel();
        topPanel.setSize(1000,60);

        label=new JLabel("歌曲名:");
        topPanel.add(label,FlowLayout.LEFT);

        font=new Font("华文宋体",Font.BOLD,20);
        textField=new JTextField();
        textField.setColumns(22);
        textField.setFont(font);

        topPanel.add(textField,FlowLayout.CENTER);

        button=new JButton("搜索");
        button.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                try {
    
    
                    String keyword=textField.getText();
                    write_file(keyword);
                    setList(list,keyword+"Names");
                    listModel.clear();
                    jList.repaint();
                    for(int i=0;i<list.size();i++)
                        listModel.insertElementAt(list.get(i),i);
                    jList.repaint();
                    centerPanel.repaint();
                } catch (Exception ex) {
    
    
                    ex.printStackTrace();
                }
            }
        });

        topPanel.add(button,FlowLayout.RIGHT);

        CenterPanel2=new JPanel();
        CenterPanel2.setSize(1000,700);
        CardLayout cardLayout=new CardLayout();
        CenterPanel2.setLayout(cardLayout);

        centerPanel=new JPanel();
        centerPanel.setSize(1000,700);
        list=new LinkedList<>();
        list2=new LinkedList<>();

        listModel=new DefaultListModel<String>();
        jList = new JList<String>(listModel);
        jList.setFont(font);
        jList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        jList.addListSelectionListener(new ListSelectionListener() {
    
    
            @Override
            public void valueChanged(ListSelectionEvent e) {
    
    
                setIndex(jList.getSelectedIndex());
                setMusicName(jList.getSelectedValue());
            }
        });

        JScrollPane scrollPane1 = new JScrollPane(jList);
        scrollPane1.setPreferredSize(new Dimension(900, 700));
        centerPanel.add(scrollPane1);

        CenterPanel2.add(centerPanel,"0");

        textArea=new JTextArea();
        textArea.setSize(900,700);
        textArea.setFont(font);
        textArea.setEditable(false);
        textPanel2=new JPanel();
        textPanel2.add(textArea);

        CenterPanel2.add(textPanel2,"1");

        bottomPanel=new JPanel();

        toolBar=new JToolBar(JToolBar.HORIZONTAL);
        zbButton=new JButton(getImage("sx"));
        zbButton.setToolTipText("转变");
        zbButton.setFont(font);
        zbButton.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                if(num==0){
    
    
                    cardLayout.show(CenterPanel2,"1");
                    num+=1;
                }else{
    
    
                    cardLayout.show(CenterPanel2,"0");
                    num=0;
                }
            }
        });

        toolBar.add(zbButton);


        ssButton=new JButton("缓冲");
        ssButton.setFont(font);

        music_words2=new LinkedList<String>();
        ssButton.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                try {
    
    
                    String keyword=textField.getText();
                    System.out.println(keyword);
                    setList(list2,keyword+"hash");
                    List<String> list3= Arrays.asList(list2.get(index).split("\t"));
                    try{
    
    
                        setHash(list3.get(0));
                        setId(list3.get(1));
                    }catch (Exception ex2){
    
    
                        setHash(list3.get(0));
                        setId("0");
                    }
                    download_file(hash,id,musicName);
                } catch (Exception ex) {
    
    
                    ex.printStackTrace();
                }
            }
        });

        toolBar.add(ssButton);

        bfButton=new JButton(getImage("ss"));
        bfButton.setToolTipText("播放");
        bfButton.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    

                List<String> music_words=null;
                try {
    
    
                    music_words = getMusicWord(musicName);
                    System.out.println(musicName);
                } catch (Exception ex) {
    
    
                    ex.printStackTrace();
                }
                for(int i=0;i<music_words.size();i++){
    
    
                    if(!("".equals(music_words.get(i))))
                        music_words2.add(music_words.get(i));
                }
                List<List<String>> music_words3=new LinkedList<>();
                for(int i=0;i<music_words2.size();i++){
    
    
                    String string=music_words2.get(i);
                    int index=string.indexOf("]")+1;
                    if(string.substring(index).length()!=0){
    
    
                        List<String> list4=new LinkedList<String>();
                        list4.add(string.substring(0,index));
                        list4.add(string.substring(index));
                        music_words3.add(list4);
                    }
                }
                int len=music_words3.size();
                System.out.println(len);
                label2.setText("音乐开始播放!");
                textArea.setText("");
                time=get_time("0",music_words3.get(0).get(0));
                timer=new Timer(time, new ActionListener() {
    
    
                    @Override
                    public void actionPerformed(ActionEvent e) {
    
    
                        if(num2<28){
    
    
                            textArea.append(music_words3.get(num2++).get(1)+"\n");
                            textArea.repaint();
                        }else{
    
    
                            textArea.setText("");
                            for(int i=num3;i<num2;i++){
    
    
                                textArea.append(music_words3.get(i).get(1)+"\n");
                            }
                            textArea.append(music_words3.get(num2++).get(1)+"\n");
                            textArea.repaint();
                            num3++;
                        }
                        if(num2>0 &&num2!=len){
    
    
                            time=get_time(music_words3.get(num2-1).get(0),music_words3.get(num2).get(0));
                            System.out.println(time);
                        }
                        timer.setDelay(time);   // 重新设置时间间隔
                        String string2=label2.getText();
                        if(num2%2==0)
                            label2.setText(string2+".");
                        if(num2==len){
    
    
                            label2.setText("音乐播放完毕!");
                            label2.repaint();
                            num2=0;
                            num3=1;
                            music_words2.clear();
                            timer.stop();
                        }
                        System.out.println("num2:"+num2);
                    }
                });
                Thread thread1=new Thread(new Runnable() {
    
    
                    @Override
                    public void run() {
    
    
                        timer.start();
                    }
                });
                Thread thread2=new Thread(new Runnable() {
    
    
                    @Override
                    public void run() {
    
    
                        play(musicName);
                    }
                });
                thread1.start();
                thread2.start(); // 定义两个线程,让播放音乐和歌词同时执行
            }
        });

        toolBar.add(bfButton);
        label2=new JLabel("音乐");
        Font font2=new Font("方正楷体",Font.BOLD,20);
        label2.setFont(font2);

        toolBar.add(label2);

        bottomPanel.add(toolBar);

        add(topPanel,BorderLayout.NORTH);
        add(CenterPanel2,BorderLayout.CENTER);
        add(bottomPanel,BorderLayout.SOUTH);
        setBounds(200,200,1000,900);
        setResizable(false);   // 设置窗体大小为固定,不可放大
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void setIndex(Integer index) {
    
    
        this.index = index;
    }

    public void setMusicName(String musicName) {
    
    
        this.musicName = musicName;
    }

    public void setHash(String hash) {
    
    
        this.hash = hash;
    }

    public void setId(String id) {
    
    
        this.id = id;
    }

    public void setList(List<String> list, String keyword) throws Exception{
    
    
        String filename=String.format("src/file/%s.txt",keyword);
        File file=new File(filename);
        if(list.size()>0){
    
    
            list.clear();
        }
        if(file.exists()){
    
    
            FileReader fr=new FileReader(filename);
            BufferedReader bf=new BufferedReader(fr);
            while(bf.ready()){
    
    
                list.add(bf.readLine());
            }
            bf.close();
            fr.close();
        }
    }// 得到歌曲列表

    public List<String> getMusicWord(String keyword) throws Exception {
    
    
        List<String> list1 = new LinkedList<String>();
        String filename = String.format("src/file2/%s.txt", keyword);
        File file = new File(filename);

        if (file.exists()) {
    
    
            FileReader fr = new FileReader(filename);
            BufferedReader bf = new BufferedReader(fr);
            while (bf.ready()) {
    
    
                list1.add(bf.readLine());
            }
            bf.close();
            fr.close();
        }
        return list1;
    }

    public ImageIcon getImage(String name){
    
    
        URL url=getClass().getResource("/images/"+name+".jpg");
        ImageIcon imageIcon=new ImageIcon(url);
        return imageIcon;
    }

    public void write_file(String keyword) throws Exception {
    
    
        if("".equals(keyword)){
    
    
            keyword="夜航星";
        }
        String exe = "python";
        String command = "D:\\Sublime\\PyCharm\\music\\music2.py";
        String[] cmdArr = new String[] {
    
    exe,command,keyword};
        Process process = Runtime.getRuntime().exec(cmdArr);
        process.waitFor();
    }

    public static Integer get_time(String time1,String time2){
    
    
        int index1=time2.indexOf(":")+1;
        int index2=time2.indexOf("]");
        int index3=time2.indexOf("[")+1;
        int time3;
        if("0".equals(time1)){
    
    
            time3=0;
        }else{
    
    
            time3=Integer.parseInt(time1.substring(index3,index1-1))*1000*60+(int) (Double.parseDouble(time1.substring(index1,index2))*1000);
        }
        int time4=Integer.parseInt(time2.substring(index3,index1-1))*1000*60+(int) (Double.parseDouble(time2.substring(index1,index2))*1000);
        return time4-time3;
    }


    public static void play(String musicName){
    
    
        String filePath=String.format("src/file2/%s.mp3",musicName);
        try {
    
    
            // 文件流
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File(filePath));
            // 文件编码
            AudioFormat audioFormat = audioInputStream.getFormat();
            // 转换文件编码
            if (audioFormat.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
    
    
                System.out.println(audioFormat.getEncoding());
                audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, audioFormat.getSampleRate(), 16, audioFormat.getChannels(), audioFormat.getChannels() * 2, audioFormat.getSampleRate(), false);
                // 将数据流也转换成指定编码
                audioInputStream = AudioSystem.getAudioInputStream(audioFormat, audioInputStream);
            }

            // 打开输出设备
            DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, audioFormat, AudioSystem.NOT_SPECIFIED);
            // 使数据行得到一个播放设备
            SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
            // 将数据行用指定的编码打开
            sourceDataLine.open(audioFormat);
            // 使数据行得到数据时就开始播放
            sourceDataLine.start();

            int bytesPerFrame = audioInputStream.getFormat().getFrameSize();
            // 将流数据逐渐写入数据行,边写边播
            int numBytes = 1024 * bytesPerFrame;
            byte[] audioBytes = new byte[numBytes];
            while (audioInputStream.read(audioBytes) != -1) {
    
    
                sourceDataLine.write(audioBytes, 0, audioBytes.length);
            }
            sourceDataLine.drain();
            sourceDataLine.stop();
            sourceDataLine.close();

        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }// 播放音乐代码

    public void download_file(String hash,String id,String keyword) throws Exception{
    
    
        String exe = "python";
        String command = "D:\\Sublime\\PyCharm\\music\\music.py";
        String[] comArr = new String[]{
    
    exe, command, hash, id, keyword};
        System.out.println(exe+" "+command+" "+hash+" "+id+" "+keyword);
        Process process = Runtime.getRuntime().exec(comArr);
        process.waitFor();
    }

    public static void main(String[] args) throws Exception {
    
    
        new music().setVisible(true);
    }
}

在这里小编讲明一点,代码中需要用到图片,所以读者最好在src文件夹下面新建一个images文件夹,然后在下面添加两张40*40像素的图片,图片命名分别为ss.jpg(播放图标)和sx.jpg(转变图标).如下:
在这里插入图片描述

另外,由于Java无法播放.mp3文件,所以小编在网上找了一些资料,终于有了一篇博客讲到了,博客链接为:利用JAVA SOUND播放mp3,flac,ape格式音乐,这篇博客讲到需要将几个.jar文件导入,小编用的IntelliJ IDEA,怎样导入呢?小编到网上找了一下,觉得这一篇博客不错,博客链接为:IntelliJ IDEA java项目导入jar包,打jar包
也许读者用的编辑器不同,希望到时候如果读者真的想实践一下,到网上找一下资料吧!

5. 总结

这个音乐播放软件比起用python实现效果好多了,真的,希望到时候读者觉得这个还不错的话!点赞一下呗!小编在此谢了!

猜你喜欢

转载自blog.csdn.net/qq_45404396/article/details/113047121