使用百度音乐盒API接口实现音乐播放器

来源:互联网 发布:写入关键词 大数据 编辑:程序博客网 时间:2024/05/09 09:17

百度音乐盒提供了一个便捷的API可以拿来访问一些音乐资源,开发者通过访问指定格式的url可以拿到返回的数据,这个数据可以是json或者xml,这里面包含了歌曲的信息。完整的API各种访问格式是非常丰富的,参见http://www.cnblogs.com/liuying1995/p/5704176.html。这里我们只实现查询关键字,得到返回的歌曲列表和百度定义的歌曲的id,然后再使用这个id访问,再从返回的数据中得到歌曲和歌词的地址,接下来就可以顺利完成歌曲的播放和下载了。-------另外,本文中还提供了一个动态显示歌词的自定义view和读取歌词文件的工具类。

我直接展示我的实现思路:

1.接收输入框的输入文字并传到查询方法里。

String name = etSearch.getText().toString();                if (name.length() == 0) {                    Toast.makeText(this, "请输入歌曲名称", Toast.LENGTH_SHORT).show();                } else {                    Toast.makeText(MainActivity.this,"已开始查询,请耐心等待",Toast.LENGTH_SHORT).show();                    query2(name);                }

2.在查询方法中访问URL并得到返回的json,传入解析json的方法。这里面的url字符串格式参见开头提到的网站,可以看到字符串最后的参数query=我们传入的查询数据。

private void query2(final String title){        new Thread(new Runnable() {            @Override            public void run() {                try {                    HttpURLConnection connection;                    String finalTitle = URLEncoder.encode(title,"utf-8");                    URL url = new URL("http://tingapi.ting.baidu.com/v1/restserver/ting?from=webapp_music&method=baidu.ting.search.catalogSug&format=json&callback=&query="+finalTitle);                    connection = (HttpURLConnection) url.openConnection();                    connection.setConnectTimeout(60*1000);                    connection.setReadTimeout(60*1000);                    connection.connect();                    BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));                    String s;                    if ((s=reader.readLine())!=null)                        doJson(s);                } catch (IOException e) {                    e.printStackTrace();                }            }        }).start();    }
3.在解析方法中最终取得歌曲的名称,艺术家,地址,歌词地址信息,json解析就不具体展开了,然后我把这些数据封装在自定义的Song对象里。(方法中调用了两个方法,分别是获取歌曲地址和歌词地址,在下面会展示,这是因为获取这两个数据需要用得到的歌曲的id再一次访问)。

//解析返回的json    public Song doJson(String json){        Song song = null;        JSONObject jsonObject = null;        list.clear();//清空原有的歌曲数组        try {            //去掉括号            json = json.replace("(","");            json = json.replace(")","");            jsonObject = new JSONObject(json);            JSONArray array = new JSONArray(jsonObject.getString("song"));            for (int i=0;i<array.length();i++){                JSONObject object = array.getJSONObject(i);                String songname = object.getString("songname");                String artistname = object.getString("artistname");                String songid = object.getString("songid");                String adress = getAdress(songid);                Song song1 = new Song(songname,artistname,adress,0);                song1.setLrcPath(getLrcAdress(songid));                list.add(i,song1);                Log.v("tag",songname+"  "+artistname+"  "+songid);                //列表更新                Message msg = new Message();                msg.what = 1;                handler.sendMessage(msg);            }        } catch (JSONException e) {            e.printStackTrace();        }        return song;    }    public String getAdress(final String songid){        new Thread(new Runnable() {            @Override            public void run() {                try {                    HttpURLConnection connection;                    //URL url = new URL("http://api.5288z.com/weixin/musicapi.php?q="+finalTitle);                    URL url = new URL("http://ting.baidu.com/data/music/links?songIds="+songid);                    connection = (HttpURLConnection) url.openConnection();                    connection.setConnectTimeout(60*1000);                    connection.setReadTimeout(60*1000);                    connection.connect();                    BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));                    String s;                    if ((s=reader.readLine())!=null){                        s = s.replace("\\","");//去掉\\                        try {                            JSONObject object = new JSONObject(s);                            JSONObject object1 = object.getJSONObject("data");                            JSONArray array = object1.getJSONArray("songList");                            JSONObject object2 = array.getJSONObject(0);                            adress = object2.getString("songLink");                            Log.v("tagadress",adress);                        } catch (JSONException e) {                            e.printStackTrace();                        }                    }                } catch (IOException e) {                    e.printStackTrace();                }            }        }).start();        try {            Thread.sleep(500);        } catch (InterruptedException e) {            e.printStackTrace();        }        return adress;    }    //获取歌词地址    public String getLrcAdress(final String songid){        new Thread(new Runnable() {            @Override            public void run() {                try {                    HttpURLConnection connection;                    //URL url = new URL("http://api.5288z.com/weixin/musicapi.php?q="+finalTitle);                    URL url = new URL("http://ting.baidu.com/data/music/links?songIds="+songid);                    connection = (HttpURLConnection) url.openConnection();                    connection.setConnectTimeout(60*1000);                    connection.setReadTimeout(60*1000);                    connection.connect();                    BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));                    String s;                    if ((s=reader.readLine())!=null){                        s = s.replace("\\","");//去掉\\                        Log.v("tag","------"+s);                        try {                            JSONObject object = new JSONObject(s);                            JSONObject object1 = object.getJSONObject("data");                            JSONArray array = object1.getJSONArray("songList");                            JSONObject object2 = array.getJSONObject(0);                            LrcAdress = object2.getString("lrcLink");                            Log.v("tag","888888lrc"+ LrcAdress);                        } catch (JSONException e) {                            e.printStackTrace();                        }                    }                } catch (IOException e) {                    e.printStackTrace();                }            }        }).start();        try {            Thread.sleep(500);        } catch (InterruptedException e) {            e.printStackTrace();        }        return LrcAdress;    }

