1. 程式人生 > >使用百度音樂盒API介面實現音樂播放器

使用百度音樂盒API介面實現音樂播放器

百度音樂盒提供了一個便捷的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;
    }
}