Android 音乐播放器实现歌词显示


Android 音乐播放器实现歌词显示

LrcHandle.java:

package com.example.welcome;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/***
 * 获取时间以及对应的歌词
 *
 * @author chao
 *
 */
public class LrcHandle {
 private List<String> mWords = new ArrayList<String>();
 private List<Integer> mTimeList = new ArrayList<Integer>();

 // 处理歌词文件
 public void readLRC(String path) {
  File file = new File(path);

  try {
   FileInputStream fileInputStream = new FileInputStream(file);
   InputStreamReader inputStreamReader = new InputStreamReader(
     fileInputStream, "GBK");
   BufferedReader bufferedReader = new BufferedReader(
     inputStreamReader);
   String s = "";
   while ((s = bufferedReader.readLine()) != null) {
    addTimeToList(s);
    if ((s.indexOf("[ar:") != -1) || (s.indexOf("[ti:") != -1)
      || (s.indexOf("[by:") != -1)) {
     s = s.substring(s.indexOf(":") + 1, s.indexOf("]"));
    } else {
     // ss为时间 [02:12.22]
     String ss = s.substring(s.indexOf("["), s.indexOf("]") + 1);
     // s为ss时间后的歌词
     s = s.replace(ss, "");
    }
    mWords.add(s);
   }

   bufferedReader.close();
   inputStreamReader.close();
   fileInputStream.close();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
   mWords.add("没有歌词文件,赶紧去下载");
  } catch (IOException e) {
   e.printStackTrace();
   mWords.add("没有读取到歌词");
  }
 }

 public List<String> getWords() {
  return mWords;
 }

 public List<Integer> getTime() {
  return mTimeList;
 }

 // 分离出时间
 private int timeHandler(String string) {
  string = string.replace(".", ":");
  String timeData[] = string.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;
 }

 private void addTimeToList(String string) {
  Matcher matcher = Pattern.compile(
    "\\[\\d{1,2}:\\d{1,2}([\\.:]\\d{1,2})?\\]").matcher(string);
  if (matcher.find()) {
   String str = matcher.group();
   mTimeList.add(new LrcHandle().timeHandler(str.substring(1,
     str.length() - 1)));
  }
 }
}

WordView.java:

package com.example.welcome;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
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;

public class WordView extends TextView {
 private List mWordsList = new ArrayList();
 private Paint mLoseFocusPaint;
 private Paint mOnFocusePaint;
 private float mX = 0;
 private float mMiddleY = 0;
 private float mY = 0;
 private static final int DY = 50;
 private int mIndex = 0;

 public WordView(Context context) throws IOException {
  super(context);
  init();
 }

 public WordView(Context context, AttributeSet attrs) throws IOException {
  super(context, attrs);
  init();
 }

 public WordView(Context context, AttributeSet attrs, int defStyle)
   throws IOException {
  super(context, attrs, defStyle);
  init();
 }

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);

  canvas.drawColor(Color.BLACK);
  Paint p = mLoseFocusPaint;
  p.setTextAlign(Paint.Align.CENTER);
  Paint p2 = mOnFocusePaint;
  p2.setTextAlign(Paint.Align.CENTER);

  canvas.drawText((String) mWordsList.get(mIndex), mX, mMiddleY, p2);

  int alphaValue = 25;
  float tempY = mMiddleY;
  for (int i = mIndex - 1; i >= 0; i--) {
   tempY -= DY;
   if (tempY < 0) {
    break;
   }
   p.setColor(Color.argb(255 - alphaValue, 245, 245, 245));
   canvas.drawText((String) mWordsList.get(i), mX, tempY, p);
   alphaValue += 25;
  }
  alphaValue = 25;
  tempY = mMiddleY;
  for (int i = mIndex + 1, len = mWordsList.size(); i < len; i++) {
   tempY += DY;
   if (tempY > mY) {
    break;
   }
   p.setColor(Color.argb(255 - alphaValue, 245, 245, 245));
   canvas.drawText((String) mWordsList.get(i), mX, tempY, p);
   alphaValue += 25;
  }
  mIndex++;
 }

 @Override
 protected void onSizeChanged(int w, int h, int ow, int oh) {
  super.onSizeChanged(w, h, ow, oh);

  mX = w * 0.5f;
  mY = h;
  mMiddleY = h * 0.3f;
 }

 @SuppressLint("SdCardPath")
 private void init() throws IOException {
  setFocusable(true);

  LrcHandle lrcHandler = new LrcHandle();
  lrcHandler.readLRC("/sdcard/aa.lrc");
  mWordsList = lrcHandler.getWords();

  mLoseFocusPaint = new Paint();
  mLoseFocusPaint.setAntiAlias(true);
  mLoseFocusPaint.setTextSize(22);
  mLoseFocusPaint.setColor(Color.WHITE);
  mLoseFocusPaint.setTypeface(Typeface.MONOSPACE);

  mOnFocusePaint = new Paint();
  mOnFocusePaint.setAntiAlias(true);
  mOnFocusePaint.setColor(Color.YELLOW);
  mOnFocusePaint.setTextSize(40);
  mOnFocusePaint.setTypeface(Typeface.SANS_SERIF);
 }
}

MainActivity.java:

package com.example.welcome;

import java.io.IOException;
import java.util.List;

import android.R.integer;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {
 private WordView mWordView;
 private List mTimeList;
 private MediaPlayer mPlayer;

 @SuppressLint("SdCardPath")
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  Button button = (Button) findViewById(R.id.button);
  button.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    mPlayer.stop();
    finish();
   }
  });

  mWordView = (WordView) findViewById(R.id.text);
  mPlayer = new MediaPlayer();
  mPlayer.reset();
  LrcHandle lrcHandler = new LrcHandle();
  try {
   lrcHandler.readLRC("/sdcard/aa.lrc");
   mTimeList = lrcHandler.getTime();
   mPlayer.setDataSource("/sdcard/e.mp3");
   mPlayer.prepare();
  } catch (IOException e) {
   e.printStackTrace();
  } catch (IllegalArgumentException e) {
   e.printStackTrace();
  } catch (SecurityException e) {
   e.printStackTrace();
  } catch (IllegalStateException e) {
   e.printStackTrace();
  }
  final Handler handler = new Handler();
  mPlayer.start();
  new Thread(new Runnable() {
   int i = 0;

   @Override
   public void run() {
    while (mPlayer.isPlaying()) {
     handler.post(new Runnable() {
      @Override
      public void run() {
       mWordView.invalidate();
      }
     });
     try {
      Thread.sleep(Integer.parseInt(mTimeList.get(i + 1)
        .toString())
        - Integer.parseInt(mTimeList.get(i).toString()));
     } catch (InterruptedException e) {
     }
     i++;
     if (i == mTimeList.size() - 1) {
      mPlayer.stop();
      break;
     }
    }
   }
  }).start();
 }
}

main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/button"
        android:layout_width="60dip"
        android:layout_height="60dip"
        android:text="stop" />

    <com.example.welcome.WordView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/button"
        android:text="song" />

</RelativeLayout>

相关内容

    暂无相关文章