4.展示歌词的自定义view(转):这里传入了一个自定义的歌词类,是把每一行歌词作为一个对象,其中有歌词内容和歌词开始时间这两个值。

package com.example.one.newmusicplayer.ui;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Typeface;import android.util.AttributeSet;import android.widget.TextView;import com.example.one.newmusicplayer.item.LrcOne;import java.util.ArrayList;import java.util.List;/** * Created by lenovo on 2016/10/27. * 显示歌词的自定义view */public class LrcView extends TextView {    private float width;        //歌词视图宽度    private float height;       //歌词视图高度    private Paint currentPaint; //当前歌词画笔    private Paint notCurrentPaint;  //非当前歌词画笔    private float textHeight = 45;  //每一行高度    private float textSize = 35;        //每一行非当前文字的大小    private int index = 0;      //list集合下标    private List<LrcOne> list = new ArrayList<>();    public LrcView(Context context) {        super(context);        init();    }    public LrcView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    private void init() {        setFocusable(true);     //设置可对焦        //高亮部分        currentPaint = new Paint();        currentPaint.setAntiAlias(true);    //设置抗锯齿,让文字美观饱满        currentPaint.setTextAlign(Paint.Align.CENTER);//设置文本对齐方式        //非高亮部分        notCurrentPaint = new Paint();        notCurrentPaint.setAntiAlias(true);        notCurrentPaint.setTextAlign(Paint.Align.CENTER);    }    /**     * 绘画歌词     */    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if(canvas == null) {            return;        }        //设置字体的大小颜色样式以及绘制出来的画笔        currentPaint.setColor(Color.argb(210, 251, 0, 0));        notCurrentPaint.setColor(Color.argb(140, 0, 0, 0));        currentPaint.setTextSize(40);        currentPaint.setTypeface(Typeface.SERIF);        notCurrentPaint.setTextSize(textSize);        notCurrentPaint.setTypeface(Typeface.DEFAULT);        try {            setText("");            canvas.drawText(list.get(index).getLrcStr(), width / 2, height / 2, currentPaint);            float tempY = height / 2;            //画出本句之前的句子            for(int i = index - 1; i >= 0; i--) {                //向上推移                tempY = tempY - textHeight;                canvas.drawText(list.get(i).getLrcStr(), width / 2, tempY, notCurrentPaint);            }            tempY = height / 2;            //画出本句之后的句子            for(int i = index + 1; i < list.size(); i++) {                //往下推移                tempY = tempY + textHeight;                canvas.drawText(list.get(i).getLrcStr(), width / 2, tempY, notCurrentPaint);            }        } catch (Exception e) {            setText("");        }    }    /**     * 当view大小改变的时候调用的方法     */    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        this.width = w;        this.height = h;    }    public void setIndex(int index) {        this.index = index;    }    public void setmLrcList(List<LrcOne> mLrcList) {        this.list = mLrcList;    }}
5.读取歌词文件的工具类,读取后封装在一个歌词类的数组里。
package com.example.one.newmusicplayer.tools;import android.util.Log;import android.widget.Toast;import com.example.one.newmusicplayer.item.LrcOne;import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.nio.charset.Charset;import java.util.ArrayList;import java.util.List;/** * Created by lenovo on 2016/10/27. * 读取歌词并将其拆成一个个歌词类的工具类 */public class LrcDeal {    public List<LrcOne> getList() {        return list;    }    private List<LrcOne> list = new ArrayList<>();    //读取歌词并返回一个装满歌词对象的list    //读取网络歌词文件的方法    public List<LrcOne> readIntnetLrc(String path){        InputStream inputStream = null;        try {            URL url = new URL(path);            HttpURLConnection connection = (HttpURLConnection) url.openConnection();            connection.setConnectTimeout(60*1000);            connection.setReadTimeout(60*1000);            inputStream = connection.getInputStream();        } catch (Exception e) {            e.printStackTrace();        }        StringBuilder stringBuilder = new StringBuilder();        //创建一个文件输入流        try {            //创建一个文件输入流对象            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream,"utf-8"));            String s = "";            while((s = br.readLine()) != null) {                s = s.replace("[", "");                s = s.replace("]", "@");                //分离“@”字符                String splitLrcData[] = s.split("@");                LrcOne lrcOne = new LrcOne();                if(splitLrcData.length > 1) {                    lrcOne.setLrcStr(splitLrcData[1]);                    //处理歌词取得歌曲的时间                    int lrcTime = time2Str(splitLrcData[0]);                    lrcOne.setLrcTime(lrcTime);                    //添加进列表数组                    list.add(lrcOne);                }            }        } catch (FileNotFoundException e) {            e.printStackTrace();            stringBuilder.append("木有歌词文件,赶紧去下载!...");        } catch (IOException e) {            e.printStackTrace();            stringBuilder.append("木有读取到歌词哦!");        }        return list;    }    //对时间字符串进行处理    public int time2Str(String timeStr) {        timeStr = timeStr.replace(":", ".");        timeStr = timeStr.replace(".", "@");        String timeData[] = timeStr.split("@"); //将时间分隔成字符串数组        //分离出分、秒并转换为整型        int minute = Integer.parseInt(timeData[0]);        int second = Integer.parseInt(timeData[1]);        int millisecond = Integer.parseInt(timeData[2]);        //计算上一行与下一行的时间转换为毫秒数        int currentTime = (minute * 60 + second) * 1000 + millisecond * 10;        return currentTime;    }}



2 0